001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.io;
018
019 import java.io.Serializable;
020
021 /**
022 * Enumeration of IO case sensitivity.
023 * <p>
024 * Different filing systems have different rules for case-sensitivity.
025 * Windows is case-insensitive, Unix is case-sensitive.
026 * <p>
027 * This class captures that difference, providing an enumeration to
028 * control how filename comparisons should be performed. It also provides
029 * methods that use the enumeration to perform comparisons.
030 * <p>
031 * Wherever possible, you should use the <code>check</code> methods in this
032 * class to compare filenames.
033 *
034 * @author Stephen Colebourne
035 * @version $Id: IOCase.java 606345 2007-12-21 23:43:01Z ggregory $
036 * @since Commons IO 1.3
037 */
038 public final class IOCase implements Serializable {
039
040 /**
041 * The constant for case sensitive regardless of operating system.
042 */
043 public static final IOCase SENSITIVE = new IOCase("Sensitive", true);
044
045 /**
046 * The constant for case insensitive regardless of operating system.
047 */
048 public static final IOCase INSENSITIVE = new IOCase("Insensitive", false);
049
050 /**
051 * The constant for case sensitivity determined by the current operating system.
052 * Windows is case-insensitive when comparing filenames, Unix is case-sensitive.
053 * <p>
054 * If you derialize this constant of Windows, and deserialize on Unix, or vice
055 * versa, then the value of the case-sensitivity flag will change.
056 */
057 public static final IOCase SYSTEM = new IOCase("System", !FilenameUtils.isSystemWindows());
058
059 /** Serialization version. */
060 private static final long serialVersionUID = -6343169151696340687L;
061
062 /** The enumeration name. */
063 private final String name;
064
065 /** The sensitivity flag. */
066 private final transient boolean sensitive;
067
068 //-----------------------------------------------------------------------
069 /**
070 * Factory method to create an IOCase from a name.
071 *
072 * @param name the name to find
073 * @return the IOCase object
074 * @throws IllegalArgumentException if the name is invalid
075 */
076 public static IOCase forName(String name) {
077 if (IOCase.SENSITIVE.name.equals(name)){
078 return IOCase.SENSITIVE;
079 }
080 if (IOCase.INSENSITIVE.name.equals(name)){
081 return IOCase.INSENSITIVE;
082 }
083 if (IOCase.SYSTEM.name.equals(name)){
084 return IOCase.SYSTEM;
085 }
086 throw new IllegalArgumentException("Invalid IOCase name: " + name);
087 }
088
089 //-----------------------------------------------------------------------
090 /**
091 * Private constructor.
092 *
093 * @param name the name
094 * @param sensitive the sensitivity
095 */
096 private IOCase(String name, boolean sensitive) {
097 this.name = name;
098 this.sensitive = sensitive;
099 }
100
101 /**
102 * Replaces the enumeration from the stream with a real one.
103 * This ensures that the correct flag is set for SYSTEM.
104 *
105 * @return the resolved object
106 */
107 private Object readResolve() {
108 return forName(name);
109 }
110
111 //-----------------------------------------------------------------------
112 /**
113 * Gets the name of the constant.
114 *
115 * @return the name of the constant
116 */
117 public String getName() {
118 return name;
119 }
120
121 /**
122 * Does the object represent case sensitive comparison.
123 *
124 * @return true if case sensitive
125 */
126 public boolean isCaseSensitive() {
127 return sensitive;
128 }
129
130 //-----------------------------------------------------------------------
131 /**
132 * Compares two strings using the case-sensitivity rule.
133 * <p>
134 * This method mimics {@link String#compareTo} but takes case-sensitivity
135 * into account.
136 *
137 * @param str1 the first string to compare, not null
138 * @param str2 the second string to compare, not null
139 * @return true if equal using the case rules
140 * @throws NullPointerException if either string is null
141 */
142 public int checkCompareTo(String str1, String str2) {
143 if (str1 == null || str2 == null) {
144 throw new NullPointerException("The strings must not be null");
145 }
146 return sensitive ? str1.compareTo(str2) : str1.compareToIgnoreCase(str2);
147 }
148
149 /**
150 * Compares two strings using the case-sensitivity rule.
151 * <p>
152 * This method mimics {@link String#equals} but takes case-sensitivity
153 * into account.
154 *
155 * @param str1 the first string to compare, not null
156 * @param str2 the second string to compare, not null
157 * @return true if equal using the case rules
158 * @throws NullPointerException if either string is null
159 */
160 public boolean checkEquals(String str1, String str2) {
161 if (str1 == null || str2 == null) {
162 throw new NullPointerException("The strings must not be null");
163 }
164 return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2);
165 }
166
167 /**
168 * Checks if one string starts with another using the case-sensitivity rule.
169 * <p>
170 * This method mimics {@link String#startsWith(String)} but takes case-sensitivity
171 * into account.
172 *
173 * @param str the string to check, not null
174 * @param start the start to compare against, not null
175 * @return true if equal using the case rules
176 * @throws NullPointerException if either string is null
177 */
178 public boolean checkStartsWith(String str, String start) {
179 return str.regionMatches(!sensitive, 0, start, 0, start.length());
180 }
181
182 /**
183 * Checks if one string ends with another using the case-sensitivity rule.
184 * <p>
185 * This method mimics {@link String#endsWith} but takes case-sensitivity
186 * into account.
187 *
188 * @param str the string to check, not null
189 * @param end the end to compare against, not null
190 * @return true if equal using the case rules
191 * @throws NullPointerException if either string is null
192 */
193 public boolean checkEndsWith(String str, String end) {
194 int endLen = end.length();
195 return str.regionMatches(!sensitive, str.length() - endLen, end, 0, endLen);
196 }
197
198 /**
199 * Checks if one string contains another at a specific index using the case-sensitivity rule.
200 * <p>
201 * This method mimics parts of {@link String#regionMatches(boolean, int, String, int, int)}
202 * but takes case-sensitivity into account.
203 *
204 * @param str the string to check, not null
205 * @param strStartIndex the index to start at in str
206 * @param search the start to search for, not null
207 * @return true if equal using the case rules
208 * @throws NullPointerException if either string is null
209 */
210 public boolean checkRegionMatches(String str, int strStartIndex, String search) {
211 return str.regionMatches(!sensitive, strStartIndex, search, 0, search.length());
212 }
213
214 /**
215 * Converts the case of the input String to a standard format.
216 * Subsequent operations can then use standard String methods.
217 *
218 * @param str the string to convert, null returns null
219 * @return the lower-case version if case-insensitive
220 */
221 String convertCase(String str) {
222 if (str == null) {
223 return null;
224 }
225 return sensitive ? str : str.toLowerCase();
226 }
227
228 //-----------------------------------------------------------------------
229 /**
230 * Gets a string describing the sensitivity.
231 *
232 * @return a string describing the sensitivity
233 */
234 public String toString() {
235 return name;
236 }
237
238 }