01: /*
02: * Licensed to the Apache Software Foundation (ASF) under one
03: * or more contributor license agreements. See the NOTICE file
04: * distributed with this work for additional information
05: * regarding copyright ownership. The ASF licenses this file
06: * to you under the Apache License, Version 2.0 (the
07: * "License"); you may not use this file except in compliance
08: * with the License. You may obtain a copy of the License at
09: *
10: * http://www.apache.org/licenses/LICENSE-2.0
11: *
12: * Unless required by applicable law or agreed to in writing,
13: * software distributed under the License is distributed on an
14: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15: * KIND, either express or implied. See the License for the
16: * specific language governing permissions and limitations
17: * under the License.
18: */
19: package org.apache.openjpa.meta;
20:
21: import java.io.Serializable;
22: import java.util.Comparator;
23:
24: /**
25: * Comparator that keeps classes in inheritance order.
26: *
27: * @author Abe White
28: * @nojavadoc
29: */
30: public class InheritanceComparator implements Comparator, Serializable {
31:
32: private Class _base = null;
33:
34: /**
35: * Set the least-derived type possible; defaults to <code>null</code>.
36: */
37: public void setBase(Class base) {
38: _base = base;
39: }
40:
41: /**
42: * Subclasses can override this method to extract the class to compare
43: * on from the elements of the collection.
44: */
45: protected Class toClass(Object elem) {
46: return (Class) elem;
47: }
48:
49: public int compare(Object o1, Object o2) {
50: if (o1 == o2)
51: return 0;
52: if (o1 == null)
53: return -1;
54: if (o2 == null)
55: return 1;
56:
57: Class c1 = toClass(o1);
58: Class c2 = toClass(o2);
59: if (c1 == c2)
60: return 0;
61: if (c1 == null)
62: return -1;
63: if (c2 == null)
64: return 1;
65:
66: int i1 = levels(c1);
67: int i2 = levels(c2);
68: if (i1 == i2) {
69: // sort simple interfaces as well as simple order test will fail.
70: if (c1.isAssignableFrom(c2))
71: return -1;
72: if (c2.isAssignableFrom(c1))
73: return 1;
74: return c1.getName().compareTo(c2.getName());
75: }
76: if (i1 < i2)
77: return -1;
78: else if (i1 > i2)
79: return 1;
80: else
81: return 0;
82: }
83:
84: /**
85: * Count the levels of inheritance between this class and our base class.
86: */
87: private int levels(Class to) {
88: if (to.isInterface())
89: return to.getInterfaces().length;
90: if (_base == null)
91: return 0;
92: for (int i = 0; to != null; i++, to = to.getSuperclass())
93: if (to == _base)
94: return i;
95: return Integer.MAX_VALUE;
96: }
97: }
|