TreeCollator.java
上传用户:huihesys
上传日期:2007-01-04
资源大小:3877k
文件大小:10k
源码类别:

WEB邮件程序

开发平台:

C/C++

  1. /*
  2.  * TreeCollator.java
  3.  * Copyright (C) 1999 dog <dog@dog.net.uk>
  4.  * 
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  * 
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  * 
  19.  * You may retrieve the latest version of this library from
  20.  * http://www.dog.net.uk/knife/
  21.  */
  22. package dog.util;
  23. import java.text.CollationKey;
  24. import java.text.Collator;
  25. import java.util.Date;
  26. import java.util.Locale;
  27. /**
  28.  * A class for comparing objects in a tree.
  29.  *
  30.  * @author dog@dog.net.uk
  31.  * @version 2.0
  32.  */
  33. public class TreeCollator extends Collator {
  34. protected Collator collator;
  35. protected boolean descending = false;
  36. /**
  37.  * Constructs a TreeCollator for the default locale.
  38.  */
  39. public TreeCollator() {
  40. collator = Collator.getInstance();
  41. }
  42. /**
  43.  * Constructs a TreeCollator for the specified locale.
  44.  */
  45. public TreeCollator(Locale locale) {
  46. collator = Collator.getInstance(locale);
  47. }
  48. /**
  49.  * Indicates whether this collator returns the opposite of any comparison.
  50.  * @see #setDescending
  51.  */
  52. public boolean isDescending() { return descending; }
  53. /**
  54.  * Sets whether this collator returns the opposite of any comparison.
  55.  * @param descending true if this collator returns the opposite of any comparison, false otherwise
  56.  * @see #setDescending
  57.  */
  58. public void setDescending(boolean descending) { this.descending = descending; }
  59. /**
  60.  * Utility method to return the opposite of a comparison if descending is true.
  61.  */
  62. protected int applyDescending(int comparison) {
  63. return (!descending ? comparison : -comparison);
  64. }
  65. /**
  66.  * Compares the source string to the target string according to the collation rules for this Collator.
  67.  * Returns an integer less than, equal to or greater than zero depending on whether the source String 
  68.  * is less than, equal to or greater than the target string. 
  69.  * @param source the source string. 
  70.  * @param target the target string. 
  71.  * @see java.text.CollationKey
  72.  */
  73. public int compare(String source, String target) {
  74. return applyDescending(collator.compare(source, target));
  75. }
  76. /**
  77.  * Compares the source object to the target object according to the collation rules for this Collator.
  78.  * Returns an integer less than, equal to or greater than zero depending on whether the source object
  79.  * is less than, equal to or greater than the target object.
  80.  * Objects that can validly be compared by such means include:<ul>
  81.  * <li>Boolean - false is less than true, can only be compared with another Boolean
  82.  * <li>Byte
  83.  * <li>Date - before is less than after, can only be compared with another Date
  84.  * <li>Double
  85.  * <li>Float
  86.  * <li>Long
  87.  * <li>Integer
  88.  * <li>Short
  89.  * <li>String
  90.  * @param source the source object.
  91.  * @param target the target object.
  92.  */
  93. public int compare(Object source, Object target) {
  94. if (source instanceof String) {
  95. if (target instanceof String)
  96. return applyDescending(collator.compare((String)source, (String)target));
  97. else if (target instanceof Number)
  98. return applyDescending(collator.compare((String)source, target.toString()));
  99. } else if (source instanceof Integer) {
  100. if (target instanceof Number)
  101. return applyDescending(((Number)target).intValue()-((Integer)source).intValue());
  102. else if (target instanceof String)
  103. return applyDescending(collator.compare(source.toString(), (String)target));
  104. } else if (source instanceof Double) {
  105. if (target instanceof Number)
  106. return applyDescending((int)(((Number)target).doubleValue()-((Double)source).doubleValue()));
  107. else if (target instanceof String)
  108. return applyDescending(collator.compare(source.toString(), (String)target));
  109. } else if (source instanceof Long) {
  110. if (target instanceof Number)
  111. return applyDescending((int)(((Number)target).longValue()-((Long)source).longValue()));
  112. else if (target instanceof String)
  113. return applyDescending(collator.compare(source.toString(), (String)target));
  114. } else if (source instanceof Float) {
  115. if (target instanceof Number)
  116. return applyDescending((int)(((Number)target).floatValue()-((Float)source).floatValue()));
  117. else if (target instanceof String)
  118. return applyDescending(collator.compare(source.toString(), (String)target));
  119. } else if (source instanceof Byte) {
  120. if (target instanceof Number)
  121. return applyDescending((int)(((Number)target).byteValue()-((Byte)source).byteValue()));
  122. else if (target instanceof String)
  123. return applyDescending(collator.compare(source.toString(), (String)target));
  124. } else if (source instanceof Short) {
  125. if (target instanceof Number)
  126. return applyDescending((int)(((Number)target).shortValue()-((Short)source).shortValue()));
  127. else if (target instanceof String)
  128. return applyDescending(collator.compare(source.toString(), (String)target));
  129. } else if (source instanceof Boolean) {
  130. if (target instanceof Boolean) {
  131. boolean s = ((Boolean)source).booleanValue(), t = ((Boolean)target).booleanValue();
  132. if (!s && t) return applyDescending(-1); else if (s && !t) return applyDescending(1);
  133. }
  134. } else if (source instanceof Date) {
  135. if (target instanceof Date) {
  136. Date s = (Date)source, t = (Date)target;
  137. if (s.before(t)) return applyDescending(-1); else if (s.after(t)) return applyDescending(1);
  138. }
  139. }
  140. return 0;
  141. }
  142. /**
  143.  * Transforms the String into a series of bits that can be compared bitwise to other CollationKeys. 
  144.  * CollationKeys provide better performance than Collator.compare when Strings are involved in multiple comparisons.
  145.  * @param source the string to be transformed into a collation key. 
  146.  * @return the CollationKey for the given String based on this Collator's collation rules. If the source String is null, a null CollationKey is returned. 
  147.  * @see java.text.CollationKey
  148.  * @see #compare 
  149.  */
  150. public CollationKey getCollationKey(String source) {
  151. return collator.getCollationKey(source);
  152. }
  153. /**
  154.  * Convenience method for comparing the equality of two strings based on this Collator's collation rules. 
  155.  * @param source the source string to be compared with. 
  156.  * @param target the target string to be compared with. 
  157.  * @return true if the strings are equal according to the collation rules, false otherwise. 
  158.  * @see #compare 
  159.  */
  160. public boolean equals(String source, String target) {
  161. return collator.equals(source, target);
  162. }
  163. /**
  164.  * Returns this Collator's strength property.
  165.  * The strength property determines the minimum level of difference considered significant during comparison.
  166.  * See the Collator class description for an example of use. 
  167.  * @return this Collator's current strength property. 
  168.  * @see #setStrength
  169.  */
  170. public int getStrength() { return collator.getStrength(); }
  171. /**
  172.  * Sets this Collator's strength property.
  173.  * The strength property determines the minimum level of difference considered significant during comparison.
  174.  * See the Collator class description for an example of use. 
  175.  * @param newStrength the new strength value. 
  176.  * @exception IllegalArgumentException if the new strength value is not one of PRIMARY, SECONDARY, TERTIARY or IDENTICAL. 
  177.  * @see #getStrength
  178.  */
  179. public void setStrength(int newStrength) { collator.setStrength(newStrength); }
  180. /**
  181.  * Get the decomposition mode of this Collator.
  182.  * Decomposition mode determines how Unicode composed characters are handled.
  183.  * Adjusting decomposition mode allows the user to select between faster and more complete collation behavior. 
  184.  * The three values for decomposition mode are: <ul>
  185.  * <li>NO_DECOMPOSITION, 
  186.  * <li>CANONICAL_DECOMPOSITION 
  187.  * <li>FULL_DECOMPOSITION. 
  188.  * </ul>See the documentation for these three constants for a description of their meaning. 
  189.  * @return the decomposition mode 
  190.  * @see #setDecomposition
  191.  */
  192. public int getDecomposition() { return collator.getDecomposition(); }
  193. /**
  194.  * Set the decomposition mode of this Collator.
  195.  * See getDecomposition for a description of decomposition mode. 
  196.  * @param decompositionMode the new decomposition mode 
  197.  * @throws IllegalArgumentException if the given value is not a valid decomposition mode. 
  198.  * @see #getDecomposition
  199.  */
  200. public void setDecomposition(int decompositionMode) { collator.setDecomposition(decompositionMode); }
  201. public int hashCode() { return collator.hashCode(); }
  202. public boolean equals(Object other) { return (other instanceof TreeCollator) ? collator.equals(((TreeCollator)other).collator) : false; }
  203. /**
  204.  * Provides a string description of this object.
  205.  */
  206. public String toString() {
  207. StringBuffer buffer = new StringBuffer();
  208. buffer.append(getClass().getName());
  209. buffer.append("[");
  210. buffer.append(paramString().toString());
  211. buffer.append("]");
  212. return buffer.toString();
  213. }
  214. protected StringBuffer paramString() {
  215. StringBuffer buffer = new StringBuffer();
  216. buffer.append("strength=");
  217. switch (getStrength()) {
  218. case PRIMARY:
  219. buffer.append("PRIMARY");
  220. break;
  221. case SECONDARY:
  222. buffer.append("SECONDARY");
  223. break;
  224. case TERTIARY:
  225. buffer.append("TERTIARY");
  226. break;
  227. case IDENTICAL:
  228. buffer.append("IDENTICAL");
  229. break;
  230. default:
  231. buffer.append("unknown");
  232. }
  233. buffer.append(",decomposition=");
  234. switch (getDecomposition()) {
  235. case NO_DECOMPOSITION:
  236. buffer.append("NO_DECOMPOSITION");
  237. break;
  238. case CANONICAL_DECOMPOSITION:
  239. buffer.append("CANONICAL_DECOMPOSITION");
  240. break;
  241. case FULL_DECOMPOSITION:
  242. buffer.append("FULL_DECOMPOSITION");
  243. break;
  244. default:
  245. buffer.append("unknown");
  246. }
  247. if (descending) buffer.append(",descending");
  248. return buffer;
  249. }
  250. }