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 }