/* * The MIT License (MIT) * * Copyright (c) 2016 Lachlan Dowding * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package permafrost.tundra.lang; import java.io.Serializable; import java.util.Locale; /** * A case insensitive for comparison and case preserving for reference string wrapper. */ public class CaseInsensitiveString implements CharSequence, Comparable<CharSequence>, Serializable { /** * The serialization identity for this class and version. */ private static final long serialVersionUID = 1; /** * The strings to be wrapped. */ protected String originalString, lowercaseString; /** * The locale to use for case comparison. */ protected Locale locale; /** * Constructs a new CaseInsensitiveString. * * @param charSequence The string to be wrapped. */ public CaseInsensitiveString(CharSequence charSequence) { this(charSequence, null); } /** * Constructs a new CaseInsensitiveString. * * @param charSequence The string to be wrapped. * @param locale The locale to use for case comparison. */ public CaseInsensitiveString(CharSequence charSequence, Locale locale) { if (charSequence == null) throw new NullPointerException("charSequence must not be null"); this.locale = locale == null ? Locale.getDefault() : locale; this.originalString = charSequence.toString(); this.lowercaseString = this.originalString.toLowerCase(this.locale); } /** * Returns the character at the given index. * * @param i The character index. * @return The character at the given index. */ public char charAt(int i) { return this.originalString.charAt(i); } /** * Returns the number of characters in this string. * * @return The number of characters in this string. */ public int length() { return this.originalString.length(); } /** * Returns a sub-sequence for the given range of characters. * * @param start The start index for the range. * @param end The end index for the range. * @return The sub-sequence of characters for the given range. */ public CaseInsensitiveString subSequence(int start, int end) { return new CaseInsensitiveString(originalString.subSequence(start, end)); } /** * Performs a case-insensitive comparison with the other string. * * @param other A string to compared with this object. * @return The result of the comparison. */ public int compareTo(CharSequence other) { return this.lowercaseString.compareTo(other.toString().toLowerCase(locale)); } /** * Compares this object against another for equality. * * @param other The other object to compare this object against for equality. * @return True if the two objects are equal. */ @Override public boolean equals(Object other) { if (this == other) return true; boolean result = false; if (other instanceof CharSequence) { String otherString = ((CharSequence)other).toString(); result = this.lowercaseString.equals(otherString.toLowerCase(locale)); } return result; } /** * Returns a hash code value for the object. * * @return A hash code value for the object. */ @Override public int hashCode() { return lowercaseString.hashCode(); } /** * Returns the original string wrapped by this case-insensitive string object. * * @return The original string wrapped by this case-insensitive string object. */ @Override public String toString() { return this.originalString; } }