View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io;
18  
19  import java.io.Serializable;
20  
21  /**
22   * Enumeration of IO case sensitivity.
23   * <p>
24   * Different filing systems have different rules for case-sensitivity.
25   * Windows is case-insensitive, Unix is case-sensitive.
26   * <p>
27   * This class captures that difference, providing an enumeration to
28   * control how filename comparisons should be performed. It also provides
29   * methods that use the enumeration to perform comparisons.
30   * <p>
31   * Wherever possible, you should use the <code>check</code> methods in this
32   * class to compare filenames.
33   *
34   * @author Stephen Colebourne
35   * @version $Id: IOCase.java 484844 2006-12-08 23:27:18Z ggregory $
36   * @since Commons IO 1.3
37   */
38  public final class IOCase implements Serializable {
39  
40      /**
41       * The constant for case sensitive regardless of operating system.
42       */
43      public static final IOCase SENSITIVE = new IOCase("Sensitive", true);
44      /**
45       * The constant for case insensitive regardless of operating system.
46       */
47      public static final IOCase INSENSITIVE = new IOCase("Insensitive", false);
48      /**
49       * The constant for case sensitivity determined by the current operating system.
50       * Windows is case-insensitive when comparing filenames, Unix is case-sensitive.
51       * <p>
52       * If you derialize this constant of Windows, and deserialize on Unix, or vice
53       * versa, then the value of the case-sensitivity flag will change.
54       */
55      public static final IOCase SYSTEM = new IOCase("System", !FilenameUtils.isSystemWindows());
56  
57      /** Serialization version. */
58      private static final long serialVersionUID = -6343169151696340687L;
59  
60      /** The enumeration name. */
61      private final String name;
62      /** The sensitivity flag. */
63      private final transient boolean sensitive;
64  
65      //-----------------------------------------------------------------------
66      /**
67       * Factory method to create an IOCase from a name.
68       * 
69       * @param name  the name to find
70       * @return the IOCase object
71       * @throws IllegalArgumentException if the name is invalid
72       */
73      public static IOCase forName(String name) {
74          if (IOCase.SENSITIVE.name.equals(name)){
75              return IOCase.SENSITIVE;
76          }
77          if (IOCase.INSENSITIVE.name.equals(name)){
78              return IOCase.INSENSITIVE;
79          }
80          if (IOCase.SYSTEM.name.equals(name)){
81              return IOCase.SYSTEM;
82          }
83          throw new IllegalArgumentException("Invalid IOCase name: " + name);
84      }
85  
86      //-----------------------------------------------------------------------
87      /**
88       * Private constructor.
89       * 
90       * @param name  the name
91       * @param sensitive  the sensitivity
92       */
93      private IOCase(String name, boolean sensitive) {
94          this.name = name;
95          this.sensitive = sensitive;
96      }
97  
98      /**
99       * Replaces the enumeration from the stream with a real one.
100      * This ensures that the correct flag is set for SYSTEM.
101      * 
102      * @return the resolved object
103      */
104     private Object readResolve() {
105         return forName(name);
106     }
107 
108     //-----------------------------------------------------------------------
109     /**
110      * Gets the name of the constant.
111      * 
112      * @return the name of the constant
113      */
114     public String getName() {
115         return name;
116     }
117 
118     /**
119      * Does the object represent case sensitive comparison.
120      * 
121      * @return true if case sensitive
122      */
123     public boolean isCaseSensitive() {
124         return sensitive;
125     }
126 
127     //-----------------------------------------------------------------------
128     /**
129      * Compares two strings using the case-sensitivity rule.
130      * <p>
131      * This method mimics {@link String#equals} but takes case-sensitivity
132      * into account.
133      * 
134      * @param str1  the first string to compare, not null
135      * @param str2  the second string to compare, not null
136      * @return true if equal using the case rules
137      * @throws NullPointerException if either string is null
138      */
139     public boolean checkEquals(String str1, String str2) {
140         if (str1 == null || str2 == null) {
141             throw new NullPointerException("The strings must not be null");
142         }
143         return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2);
144     }
145 
146     /**
147      * Checks if one string starts with another using the case-sensitivity rule.
148      * <p>
149      * This method mimics {@link String#startsWith(String)} but takes case-sensitivity
150      * into account.
151      * 
152      * @param str  the string to check, not null
153      * @param start  the start to compare against, not null
154      * @return true if equal using the case rules
155      * @throws NullPointerException if either string is null
156      */
157     public boolean checkStartsWith(String str, String start) {
158         return str.regionMatches(!sensitive, 0, start, 0, start.length());
159     }
160 
161     /**
162      * Checks if one string ends with another using the case-sensitivity rule.
163      * <p>
164      * This method mimics {@link String#endsWith} but takes case-sensitivity
165      * into account.
166      * 
167      * @param str  the string to check, not null
168      * @param end  the end to compare against, not null
169      * @return true if equal using the case rules
170      * @throws NullPointerException if either string is null
171      */
172     public boolean checkEndsWith(String str, String end) {
173         int endLen = end.length();
174         return str.regionMatches(!sensitive, str.length() - endLen, end, 0, endLen);
175     }
176 
177     /**
178      * Checks if one string contains another at a specific index using the case-sensitivity rule.
179      * <p>
180      * This method mimics parts of {@link String#regionMatches(boolean, int, String, int, int)} 
181      * but takes case-sensitivity into account.
182      * 
183      * @param str  the string to check, not null
184      * @param strStartIndex  the index to start at in str
185      * @param search  the start to search for, not null
186      * @return true if equal using the case rules
187      * @throws NullPointerException if either string is null
188      */
189     public boolean checkRegionMatches(String str, int strStartIndex, String search) {
190         return str.regionMatches(!sensitive, strStartIndex, search, 0, search.length());
191     }
192 
193     /**
194      * Converts the case of the input String to a standard format.
195      * Subsequent operations can then use standard String methods.
196      * 
197      * @param str  the string to convert, null returns null
198      * @return the lower-case version if case-insensitive
199      */
200     String convertCase(String str) {
201         if (str == null) {
202             return null;
203         }
204         return sensitive ? str : str.toLowerCase();
205     }
206 
207     //-----------------------------------------------------------------------
208     /**
209      * Gets a string describing the sensitivity.
210      * 
211      * @return a string describing the sensitivity
212      */
213     public String toString() {
214         return name;
215     }
216 
217 }