KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > clirr > core > Checker


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;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25
26 import net.sf.clirr.core.internal.ApiDiffDispatcher;
27 import net.sf.clirr.core.internal.ClassChangeCheck;
28 import net.sf.clirr.core.internal.CoIterator;
29 import net.sf.clirr.core.internal.NameComparator;
30 import net.sf.clirr.core.internal.checks.ClassHierarchyCheck;
31 import net.sf.clirr.core.internal.checks.ClassModifierCheck;
32 import net.sf.clirr.core.internal.checks.ClassScopeCheck;
33 import net.sf.clirr.core.internal.checks.FieldSetCheck;
34 import net.sf.clirr.core.internal.checks.GenderChangeCheck;
35 import net.sf.clirr.core.internal.checks.InterfaceSetCheck;
36 import net.sf.clirr.core.internal.checks.MethodSetCheck;
37 import net.sf.clirr.core.spi.JavaType;
38 import net.sf.clirr.core.spi.Scope;
39
40 /**
41  * This is the main class to be used by Clirr frontends,
42  * it implements the checking functionality of Clirr.
43  * Frontends can create an instance of this class
44  * and register themselves as DiffListeners, they are then
45  * informed whenever an API change is detected by the
46  * reportDiffs method.
47  *
48  * @author lkuehne
49  */

50 public final class Checker implements ApiDiffDispatcher
51 {
52     private static final Message MSG_CLASS_ADDED = new Message(8000);
53     private static final Message MSG_CLASS_REMOVED = new Message(8001);
54
55     private List JavaDoc listeners = new ArrayList JavaDoc();
56
57     private List JavaDoc classChecks = new ArrayList JavaDoc();
58
59     private ScopeSelector scopeSelector = new ScopeSelector();
60
61     /**
62      * Package visible constructor for unit testing.
63      */

64     Checker(ClassChangeCheck ccc)
65     {
66         if (ccc != null)
67         {
68             classChecks.add(ccc);
69         }
70     }
71
72     /**
73      * Creates a new Checker.
74      */

75     public Checker()
76     {
77         classChecks.add(new ClassScopeCheck(this, scopeSelector));
78         classChecks.add(new GenderChangeCheck(this));
79         classChecks.add(new ClassModifierCheck(this));
80         classChecks.add(new InterfaceSetCheck(this));
81         classChecks.add(new ClassHierarchyCheck(this));
82         classChecks.add(new FieldSetCheck(this, scopeSelector));
83         classChecks.add(new MethodSetCheck(this, scopeSelector));
84     }
85
86     public ScopeSelector getScopeSelector()
87     {
88         return scopeSelector;
89     }
90
91     public void addDiffListener(DiffListener listener)
92     {
93         listeners.add(listener);
94     }
95
96     private void fireStart()
97     {
98         for (Iterator JavaDoc it = listeners.iterator(); it.hasNext();)
99         {
100             DiffListener diffListener = (DiffListener) it.next();
101             diffListener.start();
102         }
103     }
104
105     private void fireStop()
106     {
107         for (Iterator JavaDoc it = listeners.iterator(); it.hasNext();)
108         {
109             DiffListener diffListener = (DiffListener) it.next();
110             diffListener.stop();
111         }
112     }
113
114     public void fireDiff(ApiDifference diff)
115     {
116         for (Iterator JavaDoc it = listeners.iterator(); it.hasNext();)
117         {
118             DiffListener diffListener = (DiffListener) it.next();
119             diffListener.reportDiff(diff);
120         }
121     }
122
123     /**
124      * Checks two sets of classes for api changes and reports
125      * them to the DiffListeners.
126      * @param compatibilityBaseline the classes that form the
127      * compatibility baseline to check against
128      * @param currentVersion the classes that are checked for
129      * compatibility with compatibilityBaseline
130      */

131     public void reportDiffs(
132         JavaType[] compatibilityBaseline, JavaType[] currentVersion)
133         throws CheckerException
134     {
135         fireStart();
136         runClassChecks(compatibilityBaseline, currentVersion);
137         fireStop();
138     }
139
140     private void runClassChecks(
141         JavaType[] compat, JavaType[] current)
142         throws CheckerException
143     {
144         CoIterator iter = new CoIterator(
145             new NameComparator(), compat, current);
146
147         while (iter.hasNext())
148         {
149             iter.next();
150
151             JavaType compatBaselineClass = (JavaType) iter.getLeft();
152             JavaType currentClass = (JavaType) iter.getRight();
153
154             if (compatBaselineClass == null)
155             {
156                 if (!scopeSelector.isSelected(currentClass.getEffectiveScope()))
157                 {
158                     continue;
159                 }
160                 final String JavaDoc className = currentClass.getName();
161                 final ApiDifference diff =
162                     new ApiDifference(
163                         MSG_CLASS_ADDED, Severity.INFO, className,
164                         null, null, null);
165                 fireDiff(diff);
166             }
167             else if (currentClass == null)
168             {
169                 final Scope classScope = compatBaselineClass.getEffectiveScope();
170                 if (!scopeSelector.isSelected(classScope))
171                 {
172                     continue;
173                 }
174                 final String JavaDoc className = compatBaselineClass.getName();
175                 final Severity severity = classScope.isLessVisibleThan(
176                         Scope.PROTECTED) ? Severity.INFO : Severity.ERROR;
177                 final ApiDifference diff =
178                     new ApiDifference(
179                         MSG_CLASS_REMOVED, severity, className,
180                         null, null, null);
181                 fireDiff(diff);
182             }
183             else
184             {
185                 // class is available in both releases
186
boolean continueTesting = true;
187                 for (Iterator JavaDoc it = classChecks.iterator(); it.hasNext() && continueTesting;)
188                 {
189                     ClassChangeCheck classChangeCheck = (ClassChangeCheck) it.next();
190                     continueTesting = classChangeCheck.check(
191                         compatBaselineClass, currentClass);
192                 }
193             }
194         }
195     }
196 }
197
Popular Tags