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 */ 17package org.apache.commons.io; 18 19import 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 */ 38public 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