View Javadoc

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