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: */
017:
018: package java.text;
019:
020: import org.apache.harmony.text.internal.nls.Messages;
021:
022: /**
023: * <code>RuleBasedCollator</code> is a concrete subclass of
024: * <code>Collator</code>. It allows customization of the
025: * <code>Collator</code> via user-specified rule sets.
026: * <code>RuleBasedCollator</code> is designed to be fully compliant to the <a
027: * href="http://www.unicode.org/unicode/reports/tr10/"> Unicode Collation
028: * Algorithm (UCA) </a> and conforms to ISO 14651.
029: * </p>
030: * <p>
031: * Create a <code>RuleBasedCollator</code> from a locale by calling the
032: * <code>getInstance(Locale)</code> factory method in the base class
033: * <code>Collator</code>.<code>Collator.getInstance(Locale)</code> creates
034: * a <code>RuleBasedCollator</code> object based on the collation rules
035: * defined by the argument locale. If a customized collation is required, use
036: * the <code>RuleBasedCollator(String)</code> constructor with the appropriate
037: * rules. The customized <code>RuleBasedCollator</code> will base its ordering
038: * on UCA, while re-adjusting the attributes and orders of the characters in the
039: * specified rule accordingly.
040: * </p>
041: *
042: */
043: public class RuleBasedCollator extends Collator {
044:
045: RuleBasedCollator(com.ibm.icu.text.Collator wrapper) {
046: super (wrapper);
047: }
048:
049: /**
050: * Constructs a new instance of <code>RuleBasedCollator</code> using the
051: * specified <code>rules</code>.
052: *
053: * @param rules
054: * the collation rules.
055: * @throws ParseException
056: * when the rules contains an invalid collation rule syntax.
057: */
058: public RuleBasedCollator(String rules) throws ParseException {
059: if (rules == null) {
060: throw new NullPointerException();
061: }
062: if (rules.length() == 0) {
063: // text.06=Build rules empty
064: throw new ParseException(Messages.getString("text.06"), 0); //$NON-NLS-1$
065: }
066:
067: try {
068: this .icuColl = new com.ibm.icu.text.RuleBasedCollator(rules);
069: } catch (Exception e) {
070: if (e instanceof ParseException) {
071: throw (ParseException) e;
072: }
073: /*
074: * -1 means it's not a ParseException. Maybe IOException thrown when
075: * an error occured while reading internal data.
076: */
077: throw new ParseException(e.getMessage(), -1);
078: }
079: }
080:
081: /**
082: * Obtains a <code>CollationElementIterator</code> for the given
083: * <code>CharacterIterator</code>. The source iterator's integrity will
084: * be preserved since a new copy will be created for use.
085: *
086: * @param source
087: * the specified source
088: * @return a <code>CollationElementIterator</code> for the source.
089: */
090: public CollationElementIterator getCollationElementIterator(
091: CharacterIterator source) {
092: if (source == null) {
093: throw new NullPointerException();
094: }
095: return new CollationElementIterator(
096: ((com.ibm.icu.text.RuleBasedCollator) this .icuColl)
097: .getCollationElementIterator(source));
098: }
099:
100: /**
101: * Obtains a <code>CollationElementIterator</code> for the given String.
102: *
103: * @param source
104: * the specified source
105: * @return a <code>CollationElementIterator</code> for the given String
106: */
107: public CollationElementIterator getCollationElementIterator(
108: String source) {
109: if (source == null) {
110: throw new NullPointerException();
111: }
112: return new CollationElementIterator(
113: ((com.ibm.icu.text.RuleBasedCollator) this .icuColl)
114: .getCollationElementIterator(source));
115: }
116:
117: /**
118: * Obtains the collation rules of the <code>RuleBasedCollator</code>.
119: *
120: * @return the collation rules.
121: */
122: public String getRules() {
123: return ((com.ibm.icu.text.RuleBasedCollator) this .icuColl)
124: .getRules();
125: }
126:
127: /**
128: * Obtains the cloned object of the <code>RuleBasedCollator</code>
129: *
130: * @return the cloned object of the <code>RuleBasedCollator</code>
131: */
132: @Override
133: public Object clone() {
134: RuleBasedCollator clone = (RuleBasedCollator) super .clone();
135: return clone;
136: }
137:
138: /**
139: * Compares the <code>source</code> text <code>String</code> to the
140: * <code>target</code> text <code>String</code> according to the
141: * collation rules, strength and decomposition mode for this
142: * <code>RuleBasedCollator</code>. See the <code>Collator</code> class
143: * description for an example of use.
144: * <p>
145: * General recommendation: If comparisons are to be done to the same String
146: * multiple times, it would be more efficient to generate
147: * <code>CollationKeys</code> for the <code>String</code> s and use
148: * <code>CollationKey.compareTo(CollationKey)</code> for the comparisons.
149: * If the each Strings are compared to only once, using the method
150: * RuleBasedCollator.compare(String, String) will have a better performance.
151: * </p>
152: *
153: * @param source
154: * the source text
155: * @param target
156: * the target text
157: * @return an integer which may be a negative value, zero, or else a
158: * positive value depending on whether <code>source</code> is less
159: * than, equivalent to, or greater than <code>target</code>.
160: */
161: @Override
162: public int compare(String source, String target) {
163: if (source == null || target == null) {
164: // text.08=one of arguments is null
165: throw new NullPointerException(Messages
166: .getString("text.08")); //$NON-NLS-1$
167: }
168: return this .icuColl.compare(source, target);
169: }
170:
171: /**
172: * Obtains the <code>CollationKey</code> for the given source text.
173: *
174: * @param source
175: * the specified source text
176: * @return the <code>CollationKey</code> for the given source text.
177: */
178: @Override
179: public CollationKey getCollationKey(String source) {
180: com.ibm.icu.text.CollationKey icuKey = this .icuColl
181: .getCollationKey(source);
182: if (icuKey == null) {
183: return null;
184: }
185: return new CollationKey(source, icuKey);
186: }
187:
188: /**
189: * Obtains a unique hash code for the <code>RuleBasedCollator</code>
190: *
191: * @return the hash code for the <code>RuleBasedCollator</code>
192: */
193: @Override
194: public int hashCode() {
195: return ((com.ibm.icu.text.RuleBasedCollator) this .icuColl)
196: .getRules().hashCode();
197: }
198:
199: /**
200: * Compares the equality of two <code>RuleBasedCollator</code> objects.
201: * <code>RuleBasedCollator</code> objects are equal if they have the same
202: * collation rules and the same attributes.
203: *
204: * @param obj
205: * the other object.
206: * @return <code>true</code> if this <code>RuleBasedCollator</code> has
207: * exactly the same collation behaviour as obj, <code>false</code>
208: * otherwise.
209: */
210: @Override
211: public boolean equals(Object obj) {
212: if (!(obj instanceof Collator)) {
213: return false;
214: }
215: return super.equals(obj);
216: }
217: }
|