1/**
2*******************************************************************************
3* Copyright (C) 1996-2005, International Business Machines Corporation and    *
4* others. All Rights Reserved.                                                *
5*******************************************************************************
6*
7*
8*******************************************************************************
9*/
10
11package libcore.icu;
12
13import java.text.CharacterIterator;
14import java.text.CollationKey;
15import java.text.ParseException;
16import java.util.Locale;
17
18public final class RuleBasedCollatorICU implements Cloneable {
19    // Values from the native UColAttributeValue enum.
20    public static final int VALUE_DEFAULT = -1;
21    public static final int VALUE_PRIMARY = 0;
22    public static final int VALUE_SECONDARY = 1;
23    public static final int VALUE_TERTIARY = 2;
24    public static final int VALUE_DEFAULT_STRENGTH = VALUE_TERTIARY;
25    public static final int VALUE_QUATERNARY = 3;
26    public static final int VALUE_IDENTICAL = 15;
27    public static final int VALUE_OFF = 16;
28    public static final int VALUE_ON = 17;
29    public static final int VALUE_SHIFTED = 20;
30    public static final int VALUE_NON_IGNORABLE = 21;
31    public static final int VALUE_LOWER_FIRST = 24;
32    public static final int VALUE_UPPER_FIRST = 25;
33    public static final int VALUE_ON_WITHOUT_HANGUL = 28;
34    public static final int VALUE_ATTRIBUTE_VALUE_COUNT = 29;
35
36    // Values from the UColAttribute enum.
37    public static final int FRENCH_COLLATION = 0;
38    public static final int ALTERNATE_HANDLING = 1;
39    public static final int CASE_FIRST = 2;
40    public static final int CASE_LEVEL = 3;
41    public static final int DECOMPOSITION_MODE = 4;
42    public static final int STRENGTH = 5;
43
44    // The address of the ICU4C native peer.
45    private int address;
46
47    public RuleBasedCollatorICU(String rules) throws ParseException {
48        if (rules == null) {
49            throw new NullPointerException("rules == null");
50        }
51        address = NativeCollation.openCollatorFromRules(rules, VALUE_OFF, VALUE_DEFAULT_STRENGTH);
52    }
53
54    public RuleBasedCollatorICU(Locale locale) {
55        address = NativeCollation.openCollator(locale.toString());
56    }
57
58    private RuleBasedCollatorICU(int address) {
59        this.address = address;
60    }
61
62    public Object clone() {
63        return new RuleBasedCollatorICU(NativeCollation.safeClone(address));
64    }
65
66    public int compare(String source, String target) {
67        return NativeCollation.compare(address, source, target);
68    }
69
70    public int getDecomposition() {
71        return NativeCollation.getAttribute(address, DECOMPOSITION_MODE);
72    }
73
74    public void setDecomposition(int mode) {
75        NativeCollation.setAttribute(address, DECOMPOSITION_MODE, mode);
76    }
77
78    public int getStrength() {
79        return NativeCollation.getAttribute(address, STRENGTH);
80    }
81
82    public void setStrength(int strength) {
83        NativeCollation.setAttribute(address, STRENGTH, strength);
84    }
85
86    public void setAttribute(int type, int value) {
87        NativeCollation.setAttribute(address, type, value);
88    }
89
90    public int getAttribute(int type) {
91        return NativeCollation.getAttribute(address, type);
92    }
93
94    public CollationKey getCollationKey(String source) {
95        if (source == null) {
96            return null;
97        }
98        byte[] key = NativeCollation.getSortKey(address, source);
99        if (key == null) {
100            return null;
101        }
102        return new CollationKeyICU(source, key);
103    }
104
105    public String getRules() {
106        return NativeCollation.getRules(address);
107    }
108
109    public CollationElementIteratorICU getCollationElementIterator(String source) {
110        return CollationElementIteratorICU.getInstance(address, source);
111    }
112
113    public CollationElementIteratorICU getCollationElementIterator(CharacterIterator it) {
114        // We only implement the String-based API, so build a string from the iterator.
115        return getCollationElementIterator(characterIteratorToString(it));
116    }
117
118    private String characterIteratorToString(CharacterIterator it) {
119        StringBuilder result = new StringBuilder();
120        for (char ch = it.current(); ch != CharacterIterator.DONE; ch = it.next()) {
121            result.append(ch);
122        }
123        return result.toString();
124    }
125
126    @Override public int hashCode() {
127        return 42; // No-one uses RuleBasedCollatorICU as a hash key.
128    }
129
130    public boolean equals(String source, String target) {
131        return (compare(source, target) == 0);
132    }
133
134    @Override public boolean equals(Object object) {
135        if (object ==  this) {
136            return true;
137        }
138        if (!(object instanceof RuleBasedCollatorICU)) {
139            return false;
140        }
141        RuleBasedCollatorICU rhs = (RuleBasedCollatorICU) object;
142        return getRules().equals(rhs.getRules()) &&
143                getStrength() == rhs.getStrength() &&
144                getDecomposition() == rhs.getDecomposition();
145    }
146
147    @Override protected void finalize() throws Throwable {
148        try {
149            NativeCollation.closeCollator(address);
150        } finally {
151            super.finalize();
152        }
153    }
154}
155