1/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2 *
3 * This program and the accompanying materials are made available under
4 * the terms of the Common Public License v1.0 which accompanies this distribution,
5 * and is available at http://www.eclipse.org/legal/cpl-v10.html
6 *
7 * $Id: ItemComparator.java,v 1.1.1.1 2004/05/09 16:57:37 vlad_r Exp $
8 */
9package com.vladium.emma.report;
10
11import java.util.Comparator;
12
13// ----------------------------------------------------------------------------
14/**
15 * @author Vlad Roubtsov, (C) 2003
16 */
17public
18interface ItemComparator extends Comparator
19{
20    // public: ................................................................
21
22
23    ItemComparator NULL_COMPARATOR = new Factory.NullComparator ();
24
25
26    abstract class Factory
27    {
28        public static ItemComparator create (final int [] attributeIDsWithDir, final int unitsID)
29        {
30            if (attributeIDsWithDir == null)
31                throw new IllegalArgumentException ("null input: attributeIDsWithDir");
32
33            if (attributeIDsWithDir.length == 0)
34                return NULL_COMPARATOR;
35
36            // TODO: validate against duplicates
37            // TODO: memoize
38
39            // TODO: move the code below into the attr factory
40            final Comparator [] comparators = new Comparator [attributeIDsWithDir.length >> 1];
41            for (int a = 0; a < attributeIDsWithDir.length; a += 2)
42            {
43                final int attributeID = attributeIDsWithDir [a];
44
45                final Comparator comparator = IItemAttribute.Factory.getAttribute (attributeID, unitsID).comparator ();
46                comparators [a >> 1] = attributeIDsWithDir [a + 1] < 0 ? new ReverseComparator (comparator) : comparator;
47            }
48
49            return new CompositeComparator (comparators);
50        }
51
52        private static final class NullComparator implements ItemComparator
53        {
54            public int compare (final Object l, final Object g)
55            {
56                return 0;
57            }
58
59        } // end of nested class
60
61
62        private static final class ReverseComparator implements ItemComparator
63        {
64            public int compare (final Object l, final Object g)
65            {
66                return m_comparator.compare (g, l);
67            }
68
69
70            ReverseComparator (final Comparator comparator)
71            {
72                m_comparator = comparator;
73            }
74
75
76            private final Comparator m_comparator;
77
78        } // end of nested class
79
80
81        private static final class CompositeComparator implements ItemComparator
82        {
83            public int compare (final Object l, final Object g)
84            {
85                // TODO: this needs to check whether both items have a given attr type
86
87                for (int c = 0; c < m_comparators.length; ++ c)
88                {
89                    final int diff = m_comparators [c].compare (l, g);
90                    if (diff != 0) return diff;
91                }
92
93                return 0;
94            }
95
96
97            CompositeComparator (final Comparator [] comparators)
98            {
99                m_comparators = comparators;
100            }
101
102
103            private final Comparator [] m_comparators;
104
105        } // end of nested class
106
107    } // end of nested interface
108
109} // end of interface
110// ----------------------------------------------------------------------------