Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 57518 invoked from network); 1 Dec 2005 06:22:38 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 1 Dec 2005 06:22:38 -0000 Received: (qmail 9001 invoked by uid 500); 1 Dec 2005 06:17:40 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 8325 invoked by uid 500); 1 Dec 2005 06:17:35 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 2254 invoked by uid 99); 1 Dec 2005 06:16:39 -0000 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Wed, 30 Nov 2005 22:12:38 -0800 Received: (qmail 44011 invoked by uid 65534); 1 Dec 2005 06:11:32 -0000 Message-ID: <20051201061132.44010.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: svn commit: r350181 [135/198] - in /incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core: ./ depends/ depends/files/ depends/jars/ depends/libs/ depends/libs/linux.IA32/ depends/libs/win.IA32/ depends/oss/ depends/oss/linux.IA32/ depends/oss/win.... Date: Thu, 01 Dec 2005 06:04:00 -0000 To: harmony-commits@incubator.apache.org From: geirm@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/AttributedString.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/AttributedString.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/AttributedString.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/AttributedString.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,590 @@ +/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.text; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; + +import com.ibm.oti.util.Msg; + +/** + * AttributedString + */ +public class AttributedString { + + String text; + + Map attributeMap; + + static class Range { + int start, end; + + Object value; + + Range(int s, int e, Object v) { + start = s; + end = e; + value = v; + } + } + + static class AttributedIterator implements AttributedCharacterIterator { + + private int begin, end, offset; + + private AttributedString attrString; + + private HashSet attributesAllowed; + + AttributedIterator(AttributedString attrString) { + this.attrString = attrString; + begin = 0; + end = attrString.text.length(); + offset = 0; + } + + AttributedIterator(AttributedString attrString, + AttributedCharacterIterator.Attribute[] attributes, int begin, + int end) { + if (begin < 0 || end > attrString.text.length() || begin > end) + throw new IllegalArgumentException(); + this.begin = begin; + this.end = end; + offset = begin; + this.attrString = attrString; + if (attributes != null) { + HashSet set = new HashSet((attributes.length * 4 / 3) + 1); + for (int i = attributes.length; --i >= 0;) + set.add(attributes[i]); + attributesAllowed = set; + } + } + + /** + * Answers a new StringCharacterIterator with the same source String, + * begin, end, and current index as this StringCharacterIterator. + * + * @return a shallow copy of this StringCharacterIterator + * + * @see java.lang.Cloneable + */ + public Object clone() { + try { + AttributedIterator clone = (AttributedIterator) super.clone(); + if (attributesAllowed != null) + clone.attributesAllowed = (HashSet) attributesAllowed + .clone(); + return clone; + } catch (CloneNotSupportedException e) { + return null; + } + } + + /** + * Answers the character at the current index in the source String. + * + * @return the current character, or DONE if the current index is past + * the end + */ + public char current() { + if (offset == end) + return DONE; + return attrString.text.charAt(offset); + } + + /** + * Sets the current position to the begin index and answers the + * character at the begin index. + * + * @return the character at the begin index + */ + public char first() { + if (begin == end) + return DONE; + offset = begin; + return attrString.text.charAt(offset); + } + + /** + * Answers the begin index in the source String. + * + * @return the index of the first character to iterate + */ + public int getBeginIndex() { + return begin; + } + + /** + * Answers the end index in the source String. + * + * @return the index one past the last character to iterate + */ + public int getEndIndex() { + return end; + } + + /** + * Answers the current index in the source String. + * + * @return the current index + */ + public int getIndex() { + return offset; + } + + private boolean inRange(Range range) { + if (!(range.value instanceof Annotation)) + return true; + return range.start >= begin && range.start < end + && range.end > begin && range.end <= end; + } + + private boolean inRange(ArrayList ranges) { + Iterator it = ranges.iterator(); + while (it.hasNext()) { + Range range = (Range) it.next(); + if (range.start >= begin && range.start < end) { + return !(range.value instanceof Annotation) + || (range.end > begin && range.end <= end); + } else if (range.end > begin && range.end <= end) { + return !(range.value instanceof Annotation) + || (range.start >= begin && range.start < end); + } + } + return false; + } + + public Set getAllAttributeKeys() { + if (begin == 0 && end == attrString.text.length() + && attributesAllowed == null) + return attrString.attributeMap.keySet(); + + HashSet result = new HashSet( + (attrString.attributeMap.size() * 4 / 3) + 1); + Iterator it = attrString.attributeMap.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + if (attributesAllowed == null + || attributesAllowed.contains(entry.getKey())) { + ArrayList ranges = (ArrayList) entry.getValue(); + if (inRange(ranges)) + result.add(entry.getKey()); + } + } + return result; + } + + private Object currentValue(ArrayList ranges) { + Iterator it = ranges.iterator(); + while (it.hasNext()) { + Range range = (Range) it.next(); + if (offset >= range.start && offset < range.end) + return inRange(range) ? range.value : null; + } + return null; + } + + public Object getAttribute( + AttributedCharacterIterator.Attribute attribute) { + if (attributesAllowed != null + && !attributesAllowed.contains(attribute)) + return null; + ArrayList ranges = (ArrayList) attrString.attributeMap + .get(attribute); + if (ranges == null) + return null; + return currentValue(ranges); + } + + public Map getAttributes() { + HashMap result = new HashMap( + (attrString.attributeMap.size() * 4 / 3) + 1); + Iterator it = attrString.attributeMap.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + if (attributesAllowed == null + || attributesAllowed.contains(entry.getKey())) { + Object value = currentValue((ArrayList) entry.getValue()); + if (value != null) + result.put(entry.getKey(), value); + } + } + return result; + } + + public int getRunLimit() { + return getRunLimit(getAllAttributeKeys()); + } + + private int runLimit(ArrayList ranges) { + int result = end; + ListIterator it = ranges.listIterator(ranges.size()); + while (it.hasPrevious()) { + Range range = (Range) it.previous(); + if (range.end <= begin) + break; + if (offset >= range.start && offset < range.end) { + return inRange(range) ? range.end : result; + } else if (offset >= range.end) + break; + result = range.start; + } + return result; + } + + public int getRunLimit(AttributedCharacterIterator.Attribute attribute) { + if (attributesAllowed != null + && !attributesAllowed.contains(attribute)) + return end; + ArrayList ranges = (ArrayList) attrString.attributeMap + .get(attribute); + if (ranges == null) + return end; + return runLimit(ranges); + } + + public int getRunLimit(Set attributes) { + int limit = end; + Iterator it = attributes.iterator(); + while (it.hasNext()) { + AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute) it + .next(); + int newLimit = getRunLimit(attribute); + if (newLimit < limit) + limit = newLimit; + } + return limit; + } + + public int getRunStart() { + return getRunStart(getAllAttributeKeys()); + } + + private int runStart(ArrayList ranges) { + int result = begin; + Iterator it = ranges.iterator(); + while (it.hasNext()) { + Range range = (Range) it.next(); + if (range.start >= end) + break; + if (offset >= range.start && offset < range.end) { + return inRange(range) ? range.start : result; + } else if (offset < range.start) + break; + result = range.end; + } + return result; + } + + public int getRunStart(AttributedCharacterIterator.Attribute attribute) { + if (attributesAllowed != null + && !attributesAllowed.contains(attribute)) + return begin; + ArrayList ranges = (ArrayList) attrString.attributeMap + .get(attribute); + if (ranges == null) + return begin; + return runStart(ranges); + } + + public int getRunStart(Set attributes) { + int start = begin; + Iterator it = attributes.iterator(); + while (it.hasNext()) { + AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute) it + .next(); + int newStart = getRunStart(attribute); + if (newStart > start) + start = newStart; + } + return start; + } + + /** + * Sets the current position to the end index - 1 and answers the + * character at the current position. + * + * @return the character before the end index + */ + public char last() { + if (begin == end) + return DONE; + offset = end - 1; + return attrString.text.charAt(offset); + } + + /** + * Increments the current index and returns the character at the new + * index. + * + * @return the character at the next index, or DONE if the next index is + * past the end + */ + public char next() { + if (offset >= (end - 1)) { + offset = end; + return DONE; + } + return attrString.text.charAt(++offset); + } + + /** + * Decrements the current index and returns the character at the new + * index. + * + * @return the character at the previous index, or DONE if the previous + * index is past the beginning + */ + public char previous() { + if (offset == begin) + return DONE; + return attrString.text.charAt(--offset); + } + + /** + * Sets the current index in the source String. + * + * @return the character at the new index, or DONE if the index is past + * the end + * + * @exception IllegalArgumentException + * when the new index is less than the begin index or + * greater than the end index + */ + public char setIndex(int location) { + if (location < begin || location > end) + throw new IllegalArgumentException(); + offset = location; + if (offset == end) + return DONE; + return attrString.text.charAt(offset); + } + } + + public AttributedString(AttributedCharacterIterator iterator) { + StringBuffer buffer = new StringBuffer(); + while (iterator.current() != CharacterIterator.DONE) { + buffer.append(iterator.current()); + iterator.next(); + } + text = buffer.toString(); + Set attributes = iterator.getAllAttributeKeys(); + attributeMap = new HashMap((attributes.size() * 4 / 3) + 1); + + Iterator it = attributes.iterator(); + while (it.hasNext()) { + AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute) it + .next(); + iterator.setIndex(0); + while (iterator.current() != CharacterIterator.DONE) { + int start = iterator.getRunStart(attribute); + int limit = iterator.getRunLimit(attribute); + Object value = iterator.getAttribute(attribute); + if (value != null) + addAttribute(attribute, value, start, limit); + iterator.setIndex(limit); + } + } + } + + private AttributedString(AttributedCharacterIterator iterator, int start, + int end, Set attributes) { + if (start < iterator.getBeginIndex() || end > iterator.getEndIndex() + || start > end) + throw new IllegalArgumentException(); + + StringBuffer buffer = new StringBuffer(); + iterator.setIndex(start); + while (iterator.getIndex() < end) { + buffer.append(iterator.current()); + iterator.next(); + } + text = buffer.toString(); + attributeMap = new HashMap((attributes.size() * 4 / 3) + 1); + + Iterator it = attributes.iterator(); + while (it.hasNext()) { + AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute) it + .next(); + iterator.setIndex(start); + while (iterator.getIndex() < end) { + Object value = iterator.getAttribute(attribute); + int runStart = iterator.getRunStart(attribute); + int limit = iterator.getRunLimit(attribute); + if ((value instanceof Annotation && runStart >= start && limit <= end) + || (value != null && !(value instanceof Annotation))) { + addAttribute(attribute, value, (runStart < start ? start + : runStart) + - start, (limit > end ? end : limit) - start); + } + iterator.setIndex(limit); + } + } + } + + public AttributedString(AttributedCharacterIterator iterator, int start, + int end) { + this(iterator, start, end, iterator.getAllAttributeKeys()); + } + + public AttributedString(AttributedCharacterIterator iterator, int start, + int end, AttributedCharacterIterator.Attribute[] attributes) { + this(iterator, start, end, new HashSet(Arrays.asList(attributes))); + } + + public AttributedString(String value) { + if (value == null) + throw new NullPointerException(); + text = value; + attributeMap = new HashMap(11); + } + + public AttributedString(String value, Map attributes) { + if (value == null) + throw new NullPointerException(); + if (value.length() == 0 && !attributes.isEmpty()) + throw new IllegalArgumentException(Msg.getString("K000e")); + text = value; + attributeMap = new HashMap((attributes.size() * 4 / 3) + 1); + Iterator it = attributes.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + ArrayList ranges = new ArrayList(1); + ranges.add(new Range(0, text.length(), entry.getValue())); + attributeMap.put(entry.getKey(), ranges); + } + } + + public void addAttribute(AttributedCharacterIterator.Attribute attribute, + Object value) { + if (text.length() == 0) + throw new IllegalArgumentException(); + + ArrayList ranges = (ArrayList) attributeMap.get(attribute); + if (ranges == null) { + ranges = new ArrayList(1); + attributeMap.put(attribute, ranges); + } else { + ranges.clear(); + } + ranges.add(new Range(0, text.length(), value)); + } + + public void addAttribute(AttributedCharacterIterator.Attribute attribute, + Object value, int start, int end) { + if (start < 0 || end > text.length() || start >= end) + throw new IllegalArgumentException(); + + ArrayList ranges = (ArrayList) attributeMap.get(attribute); + if (ranges == null) { + ranges = new ArrayList(1); + ranges.add(new Range(start, end, value)); + attributeMap.put(attribute, ranges); + return; + } + ListIterator it = ranges.listIterator(); + while (it.hasNext()) { + Range range = (Range) it.next(); + if (end <= range.start) { + it.previous(); + break; + } else if (start < range.end + || (start == range.end && (value == null ? range.value == null + : value.equals(range.value)))) { + Range r1 = null, r3; + it.remove(); + r1 = new Range(range.start, start, range.value); + r3 = new Range(end, range.end, range.value); + + while (end > range.end && it.hasNext()) { + range = (Range) it.next(); + if (end <= range.end) { + if (end > range.start + || (end == range.start && (value == null ? range.value == null + : value.equals(range.value)))) { + it.remove(); + r3 = new Range(end, range.end, range.value); + break; + } + } else + it.remove(); + } + + if (value == null ? r1.value == null : value.equals(r1.value)) { + if (value == null ? r3.value == null : value + .equals(r3.value)) { + it.add(new Range(r1.start < start ? r1.start : start, + r3.end > end ? r3.end : end, r1.value)); + } else { + it.add(new Range(r1.start < start ? r1.start : start, + end, r1.value)); + if (r3.start < r3.end) + it.add(r3); + } + } else { + if (value == null ? r3.value == null : value + .equals(r3.value)) { + if (r1.start < r1.end) + it.add(r1); + it.add(new Range(start, r3.end > end ? r3.end : end, + r3.value)); + } else { + if (r1.start < r1.end) + it.add(r1); + it.add(new Range(start, end, value)); + if (r3.start < r3.end) + it.add(r3); + } + } + return; + } + } + it.add(new Range(start, end, value)); + } + + public void addAttributes(Map attributes, int start, int end) { + Iterator it = attributes.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + addAttribute( + (AttributedCharacterIterator.Attribute) entry.getKey(), + entry.getValue(), start, end); + } + } + + public AttributedCharacterIterator getIterator() { + return new AttributedIterator(this); + } + + public AttributedCharacterIterator getIterator( + AttributedCharacterIterator.Attribute[] attributes) { + return new AttributedIterator(this, attributes, 0, text.length()); + } + + public AttributedCharacterIterator getIterator( + AttributedCharacterIterator.Attribute[] attributes, int start, + int end) { + return new AttributedIterator(this, attributes, start, end); + } + +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/Bidi.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/Bidi.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/Bidi.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/Bidi.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,463 @@ +/* Copyright 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.text; + + +import java.util.Arrays; +import java.util.LinkedList; + +import com.ibm.text.BidiRun; +import com.ibm.text.BidiWrapper; + +/** + * Bidi is the class providing the bidirectional algorithm. The algorithm is + * defined in the Unicode Standard Annex #9, version 13, also described in The + * Unicode Standard, Version 4.0 . + * + * Use a Bidi object to get the infomation on the position reordering of a + * bidirectional text, such as Arabic or Hebrew. The natural display ordering of + * horizontal text in these languages is from right to left, while they order + * numbers from left to right. + * + * If the text contains multiple runs, the information of each run can be + * obtained from the run index. The level of any particular run indicates the + * direction of the text as well as the nesting level. Left-to-right runs have + * even levels while right-to-left runs have odd levels. + * + */ +public final class Bidi { + /** + * Constant that indicates the default base level. If there is no strong + * character, then set the paragraph level to 0 (left-to-right). + */ + public static final int DIRECTION_DEFAULT_LEFT_TO_RIGHT = -2; + + /** + * Constant that indicates the default base level. If there is no strong + * character, then set the paragraph level to 1 (right-to-left). + */ + public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = -1; + + /** + * Constant that specifies the default base level as 0 (left-to-right). + */ + public static final int DIRECTION_LEFT_TO_RIGHT = 0; + + /** + * Constant that specifies the default base level as 1 (right-to-left). + */ + public static final int DIRECTION_RIGHT_TO_LEFT = 1; + + /** + * Create a Bidi object from the AttributedCharacterIterator of a paragraph + * text. + * + * The RUN_DIRECTION attribute determines the base direction of the + * bidirectional text. If it's not specified explicitly, the algorithm uses + * DIRECTION_DEFAULT_LEFT_TO_RIGHT by default. + * + * The BIDI_EMBEDDING attribute specifies the level of embedding for each + * character. Values between -1 and -62 denote overrides at the level's + * absolute value, values from 1 to 62 indicate embeddings, and the + * 0 value indicates the level is calculated by the algorithm automatically. + * For the character with no BIDI_EMBEDDING attribute or with a improper + * attribute value, such as a null value, the algorithm treats its embedding + * level as 0. + * + * The NUMERIC_SHAPING attribute specifies the instance of NumericShaper + * used to convert European digits to other decimal digits before performing + * the bidi algorithm. + * + * @param paragraph + * + * @see TextAttribute.BIDI_EMBEDDING + * @see TextAttribute.NUMERIC_SHAPING + * @see TextAttribute.RUN_DIRECTION + */ + public Bidi(AttributedCharacterIterator paragraph) { + /* + * TODO: dependency on java.awt.font.TextAttribute and + * java.awt.font.NumericShaper which is not implemented yet. + */ + } + + /** + * Create a Bidi object. + * + * @param text + * the char array of the paragraph text. + * @param textStart + * the start offset of the text array to perform the algorithm. + * @param embeddings + * the embedding level array of the paragraph text, specifying + * the embedding level infomation for each character. Values + * between -1 and -62 denote overrides at the level's absolute + * value, values from 1 to 62 indicate embeddings, and the 0 + * value indicates the level is calculated by the algorithm + * automatically. + * @param embStart + * the start offset of the embeddings array to perform the + * algorithm. + * @param paragraphLength + * the length of the text to perform the algorithm. It must be + * text.length >= textStart + paragraphLength, and + * embeddings.length >= embStart + paragraphLength. + * @param flags + * indicates the base direction of the bidirectional text. It is + * expected that this will be one of the direction constant + * values defined in this class. An unknown value is treated as + * DIRECTION_DEFAULT_LEFT_TO_RIGHT. + * + * @see #DIRECTION_LEFT_TO_RIGHT + * @see #DIRECTION_RIGHT_TO_LEFT + * @see #DIRECTION_DEFAULT_RIGHT_TO_LEFT + * @see #DIRECTION_DEFAULT_LEFT_TO_RIGHT + */ + public Bidi(char[] text, int textStart, byte[] embeddings, int embStart, + int paragraphLength, int flags) { + long pBidi = createUBiDi(text, textStart, embeddings, embStart, + paragraphLength, flags); + readBidiInfo(pBidi); + BidiWrapper.ubidi_close(pBidi); + } + + /** + * Create a Bidi object. + * + * @param paragraph + * the String containing the paragraph text to perform the + * algorithm. + * @param flags + * indicates the base direction of the bidirectional text. It is + * expected that this will be one of the direction constant + * values defined in this class. An unknown value is treated as + * DIRECTION_DEFAULT_LEFT_TO_RIGHT. + * + * @see #DIRECTION_LEFT_TO_RIGHT + * @see #DIRECTION_RIGHT_TO_LEFT + * @see #DIRECTION_DEFAULT_RIGHT_TO_LEFT + * @see #DIRECTION_DEFAULT_LEFT_TO_RIGHT + */ + public Bidi(String paragraph, int flags) { + this((paragraph == null ? null : paragraph.toCharArray()), 0, null, 0, + (paragraph == null ? 0 : paragraph.length()), flags); + } + + // create the native UBiDi struct, need to be closed with ubidi_close(). + private static long createUBiDi(char[] text, int textStart, + byte[] embeddings, int embStart, int paragraphLength, int flags) { + char[] realText = null; + + byte[] realEmbeddings = null; + + if (text == null || text.length < textStart + paragraphLength) { + throw new IllegalArgumentException(); + } + realText = new char[paragraphLength]; + System.arraycopy(text, textStart, realText, 0, paragraphLength); + + if (embeddings != null) { + if (embeddings.length < embStart + paragraphLength) { + throw new IllegalArgumentException(); + } + Bidi temp = new Bidi(text, textStart, null, 0, paragraphLength, + flags); + realEmbeddings = new byte[paragraphLength]; + System.arraycopy(temp.offsetLevel, 0, realEmbeddings, 0, + paragraphLength); + for (int i = 0; i < paragraphLength; i++) { + byte e = embeddings[i]; + if (e < 0) { + realEmbeddings[i] = (byte) (BidiWrapper.UBIDI_LEVEL_OVERRIDE - e); + } else if (e > 0) { + realEmbeddings[i] = e; + } else { + realEmbeddings[i] |= (byte) BidiWrapper.UBIDI_LEVEL_OVERRIDE; + } + } + } + + if (flags > 1 || flags < -2) { + flags = 0; + } + + long bidi = BidiWrapper.ubidi_open(); + BidiWrapper.ubidi_setPara(bidi, realText, paragraphLength, + (byte) flags, realEmbeddings); + return bidi; + } + + // private constructor, used by createLineBidi() + private Bidi(long pBidi) { + readBidiInfo(pBidi); + } + + // read info from the native UBiDi struct + private void readBidiInfo(long pBidi) { + + length = BidiWrapper.ubidi_getLength(pBidi); + + offsetLevel = (length == 0) ? null : BidiWrapper.ubidi_getLevels(pBidi); + + baseLevel = BidiWrapper.ubidi_getParaLevel(pBidi); + + int runCount = BidiWrapper.ubidi_countRuns(pBidi); + if (runCount == 0) { + runCount = 1; + runs = new BidiRun[runCount]; + runs[0] = new BidiRun(0, 0, baseLevel); + } else if (runCount < 0) { + runCount = 0; + runs = null; + } else { + runs = new BidiRun[runCount]; + for (int i = 0; i < runs.length; i++) { + runs[i] = BidiWrapper.ubidi_getRun(pBidi, i); + } + } + + direction = BidiWrapper.ubidi_getDirection(pBidi); + } + + private int baseLevel; + + private int length; + + private byte[] offsetLevel; + + private BidiRun[] runs; + + private int direction; + + /** + * Return whether the base level is from left to right. + * + * @return true if the base level is from left to right. + */ + public boolean baseIsLeftToRight() { + return baseLevel % 2 == 0 ? true : false; + } + + /** + * Create a new Bidi object containing the infomation of one line from this + * object. + * + * @param lineStart + * the start offset of the line. + * @param lineLimit + * the limit of the line. + * @return the new line Bidi object. In this new object, the indices will + * range from 0 to (limit - start - 1). + */ + public Bidi createLineBidi(int lineStart, int lineLimit) { + char[] text = new char[this.length]; + Arrays.fill(text, 'a'); + byte[] embeddings = new byte[this.length]; + for (int i = 0; i < embeddings.length; i++) { + embeddings[i] = (byte) -this.offsetLevel[i]; + } + + int dir = this.baseIsLeftToRight() ? Bidi.DIRECTION_LEFT_TO_RIGHT + : Bidi.DIRECTION_RIGHT_TO_LEFT; + + long parent = createUBiDi(text, 0, embeddings, 0, this.length, dir); + + long line = BidiWrapper.ubidi_setLine(parent, lineStart, lineLimit); + Bidi result = new Bidi(line); + BidiWrapper.ubidi_close(line); + BidiWrapper.ubidi_close(parent); + return result; + } + + /** + * Return the base level. + * + * @return the int value of the base level. + */ + public int getBaseLevel() { + return baseLevel; + } + + /** + * Return the length of the text in the Bidi object. + * + * @return the int value of the length. + */ + public int getLength() { + return length; + } + + /** + * Return the level of a specified character. + * + * @param offset + * the offset of the character. + * @return the int value of the evel. + */ + public int getLevelAt(int offset) { + try { + return offsetLevel[offset] & ~BidiWrapper.UBIDI_LEVEL_OVERRIDE; + } catch (RuntimeException e) { + return baseLevel; + } + } + + /** + * Return the number of runs in the bidirectional text. + * + * @return the int value of runs, at least 1. + */ + public int getRunCount() { + return runs.length; + } + + /** + * Return the level of a specified run. + * + * @param run + * the index of the run. + * @return the level of the run. + */ + public int getRunLevel(int run) { + return runs[run].getLevel(); + } + + /** + * Return the limit offset of a specified run. + * + * @param run + * the index of the run. + * @return the limit offset of the run. + */ + public int getRunLimit(int run) { + return runs[run].getLimit(); + } + + /** + * Return the start offset of a specified run. + * + * @param run + * the index of the run. + * @return the start offset of the run. + */ + public int getRunStart(int run) { + return runs[run].getStart(); + } + + /** + * Return whether the text is from left to right, that is, both the base + * direction and the text direction is from left to right. + * + * @return true if the text is from left to right. + */ + public boolean isLeftToRight() { + return direction == BidiWrapper.UBiDiDirection_UBIDI_LTR; + } + + /** + * Return whether the text direction is mixed. + * + * @return true if the text direction is mixed. + */ + public boolean isMixed() { + return direction == BidiWrapper.UBiDiDirection_UBIDI_MIXED; + } + + /** + * Return whether the text is from right to left, that is, both the base + * direction and the text direction is from right to left. + * + * @return true if the text is from right to left. + */ + public boolean isRightToLeft() { + return direction == BidiWrapper.UBiDiDirection_UBIDI_RTL; + } + + /** + * Reorder a range of objects according to their spefied levels. This is a + * convenience function that does not use a Bidi object. The range of + * objects at index from objectStart to objectStart + count will be + * reordered according to the range of levels at index from levelStart to + * levelStart + count. + * + * @param levels + * the level array, which is already determined. + * @param levelStart + * the start offset of the range of the levels. + * @param objects + * the object array to reoeder. + * @param objectStart + * the start offset of the range of objects. + * @param count + * the count of the range of objects to reorder. + */ + public static void reorderVisually(byte[] levels, int levelStart, + Object[] objects, int objectStart, int count) { + try { + byte[] realLevels = new byte[count]; + System.arraycopy(levels, levelStart, realLevels, 0, count); + + int[] indices = BidiWrapper.ubidi_reorderVisual(realLevels, count); + + LinkedList result = new LinkedList(); + for (int i = 0; i < count; i++) { + result.addLast(objects[objectStart + indices[i]]); + } + + System.arraycopy(result.toArray(), 0, objects, objectStart, count); + } catch (ArrayIndexOutOfBoundsException e) { + throw new IllegalArgumentException(); + } + } + + /** + * Return whether a range of characters of a text requires a Bidi object to + * display properly. + * + * @param text + * the char array of the text. + * @param start + * the start offset of the range of characters. + * @param limit + * the limit offset of the range of characters. + * @return true if the range of characters requires a Bidi object. + */ + public static boolean requiresBidi(char[] text, int start, int limit) { + if (limit < 0 || start >= limit) { + return false; + } else if (start < 0 || start > text.length || limit > text.length) { + throw new ArrayIndexOutOfBoundsException(); + } + + Bidi bidi = new Bidi(text, start, null, 0, limit - start, 0); + + if (bidi.isLeftToRight()) { + return false; + } + + return true; + } + + /** + * Return the internal message of the Bidi object, used in debugging. + * + * @return a string containing the internal messsage. + */ + public String toString() { + // simply return nothing + return ""; + } +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/BreakIterator.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/BreakIterator.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/BreakIterator.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/BreakIterator.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,365 @@ +/* Copyright 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.text; + + +import java.util.Locale; + +/** + * This class is used to locate the boundaries of text. Instance of this class + * can be got by some factory methods: + *
    + *
  • + * getCharacterIntance() returns a BreakIterator that iterate the + * logical characters without worrying about how the character is stored. For + * example, some character may be stored in more than one Unicode code point + * according to Unicode specification, this character can handle the logical + * characters with multi code points.
  • + *
  • + * getWordIntance() returns a BreakIterator that + * iterate the word-breaks. The beginning and end of each word(including numbers) + * is treated as boundary position. Whitespace and punctuation are kept separate + * from real words.
  • + *
  • + * getSentenceInstance() returns a BreakIterator that iterate the + * sentence-breaks.
  • + *
  • getLineInstance() retuens a BreakIterator that iterate the + * line-breaks which can be used to wrap lines. This iterator can handle whitespaces, + * hyphens and punctuations. + *
+ * + * BreakIterator uses CharacterIterator to perform the + * analysis, so that any storage which provides CharacterIterator + * interface. + * + * @see CharacterIterator + */ +public abstract class BreakIterator implements Cloneable { + + /* + * ----------------------------------------------------------------------- + * constantants + * ----------------------------------------------------------------------- + */ + /** + * This constant is returned by iterate methods like previous() or next() if + * they have returned all valid boundaries. + */ + public static final int DONE = -1; + + /* + * ----------------------------------------------------------------------- + * variables + * ----------------------------------------------------------------------- + */ + // the wrapped icu implementation + com.ibm.icu.text.BreakIterator wrapped; + + /* + * ----------------------------------------------------------------------- + * constructors + * ----------------------------------------------------------------------- + */ + /** + * Default constructor, just for invocation by subclass. + */ + protected BreakIterator() { + super(); + } + + /* + * wrapping constructor + */ + BreakIterator(com.ibm.icu.text.BreakIterator iterator) { + wrapped = iterator; + } + + /* + * ----------------------------------------------------------------------- + * methods + * ----------------------------------------------------------------------- + */ + /** + * Return all supported locales. + * + * @return all supported locales + */ + public static Locale[] getAvailableLocales() { + return com.ibm.icu.text.BreakIterator.getAvailableLocales(); + } + + /** + * Return a new instance of BreakIterator used to iterate characters using + * default locale. + * + * @return a new instance of BreakIterator used to iterate characters using + * default locale. + */ + public static BreakIterator getCharacterInstance() { + return new RuleBasedBreakIterator(com.ibm.icu.text.BreakIterator + .getCharacterInstance()); + } + + /** + * Return a new instance of BreakIterator used to iterate characters using + * given locale. + * + * @param where + * the given locale + * @return a new instance of BreakIterator used to iterate characters using + * given locale. + */ + public static BreakIterator getCharacterInstance(Locale where) { + return new RuleBasedBreakIterator(com.ibm.icu.text.BreakIterator + .getCharacterInstance(where)); + } + + /** + * Return a new instance of BreakIterator used to iterate line-breaks using + * default locale. + * + * @return a new instance of BreakIterator used to iterate line-breaks using + * default locale. + */ + public static BreakIterator getLineInstance() { + return new RuleBasedBreakIterator(com.ibm.icu.text.BreakIterator + .getLineInstance()); + } + + /** + * Return a new instance of BreakIterator used to iterate line-breaks using + * given locale. + * + * @param where + * the given locale + * @return a new instance of BreakIterator used to iterate line-breaks using + * given locale. + */ + public static BreakIterator getLineInstance(Locale where) { + return new RuleBasedBreakIterator(com.ibm.icu.text.BreakIterator + .getLineInstance(where)); + } + + /** + * Return a new instance of BreakIterator used to iterate sentense-breaks + * using default locale. + * + * @return a new instance of BreakIterator used to iterate sentense-breaks + * using default locale. + */ + public static BreakIterator getSentenceInstance() { + return new RuleBasedBreakIterator(com.ibm.icu.text.BreakIterator + .getSentenceInstance()); + } + + /** + * Return a new instance of BreakIterator used to iterate sentense-breaks + * using given locale. + * + * @param where + * the given locale + * @return a new instance of BreakIterator used to iterate sentense-breaks + * using given locale. + */ + public static BreakIterator getSentenceInstance(Locale where) { + return new RuleBasedBreakIterator(com.ibm.icu.text.BreakIterator + .getSentenceInstance(where)); + } + + /** + * Return a new instance of BreakIterator used to iterate word-breaks using + * default locale. + * + * @return a new instance of BreakIterator used to iterate word-breaks using + * default locale. + */ + public static BreakIterator getWordInstance() { + return new RuleBasedBreakIterator(com.ibm.icu.text.BreakIterator + .getWordInstance()); + } + + /** + * Return a new instance of BreakIterator used to iterate word-breaks using + * given locale. + * + * @param where + * the given locale + * @return a new instance of BreakIterator used to iterate word-breaks using + * given locale. + */ + public static BreakIterator getWordInstance(Locale where) { + return new RuleBasedBreakIterator(com.ibm.icu.text.BreakIterator + .getSentenceInstance(where)); + } + + /** + * Return true if the given offset is a boundary position. If this method + * returns true, the current iteration position is set to the given + * position; if the function returns false, the current iteration position + * is set as though following() had been called. + * + * @param offset + * the given offset to check + * @return true if the given offset is a boudary postion + */ + public boolean isBoundary(int offset) { + return wrapped.isBoundary(offset); + } + + /** + * Return the postion of last boundary precede the given offset, and set + * current postion to returned value, or DONE if the given + * offset specifies the starting position. + *

+ * IllegalArgumentException will be thrown if given offset is + * invalid. + *

+ * + * @param offset + * the given start position to be searched for + * @return the postion of last boundary precede the given offset + */ + public int preceding(int offset) { + return wrapped.preceding(offset); + } + + /** + * Set the new text string to be analyzed, the current position will be + * reset to beginning of this new string, and the old string will lost. + * + * @param newText + * the new text string to be analyzed + */ + public void setText(String newText) { + wrapped.setText(newText); + } + + /* + * ----------------------------------------------------------------------- + * abstract methods + * ----------------------------------------------------------------------- + */ + /** + * Return this iterator's current position. + * + * @return this iterator's current position + */ + public abstract int current(); + + /** + * Set this iterator's current position to the first boundary, and return + * this postion. + * + * @return the position of first boundary + */ + public abstract int first(); + + /** + * Set the position of the first boundary following the given offset, and + * return this position. If there is no boundary after the given offset, + * return DONE. + *

+ * IllegalArgumentException will be thrown if given offset is + * invalid. + *

+ * + * @param offset + * the given position to be searched for + * @return the position of the first boundary following the given offset + */ + public abstract int following(int offset); + + /** + * Return a CharacterIterator which represents the text being + * analyzed. Please note that the returned value is probablly the internal + * iterator used by this object, so that if the invoker want to modify the + * status of the returned iterator, a clone operation at first is + * recommended. + * + * @return a CharacterIterator which represents the text + * being analyzed. + */ + public abstract CharacterIterator getText(); + + /** + * Set this iterator's current position to the last boundary, and return + * this postion. + * + * @return the position of last boundary + */ + public abstract int last(); + + /** + * Set this iterator's current position to the next boundary after current + * position, and return this postion. Return DONE if no + * boundary found after current position. + * + * @return the position of last boundary + */ + public abstract int next(); + + /** + * Set this iterator's current position to the next boundary after the given + * position, and return this postion. Return DONE if no + * boundary found after the given position. + * + * @param n + * the given position. + * @return the position of last boundary + */ + public abstract int next(int n); + + /** + * Set this iterator's current position to the previous boundary before + * current position, and return this postion. Return DONE if + * no boundary found before current position. + * + * @return the position of last boundary + */ + public abstract int previous(); + + /** + * Set new text to be analyzed by given CharacterIterator. + * The position will be reset to the beginning of the new text, and other + * status of this iterator will be kept. + * + * @param newText + * the given CharacterIterator refer to the text + * to be analyzed + */ + public abstract void setText(CharacterIterator newText); + + /* + * ----------------------------------------------------------------------- + * methods override Object + * ----------------------------------------------------------------------- + */ + /** + * Create copy of this iterator, all status including current position is + * kept. + * + * @return copy of this iterator + */ + public Object clone() { + try { + BreakIterator cloned = (BreakIterator) super.clone(); + cloned.wrapped = (com.ibm.icu.text.BreakIterator) wrapped.clone(); + return cloned; + } catch (CloneNotSupportedException e) { + throw new InternalError(e.getMessage()); + } + } +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CharacterIterator.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CharacterIterator.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CharacterIterator.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CharacterIterator.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,112 @@ +/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.text; + + +/** + * CharacterIterator is used to sequence over a group of characters. The + * iteration starts at the begin index in the group of character and continues + * to one index before the end index. + */ +public interface CharacterIterator extends Cloneable { + + /** + * A constant which indicates there is no character. + */ + public static char DONE = '\uffff'; + + /** + * Answers a new CharacterIterator with the same properties. + * + * @return a shallow copy of this CharacterIterator + * + * @see java.lang.Cloneable + */ + public Object clone(); + + /** + * Answers the character at the current index. + * + * @return the current character, or DONE if the current index is past the + * end + */ + public char current(); + + /** + * Sets the current position to the begin index and answers the character at + * the begin index. + * + * @return the character at the begin index + */ + public char first(); + + /** + * Answers the begin index. + * + * @return the index of the first character to iterate + */ + public int getBeginIndex(); + + /** + * Answers the end index. + * + * @return the index one past the last character to iterate + */ + public int getEndIndex(); + + /** + * Answers the current index. + * + * @return the current index + */ + public int getIndex(); + + /** + * Sets the current position to the end index - 1 and answers the character + * at the current position. + * + * @return the character before the end index + */ + public char last(); + + /** + * Increments the current index and returns the character at the new index. + * + * @return the character at the next index, or DONE if the next index is + * past the end + */ + public char next(); + + /** + * Decrements the current index and returns the character at the new index. + * + * @return the character at the previous index, or DONE if the previous + * index is past the beginning + */ + public char previous(); + + /** + * Sets the current index. + * + * @return the character at the new index, or DONE if the index is past the + * end + * + * @exception IllegalArgumentException + * when the new index is less than the begin index or greater + * than the end index + */ + public char setIndex(int location); +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/ChoiceFormat.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/ChoiceFormat.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/ChoiceFormat.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/ChoiceFormat.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,389 @@ +/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.text; + + +import java.util.Arrays; +import java.util.Vector; + +/** + * ChoiceFormat is used to assocate strings with ranges of double values. The + * strings and ranges are either specified using arrays or with a pattern which + * is parsed to determine the Strings and ranges. + */ + +public class ChoiceFormat extends NumberFormat { + + static final long serialVersionUID = 1795184449645032964L; + + private double[] choiceLimits; + + private String[] choiceFormats; + + /** + * Constructs a new ChoiceFormat with the specified ranges and associated + * strings. + * + * @param limits + * an array of double, the ranges are greater or equal to the + * value in lower index up to less than the value in the next + * higher index. The bounds of the lowest and highest indexes are + * negative and positive infinity. + * @param formats + * the strings associated with the ranges. The lower bound of the + * associated range is at the same index as the string. + */ + public ChoiceFormat(double[] limits, String[] formats) { + setChoices(limits, formats); + } + + /** + * Constructs a new ChoiceFormat with the strings and ranges parsed from the + * specified pattern. + * + * @param template + * the pattern of strings and ranges + * + * @exception IllegalArgumentException + * then an error occurs parsing the pattern + */ + public ChoiceFormat(String template) { + applyPattern(template); + } + + /** + * Parses the pattern to determine new strings and ranges for this + * ChoiceFormat. + * + * @param template + * the pattern of strings and ranges + * + * @exception IllegalArgumentException + * then an error occurs parsing the pattern + */ + public void applyPattern(String template) { + boolean first = true; + double[] limits = new double[5]; + Vector formats = new Vector(); + int length = template.length(), limitCount = 0, index = 0; + StringBuffer buffer = new StringBuffer(); + NumberFormat format = NumberFormat.getInstance(); + ParsePosition position = new ParsePosition(0); + while (true) { + index = skipWhitespace(template, index); + if (index >= length) { + if (limitCount == limits.length) + choiceLimits = limits; + else { + choiceLimits = new double[limitCount]; + System.arraycopy(limits, 0, choiceLimits, 0, limitCount); + } + choiceFormats = new String[formats.size()]; + for (int i = 0; i < formats.size(); i++) + choiceFormats[i] = (String) formats.elementAt(i); + return; + } + + position.setIndex(index); + Number value = format.parse(template, position); + index = skipWhitespace(template, position.getIndex()); + if (position.getErrorIndex() != -1 || index >= length) + throw new IllegalArgumentException(); + char ch = template.charAt(index++); + if (limitCount == limits.length) { + double[] newLimits = new double[limitCount * 2]; + System.arraycopy(limits, 0, newLimits, 0, limitCount); + limits = newLimits; + } + double next; + switch (ch) { + case '#': + case '\u2264': + next = value.doubleValue(); + break; + case '<': + if (first) + throw new IllegalArgumentException(); + next = nextDouble(value.doubleValue()); + break; + default: + throw new IllegalArgumentException(); + } + first = false; + if (limitCount > 0 && next <= limits[limitCount - 1]) + throw new IllegalArgumentException(); + buffer.setLength(0); + position.setIndex(index); + upTo(template, position, buffer, '|'); + index = position.getIndex(); + limits[limitCount++] = next; + formats.addElement(buffer.toString()); + } + } + + /** + * Answers a new instance of ChoiceFormat with the same ranges and strings + * as this ChoiceFormat. + * + * @return a shallow copy of this ChoiceFormat + * + * @see java.lang.Cloneable + */ + public Object clone() { + ChoiceFormat clone = (ChoiceFormat) super.clone(); + clone.choiceLimits = (double[]) choiceLimits.clone(); + clone.choiceFormats = (String[]) choiceFormats.clone(); + return clone; + } + + /** + * Compares the specified object to this ChoiceFormat and answer if they are + * equal. The object must be an instance of ChoiceFormat and have the same + * limits and formats. + * + * @param object + * the object to compare with this object + * @return true if the specified object is equal to this ChoiceFormat, false + * otherwise + * + * @see #hashCode + */ + public boolean equals(Object object) { + if (this == object) + return true; + if (!(object instanceof ChoiceFormat)) + return false; + ChoiceFormat choice = (ChoiceFormat) object; + return Arrays.equals(choiceLimits, choice.choiceLimits) + && Arrays.equals(choiceFormats, choice.choiceFormats); + } + + /** + * Appends to the specified StringBuffer the string associated with the + * range in which the specified double value fits. + * + * @param value + * the double to format + * @param buffer + * the StringBuffer + * @param field + * a FieldPosition which is ignored + * @return the StringBuffer parameter buffer + */ + public StringBuffer format(double value, StringBuffer buffer, + FieldPosition field) { + if (Double.isNaN(value) + || (choiceLimits.length > 1 && value < choiceLimits[1])) + return buffer.append(choiceFormats[0]); + for (int i = 2; i < choiceLimits.length; i++) + if (value >= choiceLimits[i - 1] && value < choiceLimits[i]) + return buffer.append(choiceFormats[i - 1]); + return buffer.append(choiceFormats[choiceFormats.length - 1]); + } + + /** + * Appends to the specified StringBuffer the string associated with the + * range in which the specified long value fits. + * + * @param value + * the long to format + * @param buffer + * the StringBuffer + * @param field + * a FieldPosition which is ignored + * @return the StringBuffer parameter buffer + */ + public StringBuffer format(long value, StringBuffer buffer, + FieldPosition field) { + return format((double) value, buffer, field); + } + + /** + * Answers the Strings associated with the ranges of this ChoiceFormat. + * + * @return an array of String + */ + public Object[] getFormats() { + return choiceFormats; + } + + /** + * Answers the ranges of this ChoiceFormat. + * + * @return an array of double, the ranges are greater or equal to the value + * in lower index up to less than the value in the next higher + * index. The bounds of the lowest and highest indexes are negative + * and positive infinity. + */ + public double[] getLimits() { + return choiceLimits; + } + + /** + * Answers an integer hash code for the receiver. Objects which are equal + * answer the same value for this method. + * + * @return the receiver's hash + * + * @see #equals + */ + public int hashCode() { + int hashCode = 0; + for (int i = 0; i < choiceLimits.length; i++) { + long v = Double.doubleToLongBits(choiceLimits[i]); + hashCode += (int) (v ^ (v >>> 32)) + choiceFormats[i].hashCode(); + } + return hashCode; + } + + /** + * Answers the double value which is closest to the specified double but + * larger. + * + * @param value + * a double value + * @return the next larger double value + */ + public static final double nextDouble(double value) { + if (value == Double.POSITIVE_INFINITY) + return value; + long bits; + // Handle -0.0 + if (value == 0) + bits = 0; + else + bits = Double.doubleToLongBits(value); + return Double.longBitsToDouble(value < 0 ? bits - 1 : bits + 1); + } + + /** + * Answers the double value which is closest to the specified double but + * either larger or smaller as specified. + * + * @param value + * a double value + * @param increment + * true to get a larger value, false to get a smaller value + * @return the next larger or smaller double value + */ + public static double nextDouble(double value, boolean increment) { + return increment ? nextDouble(value) : previousDouble(value); + } + + /** + * Parse a Double from the specified String starting at the index specified + * by the ParsePosition. The String is compared to the strings of this + * ChoiceFormat and if a match occurs, the answer is the lower bound of the + * corresponding range. If the string is successfully parsed, the index of + * the ParsePosition is updated to the index following the parsed text. + * + * @param string + * the String to parse + * @param position + * the ParsePosition, updated on return with the index following + * the parsed text, or on error the index is unchanged and the + * error index is set to the index where the error occurred + * @return a Double resulting from the parse, or Double.NaN if there is an + * error + */ + public Number parse(String string, ParsePosition position) { + int offset = position.getIndex(); + for (int i = 0; i < choiceFormats.length; i++) { + if (string.startsWith(choiceFormats[i], offset)) { + position.setIndex(offset + choiceFormats[i].length()); + return new Double(choiceLimits[i]); + } + } + position.setErrorIndex(offset); + return new Double(Double.NaN); + } + + /** + * Answers the double value which is closest to the specified double but + * smaller. + * + * @param value + * a double value + * @return the next smaller double value + */ + public static final double previousDouble(double value) { + if (value == Double.NEGATIVE_INFINITY) + return value; + long bits; + // Handle 0.0 + if (value == 0) + bits = 0x8000000000000000L; + else + bits = Double.doubleToLongBits(value); + return Double.longBitsToDouble(value <= 0 ? bits + 1 : bits - 1); + } + + /** + * Sets the ranges and associated strings of this ChoiceFormat. + * + * @param limits + * an array of double, the ranges are greater or equal to the + * value in lower index up to less than the value in the next + * higher index. The bounds of the lowest and highest indexes are + * negative and positive infinity. + * @param formats + * the strings associated with the ranges. The lower bound of the + * range is at the same index as the string. + */ + public void setChoices(double[] limits, String[] formats) { + if (limits.length != formats.length) + throw new IllegalArgumentException(); + choiceLimits = limits; + choiceFormats = formats; + } + + private int skipWhitespace(String string, int index) { + int length = string.length(); + while (index < length && Character.isWhitespace(string.charAt(index))) + index++; + return index; + } + + /** + * Answers the pattern of this ChoiceFormat which specified the ranges and + * their associated strings. + * + * @return the pattern + */ + public String toPattern() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < choiceLimits.length; i++) { + String previous = String.valueOf(previousDouble(choiceLimits[i])); + String limit = String.valueOf(choiceLimits[i]); + if (previous.length() < limit.length()) { + buffer.append(previous); + buffer.append('<'); + } else { + buffer.append(limit); + buffer.append('#'); + } + boolean quote = (choiceFormats[i].indexOf('|') != -1); + if (quote) + buffer.append('\''); + buffer.append(choiceFormats[i]); + if (quote) + buffer.append('\''); + buffer.append('|'); + } + buffer.setLength(buffer.length() - 1); + return buffer.toString(); + } +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CollationElementIterator.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CollationElementIterator.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CollationElementIterator.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CollationElementIterator.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,246 @@ +/* Copyright 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.text; + + +/** + *

+ * CollationElementIterator is created by a + * RuleBasedCollator to iterate through a string. The return result + * of each iteration is a 32-bit collation element that defines the ordering + * priority of the next character or sequence of characters in the source + * string. + *

+ *

+ * For illustration, consider the following in Spanish: + *

+ * + *

+ * + * "ca" -> the first collation element is collation_element('c') and second + * collation element is collation_element('a'). + * + *

+ * + *

+ * + * Since "ch" in Spanish sorts as one entity, the below example returns one + * collation element for the two characters 'c' and 'h' + * + *

+ * + *

+ * + * "cha" -> the first collation element is collation_element('ch') and second + * collation element is collation_element('a'). + * + *

+ *

+ * And in German, + *

+ * + *

+ * + * Since the character '�' is a composed character of 'a' and 'e', the iterator + * returns two collation elements for the single character '�' + * + *

+ *

+ * + * "�b" -> the first + * collation element is collation_element('a'), the second collation element is + * collation_element('e'), and the third collation element is + * collation_element('b'). + * + *

+ * + */ +public final class CollationElementIterator { + + /** + * This constant is returned by the iterator in the methods + * next() and previous() when the end or the + * beginning of the source string has been reached, and there are no more + * valid collation elements to return. + */ + public static final int NULLORDER = -1; + + private com.ibm.icu.text.CollationElementIterator icuIterator; + + CollationElementIterator(com.ibm.icu.text.CollationElementIterator iterator) { + this.icuIterator = iterator; + } + + /** + * Obtains the maximum length of any expansion sequence that ends with the + * specified collation element. If there is no expansion with this collation + * element as the last element, returns 1. + * + * @param order + * a collation element that has been previously obtained from + * a call to either the {@link #next()} or {@link #previous()} + * method. + * @return the maximum length of any expansion sequence ending with the + * specified collation element. + */ + public int getMaxExpansion(int order) { + return this.icuIterator.getMaxExpansion(order); + } + + /** + * Obtains the character offset in the source string corresponding to the + * next collation element. This value could be any of: + *
  • The index of the first character in the source string that matches + * the value of the next collation element. (This means that if + * setOffset(offset) sets the index in the middle of a contraction, + * getOffset() returns the index of the first character in the contraction, + * which may not be equal to the original offset that was set. Hence calling + * getOffset() immediately after setOffset(offset) does not guarantee that + * the original offset set will be returned.)
  • + *
  • If normalization is on, the index of the immediate subsequent + * character, or composite character with the first character, having a + * combining class of 0.
  • + *
  • The length of the source string, if iteration has reached the end. + *
  • + * + * + * @return The position of the collation element in the source string that + * will be returned in the next invocation of the {@link #next()} method. + */ + public int getOffset() { + return this.icuIterator.getOffset(); + } + + /** + * Obtains the next collation element in the source string. + * + * @return the next collation element or NULLORDER if the end + * of the iteration has been reached. + */ + public int next() { + return this.icuIterator.next(); + } + + /** + * Obtains the previous collation element in the source string. + * + * @return the previous collation element, or NULLORDER when + * the start of the iteration has been reached. + */ + public int previous() { + return this.icuIterator.previous(); + } + + /** + * Obtains the primary order of the specified collation element, i.e. the + * first 16 bits. This value is unsigned. + * + * @param order + * @return the element's 16 bits primary order. + */ + public static final int primaryOrder(int order) { + return com.ibm.icu.text.CollationElementIterator.primaryOrder(order); + } + + /** + * Repositions the cursor to point at the first element of the current + * string. The next call to next() or previous() + * will return the first and last collation element in the string, + * respectively. + *

    + * If the RuleBasedCollator used by this iterator has had its + * attributes changed, calling reset() will reinitialize the + * iterator to use the new attributes. + *

    + */ + public void reset() { + this.icuIterator.reset(); + } + + /** + * Obtains the secondary order of the specified collation element, i.e. the + * 16th to 23th bits, inclusive. This value is unsigned. + * + * @param order + * @return the 8 bit secondary order of the element + */ + public static final short secondaryOrder(int order) { + return (short) com.ibm.icu.text.CollationElementIterator + .secondaryOrder(order); + } + + /** + * Points the iterator at the collation element associated with the + * character in the source string which is found at the supplied offset. + * After this call completes, an invocation of the {@link #next()} method + * will return this collation element. + *

    + * If newOffset corresponds to a character which is part of a + * sequence that maps to a single collation element the iterator is adjusted + * to the start of that sequence. As a result of this, any subsequent call + * made to getOffset() may not return the same value set by + * this method. + *

    + *

    + * If the decomposition mode is on, and offset is in the middle of a + * decomposible range of source text, the iterator may not return a correct + * result for the next forwards or backwards iteration. The user must ensure + * that the offset is not in the middle of a decomposible range. + *

    + * + * @param newOffset + * the character offset into the original source string to set. + * Note that this is not an offset into the corresponding + * sequence of collation elements. + */ + public void setOffset(int newOffset) { + this.icuIterator.setOffset(newOffset); + } + + /** + * Sets a new source string interator for iteration, and reset the offset to + * the beginning of the text. + * + * @param source + * the new source string iterator for iteration. + */ + public void setText(CharacterIterator source) { + this.icuIterator.setText(source); + } + + /** + * Sets a new source string for iteration, and reset the offset to the + * beginning of the text. + * + * @param source + * the new source string for iteration + */ + public void setText(String source) { + this.icuIterator.setText(source); + } + + /** + * Obtains the tertiary order of the specified collation element, i.e. the + * last 8 bits. This value is unsigned. + * + * @param order + * @return the 8 bits tertiary order of the element + */ + public static final short tertiaryOrder(int order) { + return (short) com.ibm.icu.text.CollationElementIterator + .tertiaryOrder(order); + } +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CollationKey.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CollationKey.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CollationKey.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/CollationKey.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,116 @@ +/* Copyright 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.text; + + +/** + * CollationKey represents the collation order of a particular String for a + * specific Collator. CollationKeys can be compared to determine the relative + * ordering of their source Strings. This is useful when the Strings must be + * compared multiple times, as in sorting. + */ +public final class CollationKey implements Comparable { + + private String source; + + private com.ibm.icu.text.CollationKey icuKey; + + CollationKey(String source, com.ibm.icu.text.CollationKey key) { + this.source = source; + this.icuKey = key; + } + + /** + * Compare the receiver to the specified CollationKey to determine the + * relative ordering. + * + * @param value + * a CollationKey + * @return an int < 0 if this CollationKey is less than the specified + * CollationKey, 0 if they are equal, and > 0 if this CollationKey + * is greater + */ + public int compareTo(CollationKey value) { + return icuKey.compareTo(value.icuKey); + } + + /** + * Compare this CollationKey to the specified Object to determine the + * relative ordering. + * + * @param object + * an Object + * @return an int < 0 if this CollationKey is less than the specified + * CollationKey, 0 if they are equal, and > 0 if this CollationKey + * is greater + * + * @exception ClassCastException + * when object is not a CollationKey + */ + public int compareTo(Object object) { + return icuKey.compareTo(((CollationKey) object).icuKey); + } + + /** + * Compares the specified object to this CollationKey and answer if they are + * equal. The object must be an instance of CollationKey and have the same + * source string and collation key. The instances of CollationKey must have + * been created by the same Collator. + * + * @param object + * the object to compare with this object + * @return true if the specified object is equal to this CollationKey, false + * otherwise + * + * @see #hashCode + */ + public boolean equals(Object object) { + if (!(object instanceof CollationKey)) + return false; + CollationKey collationKey = (CollationKey) object; + return icuKey.equals(collationKey.icuKey); + } + + /** + * Answer the String from which this CollationKey was created. + * + * @return a String + */ + public String getSourceString() { + return this.source; + } + + /** + * Answers an integer hash code for the receiver. Objects which are equal + * answer the same value for this method. + * + * @return the receiver's hash + * + * @see #equals + */ + public int hashCode() { + return icuKey.hashCode(); + } + + /** + * Answer the collation key as a byte array. + * + * @return an array of bytes + */ + public byte[] toByteArray() { + return icuKey.toByteArray(); + } +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/Collator.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/Collator.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/Collator.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/text/src/java/text/Collator.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,358 @@ +/* Copyright 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.text; + + +import java.security.AccessController; +import java.util.Comparator; +import java.util.Locale; +import java.util.Vector; + +import com.ibm.oti.util.PriviAction; + +/** + * Collator is an abstract class which is the root of classes which provide + * Locale specific String comparison to determine their ordering with respect to + * each other. + */ +public abstract class Collator implements Comparator, Cloneable { + + static final int EQUAL = 0; + + static final int GREATER = 1; + + static final int LESS = -1; + + /** + * Constant used to specify the decomposition rule. + */ + public static final int NO_DECOMPOSITION = 0; + + /** + * Constant used to specify the decomposition rule. + */ + public static final int CANONICAL_DECOMPOSITION = 1; + + /** + * Constant used to specify the decomposition rule. + */ + public static final int FULL_DECOMPOSITION = 2; + + /** + * Constant used to specify the collation strength. + */ + public static final int PRIMARY = 0; + + /** + * Constant used to specify the collation strength. + */ + public static final int SECONDARY = 1; + + /** + * Constant used to specify the collation strength. + */ + public static final int TERTIARY = 2; + + /** + * Constant used to specify the collation strength. + */ + public static final int IDENTICAL = 3; + + private static int CACHE_SIZE; + + private static Vector cache = new Vector(CACHE_SIZE); + + // Wrapper class of ICU4J Collator + com.ibm.icu.text.Collator icuColl; + + static { + // CACHE_SIZE includes key and value, so needs to be double + String cacheSize = (String) AccessController + .doPrivileged(new PriviAction("collator.cache")); //$NON-NLS-1$ + if (cacheSize != null) { + try { + CACHE_SIZE = Integer.parseInt(cacheSize); + } catch (NumberFormatException e) { + CACHE_SIZE = 6; + } + } else + CACHE_SIZE = 6; + } + + Collator(com.ibm.icu.text.Collator wrapper) { + this.icuColl = wrapper; + } + + /** + * Constructs a new instance of this Collator. + */ + protected Collator() { + super(); + } + + /** + * Answers a new Collator with the same decomposition rule and strength + * value as this Collator. + * + * @return a shallow copy of this Collator + * @see java.lang.Cloneable + */ + public Object clone() { + try { + Collator clone = (Collator) super.clone(); + clone.icuColl = (com.ibm.icu.text.Collator) this.icuColl.clone(); + return clone; + } catch (CloneNotSupportedException e) { + return null; + } + } + + /** + * Compares the two objects to determine their relative ordering. The + * objects must be Strings. + * + * @param object1 + * the first String to compare + * @param object2 + * the second String to compare + * @return an int < 0 if object1 is less than object2, 0 if they are equal, + * and > 0 if object1 is greater than object2 + * + * @exception ClassCastException + * when the objects are not Strings + */ + public int compare(Object object1, Object object2) { + return compare((String) object1, (String) object2); + } + + /** + * Compares the two Strings to determine their relative ordering. + * + * @param string1 + * the first String to compare + * @param string2 + * the second String to compare + * @return an int < 0 if string1 is less than string2, 0 if they are equal, + * and > 0 if string1 is greater than string2 + */ + public abstract int compare(String string1, String string2); + + /** + * Compares the specified object to this Collator and answer if they are + * equal. The object must be an instance of Collator and have the same + * strength and decomposition values. + * + * @param object + * the object to compare with this object + * @return true if the specified object is equal to this Collator, false + * otherwise + * + * @see #hashCode + */ + public boolean equals(Object object) { + if (!(object instanceof Collator)) + return false; + Collator collator = (Collator) object; + return this.icuColl == null ? collator.icuColl == null : this.icuColl + .equals(collator.icuColl); + } + + /** + * Compares the two Strings using the collation rules to determine if they + * are equal. + * + * @param string1 + * the first String to compare + * @param string2 + * the second String to compare + * @return true if the strings are equal using the collation rules, false + * otherwise + */ + public boolean equals(String string1, String string2) { + return compare(string1, string2) == 0; + } + + /** + * Gets the list of installed Locales which support Collator. + * + * @return an array of Locale + */ + public static Locale[] getAvailableLocales() { + return com.ibm.icu.text.Collator.getAvailableLocales(); + } + + /** + * Answers a CollationKey for the specified String for this Collator with + * the current decomposition rule and stength value. + * + * @param string + * the collation key. + * @return a CollationKey + */ + public abstract CollationKey getCollationKey(String string); + + /** + * Answers the decomposition rule for this Collator. + * + * @return the decomposition rule, either NO_DECOMPOSITION, + * CANONICAL_DECOMPOSITION or FULL_DECOMPOSITION + */ + public int getDecomposition() { + return decompositionMode_ICU_Java(this.icuColl.getDecomposition()); + } + + /** + * Answers a Collator instance which is appropriate for the default Locale. + * + * @return a Collator + */ + public static Collator getInstance() { + return getInstance(Locale.getDefault()); + } + + /** + * Answers a Collator instance which is appropriate for the specified + * Locale. + * + * @param locale + * the Locale + * @return a Collator + */ + public static Collator getInstance(Locale locale) { + String key = locale.toString(); + for (int i = cache.size() - 1; i >= 0; i -= 2) { + if (cache.elementAt(i).equals(key)) + return (Collator) ((Collator) cache.elementAt(i - 1)).clone(); + } + + return new RuleBasedCollator(com.ibm.icu.text.Collator + .getInstance(locale)); + } + + /** + * Answers the strength value for this Collator. + * + * @return the strength value, either PRIMARY, SECONDARY, TERTIARY, or + * IDENTICAL + */ + public int getStrength() { + return strength_ICU_Java(this.icuColl.getStrength()); + } + + /** + * Answers an integer hash code for the receiver. Objects which are equal + * answer the same value for this method. + * + * @return the receiver's hash + * + * @see #equals(Object) + * @see #equals(String, String) + */ + public abstract int hashCode(); + + /** + * Sets the decomposition rule for this Collator. + * + * @param value + * the decomposition rule, either NO_DECOMPOSITION, + * CANONICAL_DECOMPOSITION or FULL_DECOMPOSITION + * + * @exception IllegalArgumentException + * when the decomposition rule is not valid + */ + public void setDecomposition(int value) { + this.icuColl.setDecomposition(decompositionMode_Java_ICU(value)); + } + + /** + * Sets the strength value for this Collator. + * + * @param value + * the strength value, either PRIMARY, SECONDARY, TERTIARY, or + * IDENTICAL + * + * @exception IllegalArgumentException + * when the strength value is not valid + */ + public void setStrength(int value) { + this.icuColl.setStrength(strength_Java_ICU(value)); + } + + private int decompositionMode_Java_ICU(int mode) { + int icuDecomp = mode; + switch (mode) { + case Collator.CANONICAL_DECOMPOSITION: + icuDecomp = com.ibm.icu.text.Collator.CANONICAL_DECOMPOSITION; + break; + case Collator.NO_DECOMPOSITION: + icuDecomp = com.ibm.icu.text.Collator.NO_DECOMPOSITION; + break; + } + return icuDecomp; + } + + private int decompositionMode_ICU_Java(int mode) { + int javaMode = mode; + switch (mode) { + case com.ibm.icu.text.Collator.NO_DECOMPOSITION: + javaMode = Collator.NO_DECOMPOSITION; + break; + case com.ibm.icu.text.Collator.CANONICAL_DECOMPOSITION: + javaMode = Collator.CANONICAL_DECOMPOSITION; + break; + } + return javaMode; + } + + private int strength_Java_ICU(int value) { + int icuValue = value; + switch (value) { + case Collator.PRIMARY: + icuValue = com.ibm.icu.text.Collator.PRIMARY; + break; + case Collator.SECONDARY: + icuValue = com.ibm.icu.text.Collator.SECONDARY; + break; + case Collator.TERTIARY: + icuValue = com.ibm.icu.text.Collator.TERTIARY; + break; + case Collator.IDENTICAL: + icuValue = com.ibm.icu.text.Collator.IDENTICAL; + break; + } + return icuValue; + + } + + private int strength_ICU_Java(int value) { + int javaValue = value; + switch (value) { + case com.ibm.icu.text.Collator.PRIMARY: + javaValue = Collator.PRIMARY; + break; + case com.ibm.icu.text.Collator.SECONDARY: + javaValue = Collator.SECONDARY; + break; + case com.ibm.icu.text.Collator.TERTIARY: + javaValue = Collator.TERTIARY; + break; + case com.ibm.icu.text.Collator.IDENTICAL: + javaValue = Collator.IDENTICAL; + break; + } + return javaValue; + } +}