01: //////////////////////////////////////////////////////////////////////////////
02: // Clirr: compares two versions of a java library for binary compatibility
03: // Copyright (C) 2003 - 2005 Lars Kühne
04: //
05: // This library is free software; you can redistribute it and/or
06: // modify it under the terms of the GNU Lesser General Public
07: // License as published by the Free Software Foundation; either
08: // version 2.1 of the License, or (at your option) any later version.
09: //
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:
20: package net.sf.clirr.core.internal.checks;
21:
22: import net.sf.clirr.core.Message;
23: import net.sf.clirr.core.Severity;
24: import net.sf.clirr.core.internal.AbstractDiffReporter;
25: import net.sf.clirr.core.internal.ApiDiffDispatcher;
26: import net.sf.clirr.core.internal.ClassChangeCheck;
27: import net.sf.clirr.core.internal.CoIterator;
28: import net.sf.clirr.core.internal.NameComparator;
29: import net.sf.clirr.core.spi.JavaType;
30:
31: /**
32: * Detects changes in the set of superclasses.
33: *
34: * @author lkuehne
35: */
36: public final class ClassHierarchyCheck extends AbstractDiffReporter
37: implements ClassChangeCheck {
38: private static final Message MSG_ADDED_CLASS_TO_SUPERCLASSES = new Message(
39: 5000);
40: private static final Message MSG_REMOVED_CLASS_FROM_SUPERCLASSES = new Message(
41: 5001);
42:
43: /**
44: * Create a new instance of this check.
45: * @param dispatcher the diff dispatcher that distributes the detected changes to the listeners.
46: */
47: public ClassHierarchyCheck(ApiDiffDispatcher dispatcher) {
48: super (dispatcher);
49: }
50:
51: /** {@inheritDoc} */
52: public boolean check(JavaType compatBaseline,
53: JavaType currentVersion) {
54: JavaType[] compatSupers = compatBaseline.getSuperClasses();
55: JavaType[] currentSupers = currentVersion.getSuperClasses();
56:
57: boolean isThrowable = false;
58: for (int i = 0; i < compatSupers.length; i++) {
59: JavaType javaClass = compatSupers[i];
60: if ("java.lang.Throwable".equals(javaClass.getName())) {
61: isThrowable = true;
62: }
63: }
64:
65: final String className = compatBaseline.getName();
66:
67: CoIterator iter = new CoIterator(new NameComparator(),
68: compatSupers, currentSupers);
69:
70: while (iter.hasNext()) {
71: iter.next();
72: JavaType baselineSuper = (JavaType) iter.getLeft();
73: JavaType currentSuper = (JavaType) iter.getRight();
74:
75: if (baselineSuper == null) {
76: Severity severity;
77: if (isThrowable) {
78: // report a warning, because a change to the set of types
79: // implemented by a thrown object can affect the
80: // exception-catching behaviour of a program.
81: severity = Severity.WARNING;
82: } else {
83: severity = Severity.INFO;
84: }
85:
86: log(MSG_ADDED_CLASS_TO_SUPERCLASSES, getSeverity(
87: compatBaseline, severity), className, null,
88: null, new String[] { currentSuper.getName() });
89: } else if (currentSuper == null) {
90: log(MSG_REMOVED_CLASS_FROM_SUPERCLASSES, getSeverity(
91: compatBaseline, Severity.ERROR), className,
92: null, null, new String[] { baselineSuper
93: .getName() });
94: }
95: }
96:
97: return true;
98: }
99: }
|