Home | History | Annotate | Download | only in io
      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 606345 2007-12-21 23:43:01Z 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     /**
     46      * The constant for case insensitive regardless of operating system.
     47      */
     48     public static final IOCase INSENSITIVE = new IOCase("Insensitive", false);
     49 
     50     /**
     51      * The constant for case sensitivity determined by the current operating system.
     52      * Windows is case-insensitive when comparing filenames, Unix is case-sensitive.
     53      * <p>
     54      * If you derialize this constant of Windows, and deserialize on Unix, or vice
     55      * versa, then the value of the case-sensitivity flag will change.
     56      */
     57     public static final IOCase SYSTEM = new IOCase("System", !FilenameUtils.isSystemWindows());
     58 
     59     /** Serialization version. */
     60     private static final long serialVersionUID = -6343169151696340687L;
     61 
     62     /** The enumeration name. */
     63     private final String name;
     64 
     65     /** The sensitivity flag. */
     66     private final transient boolean sensitive;
     67 
     68     //-----------------------------------------------------------------------
     69     /**
     70      * Factory method to create an IOCase from a name.
     71      *
     72      * @param name  the name to find
     73      * @return the IOCase object
     74      * @throws IllegalArgumentException if the name is invalid
     75      */
     76     public static IOCase forName(String name) {
     77         if (IOCase.SENSITIVE.name.equals(name)){
     78             return IOCase.SENSITIVE;
     79         }
     80         if (IOCase.INSENSITIVE.name.equals(name)){
     81             return IOCase.INSENSITIVE;
     82         }
     83         if (IOCase.SYSTEM.name.equals(name)){
     84             return IOCase.SYSTEM;
     85         }
     86         throw new IllegalArgumentException("Invalid IOCase name: " + name);
     87     }
     88 
     89     //-----------------------------------------------------------------------
     90     /**
     91      * Private constructor.
     92      *
     93      * @param name  the name
     94      * @param sensitive  the sensitivity
     95      */
     96     private IOCase(String name, boolean sensitive) {
     97         this.name = name;
     98         this.sensitive = sensitive;
     99     }
    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 }
    239