KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > clirr > core > internal > checks > InterfaceSetCheck


1 //////////////////////////////////////////////////////////////////////////////
2
// Clirr: compares two versions of a java library for binary compatibility
3
// Copyright (C) 2003 - 2005 Lars Kühne
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
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 java.util.Set JavaDoc;
23 import java.util.TreeSet JavaDoc;
24
25 import net.sf.clirr.core.Severity;
26 import net.sf.clirr.core.Message;
27 import net.sf.clirr.core.internal.AbstractDiffReporter;
28 import net.sf.clirr.core.internal.ApiDiffDispatcher;
29 import net.sf.clirr.core.internal.ClassChangeCheck;
30 import net.sf.clirr.core.internal.CoIterator;
31 import net.sf.clirr.core.internal.NameComparator;
32 import net.sf.clirr.core.spi.JavaType;
33
34 /**
35  * Detects changes in the set of interfaces implemented by a class.
36  *
37  * @author lkuehne
38  */

39 public final class InterfaceSetCheck
40     extends AbstractDiffReporter
41     implements ClassChangeCheck
42 {
43     private static final Message MSG_IFACE_ADDED = new Message(4000);
44     private static final Message MSG_IFACE_REMOVED = new Message(4001);
45
46     /**
47      * Create a new instance of this check.
48      * @param dispatcher the diff dispatcher that distributes the detected changes to the listeners.
49      */

50     public InterfaceSetCheck(ApiDiffDispatcher dispatcher)
51     {
52         super(dispatcher);
53     }
54
55     /** {@inheritDoc} */
56     public boolean check(JavaType compatBaseline, JavaType currentVersion)
57     {
58         JavaType[] compatInterfaces = compatBaseline.getAllInterfaces();
59         JavaType[] currentInterfaces = currentVersion.getAllInterfaces();
60
61         // Note: getAllInterfaces might return multiple array entries with the same
62
// interface, so we need to use sets to remove duplicates...
63
Set JavaDoc compat = createClassSet(compatInterfaces);
64         Set JavaDoc current = createClassSet(currentInterfaces);
65
66         final String JavaDoc className = compatBaseline.getName();
67
68         CoIterator iter = new CoIterator(
69             new NameComparator(), compat, current);
70
71         while (iter.hasNext())
72         {
73             iter.next();
74
75             JavaType compatInterface = (JavaType) iter.getLeft();
76             JavaType currentInterface = (JavaType) iter.getRight();
77
78             if (compatInterface != null && className.equals(compatInterface.getName())
79                 || currentInterface != null && className.equals(currentInterface.getName()))
80             {
81                 // This occurs because an interface has itself in the set of all interfaces.
82
// We can't just let the test below handle this case because that won't
83
// work when a gender change has occurred.
84
continue;
85             }
86
87             if (compatInterface == null)
88             {
89                 // TODO: check whether the class already implements
90
// throwable. If so, this should probably be a warning,
91
// because the presence of this extra interface could
92
// change exception-catching behaviour.
93
//
94
// Actually, it could also change code which uses
95
// "instance-of" and similar methods too, even when not
96
// a throwable. However this is fairly low probability..
97
log(MSG_IFACE_ADDED,
98                         Severity.INFO, className, null, null,
99                         new String JavaDoc[] {currentInterface.getName()});
100             }
101             else if (currentInterface == null)
102             {
103                 log(MSG_IFACE_REMOVED,
104                         getSeverity(compatBaseline, Severity.ERROR),
105                         className, null, null,
106                         new String JavaDoc[] {compatInterface.getName()});
107             }
108         }
109
110         return true;
111     }
112
113     /**
114      * Creates a Set of JavaType objects.
115      * @param classes the classes to include in the set, might contain duplicates
116      * @return Set<JavaType>
117      */

118     private Set JavaDoc createClassSet(JavaType[] classes)
119     {
120         // JavaType does not specify the semantics of equals(), so we use a Set implementation
121
// that determines equality by invoking a Comparator instead of calling equals()
122

123         Set JavaDoc current = new TreeSet JavaDoc(new NameComparator());
124         for (int i = 0; i < classes.length; i++)
125         {
126             current.add(classes[i]);
127         }
128         return current;
129     }
130 }
131
Popular Tags