View Javadoc

1   /*
2    *  Copyright 2001-2004 The Apache Software Foundation
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package net.sf.collections15.comparators;
17  
18  import net.sf.collections15.Transformer;
19  
20  import java.util.Comparator;
21  
22  
23  /***
24   * Decorates another <code>Comparator</code> with transformation behavior. That
25   * is, the input values are transformed, and the results are passed to the
26   * underlying <code>Comparator</code>'s. {@link Comparator#compare(Object,Object)
27   * compare} method.
28   *
29   * @see net.sf.collections15.Transformer
30   * @see ComparableComparator
31   * @author Chris Lambrou (port to Java 5.0)
32   * @since Collections15 1.0
33   */
34  public class TransformingComparator <I, O> implements Comparator<I>
35  {
36  
37      /***
38       * The decorated <code>Comparator</code>.
39       */
40      protected Comparator<O> decorated;
41  
42      /***
43       * The <code>Transformer</code> being used.
44       */
45      protected Transformer<I, O> transformer;
46  
47      /***
48       * Returns an instance whose ordering is based on the natural ordering of
49       * the output of the specified <code>Transformer</code>.
50       *
51       * @param transformer The <code>Transformer</code> used to transform the
52       *                    compared objects prior to applying the natural sorting
53       *                    order of the resulting transformed output.
54       */
55      public static <I, O extends Comparable> TransformingComparator<I, O> getInstance(Transformer<I, O> transformer)
56      {
57          return decorate(transformer, new ComparableComparator<O>());
58      }
59  
60      /***
61       * Returns an instance whose ordering is determined by applying the odereing
62       * of the specified <code>Comparator</code> to the output of the specified
63       * <code>Transformer</code>.
64       *
65       * @param transformer The <code>Transformer</code> used to transform the
66       *                    compared objects.
67       * @param decorated   The decorated <code>Comparator</code> that is applied
68       *                    to the transformed comparison objects.
69       */
70      public static <I, O> TransformingComparator<I, O> decorate(Transformer<I, O> transformer, Comparator<O> decorated)
71      {
72          return new TransformingComparator<I, O>(transformer, decorated);
73      }
74  
75      /***
76       * Constructs an instance with the given <code>Transformer</code> and
77       * <code>Comparator</code>.
78       *
79       * @param transformer The <code>Transformer</code> used to transform the
80       *                    compared objects.
81       * @param decorated   The decorated <code>Comparator</code> that is applied
82       *                    to the transformed comparison objects.
83       *
84       * @throws IllegalArgumentException If either argument is <code>null</code>.
85       */
86      protected TransformingComparator(Transformer<I, O> transformer, Comparator<O> decorated)
87      {
88          if (transformer == null) {
89              throw new IllegalArgumentException("null transformer");
90          }
91          if (decorated == null) {
92              throw new IllegalArgumentException("null decorated comparator");
93          }
94          this.decorated = decorated;
95          this.transformer = transformer;
96      }
97  
98      /***
99       * Returns the result of comparing the values from the transform operation.
100      *
101      * @param obj1 The first object to transform then compare.
102      * @param obj2 The second object to transform then compare.
103      *
104      * @return A negative value if <code>obj1</code> is less than
105      *         <code>obj2</code>. A positive value if <code>obj1</code> is
106      *         greater than <code>obj2</code>. Zero if the two objects are
107      *         equivalent with respect to the ordering.
108      */
109     public int compare(I obj1, I obj2)
110     {
111         O value1 = transformer.transform(obj1);
112         O value2 = transformer.transform(obj2);
113         return decorated.compare(value1, value2);
114     }
115 
116 }
117