01: /* ***** BEGIN LICENSE BLOCK *****
02: * Version: MPL 1.1
03: * The contents of this file are subject to the Mozilla Public License Version
04: * 1.1 (the "License"); you may not use this file except in compliance with
05: * the License. You may obtain a copy of the License at
06: * http://www.mozilla.org/MPL/
07: *
08: * Software distributed under the License is distributed on an "AS IS" basis,
09: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10: * for the specific language governing rights and limitations under the
11: * License.
12: *
13: * The Original Code is Riot.
14: *
15: * The Initial Developer of the Original Code is
16: * Neteye GmbH.
17: * Portions created by the Initial Developer are Copyright (C) 2006
18: * the Initial Developer. All Rights Reserved.
19: *
20: * Contributor(s):
21: * Felix Gnass [fgnass at neteye dot de]
22: *
23: * ***** END LICENSE BLOCK ***** */
24: package org.riotfamily.common.collection;
25:
26: import java.util.Comparator;
27:
28: /**
29: * Comparator that compares two classes by their hierarchy differnce to a
30: * target class.
31: * <p>
32: * Example:
33: * <pre>
34: * c = new TypeDifferenceComparator(Integer.class);
35: *
36: * c.compare(Object.class, Number.class); // returns 1
37: * c.compare(Integer.class, Number.class); // returns -1
38: * c.compare(Collection.class, Number.class); // returns Integer.MAX_VALUE - 1
39: * c.compare(Collection.class, Object.class); // returns Integer.MAX_VALUE - 2
40: * </pre>
41: * </p>
42: */
43: public class TypeDifferenceComparator implements Comparator {
44:
45: private Class targetClass;
46:
47: public TypeDifferenceComparator(Class targetClass) {
48: this .targetClass = targetClass;
49: }
50:
51: public int compare(Object o1, Object o2) {
52: return getTypeDifference((Class) o1, targetClass)
53: - getTypeDifference((Class) o2, targetClass);
54: }
55:
56: /**
57: * <p>
58: * Example:
59: * <pre>
60: * getTypeDifference(Object.class, Integer.class); // returns 2
61: * getTypeDifference(Number.class, Integer.class); // returns 1
62: * getTypeDifference(Integer.class, Integer.class); // returns 0
63: *
64: * getTypeDifference(Integer.class, Float.class); // returns Integer.MAX_VALUE
65: * getTypeDifference(Integer.class, Number.class); // returns Integer.MAX_VALUE
66: * </pre>
67: * </p>
68: */
69: public static int getTypeDifference(Class baseClass, Class subClass) {
70: if (!baseClass.isAssignableFrom(subClass)) {
71: return Integer.MAX_VALUE;
72: }
73: int result = 0;
74: Class superClass = subClass.getSuperclass();
75: while (superClass != null) {
76: if (baseClass.isAssignableFrom(superClass)) {
77: result++;
78: superClass = superClass.getSuperclass();
79: } else {
80: superClass = null;
81: }
82: }
83: return result;
84: }
85:
86: }
|