KickJava   Java API By Example, From Geeks To Geeks.

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


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 net.sf.clirr.core.Severity;
23 import net.sf.clirr.core.ScopeSelector;
24 import net.sf.clirr.core.Message;
25 import net.sf.clirr.core.internal.AbstractDiffReporter;
26 import net.sf.clirr.core.internal.ApiDiffDispatcher;
27 import net.sf.clirr.core.internal.ClassChangeCheck;
28 import net.sf.clirr.core.spi.JavaType;
29 import net.sf.clirr.core.spi.Scope;
30
31 /**
32  * Detects changes in class access declaration, for both "top-level" classes,
33  * and nested classes.
34  * <p>
35  * Java class files only ever contain scope specifiers of "public" or "package".
36  * For top-level classes, this is expected: it is not possible to have a
37  * top-level protected or private class.
38  * <p>
39  * However nested classes <i>can</i> be declared as protected or private. The
40  * way to tell the real scope of a nested class is to ignore the scope in
41  * the actual class file itself, and instead look in the "InnerClasses"
42  * attribute stored on the enclosing class. This is exactly what the java
43  * compiler does when compiling, and what the jvm does when verifying class
44  * linkage at runtime.
45  *
46  * @author Simon Kitching
47  */

48 public final class ClassScopeCheck
49         extends AbstractDiffReporter
50         implements ClassChangeCheck
51 {
52     private static final Message MSG_SCOPE_INCREASED = new Message(1000);
53     private static final Message MSG_SCOPE_DECREASED = new Message(1001);
54     private static final Message MSG_ERROR_DETERMINING_SCOPE_OLD = new Message(1002);
55     private static final Message MSG_ERROR_DETERMINING_SCOPE_NEW = new Message(1003);
56
57     private ScopeSelector scopeSelector;
58
59     /**
60      * Create a new instance of this check.
61      * @param dispatcher the diff dispatcher that distributes the detected changes to the listeners.
62      */

63     public ClassScopeCheck(ApiDiffDispatcher dispatcher, ScopeSelector scopeSelector)
64     {
65         super(dispatcher);
66         this.scopeSelector = scopeSelector;
67     }
68
69     /** {@inheritDoc} */
70     public boolean check(JavaType compatBaseline, JavaType currentVersion)
71     {
72         Scope bScope = compatBaseline.getEffectiveScope();
73         Scope cScope = currentVersion.getEffectiveScope();
74
75         if (!scopeSelector.isSelected(bScope) && !scopeSelector.isSelected(cScope))
76         {
77             // neither the old nor the new class are "visible" at the scope
78
// the user of this class cares about, so just skip this test
79
// and all following tests for this pair of classes.
80
return false;
81         }
82
83         if (cScope.isMoreVisibleThan(bScope))
84         {
85             String JavaDoc[] args = {bScope.getDesc(), cScope.getDesc()};
86
87             log(MSG_SCOPE_INCREASED,
88                 Severity.INFO, compatBaseline.getName(), null, null, args);
89         }
90         else if (cScope.isLessVisibleThan(bScope))
91         {
92             String JavaDoc[] args = {bScope.getDesc(), cScope.getDesc()};
93
94             log(MSG_SCOPE_DECREASED,
95                 getSeverity(compatBaseline, Severity.ERROR),
96                 compatBaseline.getName(), null, null, args);
97         }
98
99         // Apply further checks only if both versions of the class have scopes
100
// of interest. For example, when the user is only interested in
101
// public & protected classes, then for classes which have just become
102
// public/protected we just want to report that it is now "visible";
103
// because the class was not visible before the differences since its
104
// last version are not relevant. And for classes which are no longer
105
// public/protected, we just want to report that the whole class is no
106
// longer "visible"; as it is not visible to users any changes to it
107
// are irrelevant.
108
return scopeSelector.isSelected(bScope) && scopeSelector.isSelected(cScope);
109     }
110
111 }
112
Popular Tags