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 */ 017package org.apache.commons.io; 018 019import 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 * @since 1.3 035 */ 036public enum IOCase implements Serializable { 037 038 /** 039 * The constant for case sensitive regardless of operating system. 040 */ 041 SENSITIVE ("Sensitive", true), 042 043 /** 044 * The constant for case insensitive regardless of operating system. 045 */ 046 INSENSITIVE ("Insensitive", false), 047 048 /** 049 * The constant for case sensitivity determined by the current operating system. 050 * Windows is case-insensitive when comparing filenames, Unix is case-sensitive. 051 * <p> 052 * <strong>Note:</strong> This only caters for Windows and Unix. Other operating 053 * systems (e.g. OSX and OpenVMS) are treated as case sensitive if they use the 054 * Unix file separator and case-insensitive if they use the Windows file separator 055 * (see {@link java.io.File#separatorChar}). 056 * <p> 057 * If you serialize this constant on Windows, and deserialize on Unix, or vice 058 * versa, then the value of the case-sensitivity flag will change. 059 */ 060 SYSTEM ("System", !FilenameUtils.isSystemWindows()); 061 062 /** Serialization version. */ 063 private static final long serialVersionUID = -6343169151696340687L; 064 065 /** The enumeration name. */ 066 private final String name; 067 068 /** The sensitivity flag. */ 069 private final transient boolean sensitive; 070 071 //----------------------------------------------------------------------- 072 /** 073 * Factory method to create an IOCase from a name. 074 * 075 * @param name the name to find 076 * @return the IOCase object 077 * @throws IllegalArgumentException if the name is invalid 078 */ 079 public static IOCase forName(final String name) { 080 for (final IOCase ioCase : IOCase.values()) 081 { 082 if (ioCase.getName().equals(name)) 083 { 084 return ioCase; 085 } 086 } 087 throw new IllegalArgumentException("Invalid IOCase name: " + name); 088 } 089 090 //----------------------------------------------------------------------- 091 /** 092 * Private constructor. 093 * 094 * @param name the name 095 * @param sensitive the sensitivity 096 */ 097 private IOCase(final String name, final boolean sensitive) { 098 this.name = name; 099 this.sensitive = sensitive; 100 } 101 102 /** 103 * Replaces the enumeration from the stream with a real one. 104 * This ensures that the correct flag is set for SYSTEM. 105 * 106 * @return the resolved object 107 */ 108 private Object readResolve() { 109 return forName(name); 110 } 111 112 //----------------------------------------------------------------------- 113 /** 114 * Gets the name of the constant. 115 * 116 * @return the name of the constant 117 */ 118 public String getName() { 119 return name; 120 } 121 122 /** 123 * Does the object represent case sensitive comparison. 124 * 125 * @return true if case sensitive 126 */ 127 public boolean isCaseSensitive() { 128 return sensitive; 129 } 130 131 //----------------------------------------------------------------------- 132 /** 133 * Compares two strings using the case-sensitivity rule. 134 * <p> 135 * This method mimics {@link String#compareTo} but takes case-sensitivity 136 * into account. 137 * 138 * @param str1 the first string to compare, not null 139 * @param str2 the second string to compare, not null 140 * @return true if equal using the case rules 141 * @throws NullPointerException if either string is null 142 */ 143 public int checkCompareTo(final String str1, final String str2) { 144 if (str1 == null || str2 == null) { 145 throw new NullPointerException("The strings must not be null"); 146 } 147 return sensitive ? str1.compareTo(str2) : str1.compareToIgnoreCase(str2); 148 } 149 150 /** 151 * Compares two strings using the case-sensitivity rule. 152 * <p> 153 * This method mimics {@link String#equals} but takes case-sensitivity 154 * into account. 155 * 156 * @param str1 the first string to compare, not null 157 * @param str2 the second string to compare, not null 158 * @return true if equal using the case rules 159 * @throws NullPointerException if either string is null 160 */ 161 public boolean checkEquals(final String str1, final 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 172 * into account. 173 * 174 * @param str the string to check, not null 175 * @param start the start to compare against, not null 176 * @return true if equal using the case rules 177 * @throws NullPointerException if either string is null 178 */ 179 public boolean checkStartsWith(final String str, final String start) { 180 return str.regionMatches(!sensitive, 0, start, 0, start.length()); 181 } 182 183 /** 184 * Checks if one string ends with another using the case-sensitivity rule. 185 * <p> 186 * This method mimics {@link String#endsWith} but takes case-sensitivity 187 * into account. 188 * 189 * @param str the string to check, not null 190 * @param end the end to compare against, not null 191 * @return true if equal using the case rules 192 * @throws NullPointerException if either string is null 193 */ 194 public boolean checkEndsWith(final String str, final String end) { 195 final int endLen = end.length(); 196 return str.regionMatches(!sensitive, str.length() - endLen, end, 0, endLen); 197 } 198 199 /** 200 * Checks if one string contains another starting at a specific index using the 201 * case-sensitivity rule. 202 * <p> 203 * This method mimics parts of {@link String#indexOf(String, int)} 204 * but takes case-sensitivity into account. 205 * 206 * @param str the string to check, not null 207 * @param strStartIndex the index to start at in str 208 * @param search the start to search for, not null 209 * @return the first index of the search String, 210 * -1 if no match or {@code null} string input 211 * @throws NullPointerException if either string is null 212 * @since 2.0 213 */ 214 public int checkIndexOf(final String str, final int strStartIndex, final String search) { 215 final int endIndex = str.length() - search.length(); 216 if (endIndex >= strStartIndex) { 217 for (int i = strStartIndex; i <= endIndex; i++) { 218 if (checkRegionMatches(str, i, search)) { 219 return i; 220 } 221 } 222 } 223 return -1; 224 } 225 226 /** 227 * Checks if one string contains another at a specific index using the case-sensitivity rule. 228 * <p> 229 * This method mimics parts of {@link String#regionMatches(boolean, int, String, int, int)} 230 * but takes case-sensitivity into account. 231 * 232 * @param str the string to check, not null 233 * @param strStartIndex the index to start at in str 234 * @param search the start to search for, not null 235 * @return true if equal using the case rules 236 * @throws NullPointerException if either string is null 237 */ 238 public boolean checkRegionMatches(final String str, final int strStartIndex, final String search) { 239 return str.regionMatches(!sensitive, strStartIndex, search, 0, search.length()); 240 } 241 242 //----------------------------------------------------------------------- 243 /** 244 * Gets a string describing the sensitivity. 245 * 246 * @return a string describing the sensitivity 247 */ 248 @Override 249 public String toString() { 250 return name; 251 } 252 253}