KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > LegacyAnalysisContext


1 /*
2  * FindBugs - Find Bugs in Java programs
3  * Copyright (C) 2003-2006, University of Maryland
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 edu.umd.cs.findbugs.ba;
21
22 import java.io.IOException JavaDoc;
23
24 import org.apache.bcel.Repository;
25 import org.apache.bcel.classfile.JavaClass;
26
27 import edu.umd.cs.findbugs.annotations.NonNull;
28 import edu.umd.cs.findbugs.ba.ch.Subtypes;
29 import edu.umd.cs.findbugs.ba.npe.ParameterNullnessPropertyDatabase;
30 import edu.umd.cs.findbugs.ba.type.FieldStoreTypeDatabase;
31 import edu.umd.cs.findbugs.util.MapCache;
32
33 /**
34  * Original implementation of AnalysisContext.
35  * (Eventual goal is a new implementation that uses
36  * the IAnalysisCache.)
37  *
38  * @author David Hovemeyer
39  */

40 public class LegacyAnalysisContext extends AnalysisContext {
41     
42     private RepositoryLookupFailureCallback lookupFailureCallback;
43     private SourceFinder sourceFinder;
44     private MapCache<JavaClass, ClassContext> classContextCache;
45     private Subtypes subtypes;
46     private final SourceInfoMap sourceInfoMap;
47     private InnerClassAccessMap innerClassAccessMap;
48     
49     // Interprocedural fact databases
50
// private MayReturnNullPropertyDatabase mayReturnNullDatabase;
51
private FieldStoreTypeDatabase fieldStoreTypeDatabase;
52     private ParameterNullnessPropertyDatabase unconditionalDerefParamDatabase;
53     
54     
55     private NullnessAnnotationDatabase nullnessAnnotationDatabase; //= new NullnessAnnotationDatabase();
56

57     @Override JavaDoc
58     public NullnessAnnotationDatabase getNullnessAnnotationDatabase() {
59         return nullnessAnnotationDatabase;
60     }
61
62     private CheckReturnAnnotationDatabase checkReturnAnnotationDatabase;
63
64     @Override JavaDoc
65     public CheckReturnAnnotationDatabase getCheckReturnAnnotationDatabase() {
66         return checkReturnAnnotationDatabase;
67     }
68     
69     private AnnotationRetentionDatabase annotationRetentionDatabase;
70
71     @Override JavaDoc
72     public AnnotationRetentionDatabase getAnnotationRetentionDatabase() {
73         return annotationRetentionDatabase;
74     }
75     
76     private JCIPAnnotationDatabase jcipAnnotationDatabase;
77     
78     @Override JavaDoc
79     public JCIPAnnotationDatabase getJCIPAnnotationDatabase() {
80         return jcipAnnotationDatabase;
81     }
82
83     /** save the original SyntheticRepository so we may
84      * obtain JavaClass objects which we can reuse.
85      * (A URLClassPathRepository gets closed after analysis.) */

86     private static final org.apache.bcel.util.Repository originalRepository =
87         Repository.getRepository(); // BCEL SyntheticRepository
88

89     /**
90      * Default maximum number of ClassContext objects to cache.
91      * FIXME: need to evaluate this parameter. Need to keep stats about accesses.
92      */

93     private static final int DEFAULT_CACHE_SIZE = 6;
94
95     /**
96      * Constructor.
97      *
98      * @param lookupFailureCallback the RepositoryLookupFailureCallback to use when
99      * reporting errors and class lookup failures
100      */

101     LegacyAnalysisContext(RepositoryLookupFailureCallback lookupFailureCallback) {
102         this.lookupFailureCallback = lookupFailureCallback;
103         this.sourceFinder = new SourceFinder();
104         this.subtypes = new Subtypes();
105         this.sourceInfoMap = new SourceInfoMap();
106         
107         if (originalRepository instanceof URLClassPathRepository) {
108             getLookupFailureCallback().logError(
109                 "originalRepository is a URLClassPathRepository, which may cause problems");
110         }
111
112         //CheckReturnAnnotationDatabase may reportMissingClass, so do it after the currentAnalysisContext is set.
113
//Otherwise null ptr exceptions will happen.
114

115         /*
116         checkReturnAnnotationDatabase = new CheckReturnAnnotationDatabase();
117
118         To take the above comment one step further, there is a circular dependency here.
119         CheckReturnAnnotationDatabase calls Repository.lookupClass() when it is initializing,
120         so we don't want to instantiate it until after we have set up the repository.
121         Unfortunately, we can't set up the repository properly without an AnalysisContext,
122         and therefore not until after this AnalysisContext constructor returns.
123
124         To handle this, we no longer instantiate the CheckReturnAnnotationDatabase here in
125         the constructor, but instead require that initDatabases() be called later on, after
126         the repository has been set up.
127         Yes this is ugly, but it will do for now. It's not worth the effort to redisign out
128         the circular dependency properly if we plan to move from BCEL to ASM soon anyway.
129         */

130     }
131
132     @Override JavaDoc
133     public void initDatabases() {
134         checkReturnAnnotationDatabase = new CheckReturnAnnotationDatabase();
135         annotationRetentionDatabase = new AnnotationRetentionDatabase();
136         jcipAnnotationDatabase = new JCIPAnnotationDatabase();
137         nullnessAnnotationDatabase = new NullnessAnnotationDatabase();
138     }
139
140     
141     @Override JavaDoc
142     public void updateDatabases(int pass) {
143         if (pass == 0) {
144             checkReturnAnnotationDatabase.loadAuxiliaryAnnotations();
145             nullnessAnnotationDatabase.loadAuxiliaryAnnotations();
146         }
147     }
148     @Override JavaDoc
149     public RepositoryLookupFailureCallback getLookupFailureCallback() {
150         return lookupFailureCallback;
151     }
152
153     @Override JavaDoc
154     public SourceFinder getSourceFinder() {
155         return sourceFinder;
156     }
157     
158     @Override JavaDoc
159     public Subtypes getSubtypes() {
160         return subtypes;
161     }
162     
163     @Override JavaDoc
164     public void clearRepository() {
165         // If the old repository backing store is a URLClassPathRepository
166
// (which it certainly should be), destroy it.
167
// This will close all underlying resources (archive files, etc.)
168
org.apache.bcel.util.Repository repos = Repository.getRepository();
169         if (repos instanceof URLClassPathRepository) {
170             ((URLClassPathRepository) repos).destroy();
171         }
172         
173         // Purge repository of previous contents
174
Repository.clearCache();
175         
176         // Clear any ClassContexts
177
clearClassContextCache();
178
179         // Clear InnerClassAccessMap cache.
180
getInnerClassAccessMap().clearCache();
181
182         // Create a URLClassPathRepository and make it current.
183
URLClassPathRepository repository = new URLClassPathRepository();
184         Repository.setRepository(repository);
185     }
186     
187     @Override JavaDoc
188     public void clearClassContextCache() {
189         if (classContextCache != null)
190             classContextCache.clear();
191     }
192     
193     @Override JavaDoc
194     public void addClasspathEntry(String JavaDoc url) throws IOException JavaDoc {
195         URLClassPathRepository repos = (URLClassPathRepository) Repository.getRepository();
196         repos.addURL(url);
197     }
198     
199     @Override JavaDoc
200     public void addApplicationClassToRepository(JavaClass appClass) {
201         Repository.addClass(appClass);
202         subtypes.addApplicationClass(appClass);
203     }
204     
205     @Override JavaDoc
206     public JavaClass lookupClass(@NonNull String JavaDoc className) throws ClassNotFoundException JavaDoc {
207         // TODO: eventually we should move to our own thread-safe repository implementation
208
if (className == null) throw new IllegalArgumentException JavaDoc("className is null");
209         return Repository.lookupClass(className);
210         // note: previous line does not throw ClassNotFoundException, instead returns null
211
}
212     
213     /**
214      * Get the ClassContext for a class.
215      *
216      * @param javaClass the class
217      * @return the ClassContext for that class
218      */

219     int hits = 0;
220     int misses = 0;
221
222     @Override JavaDoc
223     public ClassContext getClassContext(JavaClass javaClass) {
224         if (classContextCache == null) {
225         int cacheSize = getBoolProperty(AnalysisFeatures.CONSERVE_SPACE) ? 3 : DEFAULT_CACHE_SIZE;
226         classContextCache = new MapCache<JavaClass,ClassContext>(cacheSize);
227         }
228         ClassContext classContext = classContextCache.get(javaClass);
229         if (classContext == null) {
230             classContext = new ClassContext(javaClass, this);
231             classContextCache.put(javaClass, classContext);
232             misses++;
233         } else hits++;
234         return classContext;
235     }
236
237     @Override JavaDoc
238     public String JavaDoc getClassContextStats() {
239         if (classContextCache == null) return null;
240         return hits + "/" + misses + ":" + classContextCache.getStatistics();
241     }
242
243     @Override JavaDoc
244     public SourceInfoMap getSourceInfoMap() {
245         return sourceInfoMap;
246     }
247
248     @Override JavaDoc
249     public FieldStoreTypeDatabase getFieldStoreTypeDatabase() {
250         if (fieldStoreTypeDatabase == null) {
251             fieldStoreTypeDatabase = new FieldStoreTypeDatabase();
252         }
253         return fieldStoreTypeDatabase;
254     }
255
256     @Override JavaDoc
257     public ParameterNullnessPropertyDatabase getUnconditionalDerefParamDatabase() {
258         if (unconditionalDerefParamDatabase == null) {
259             unconditionalDerefParamDatabase = new ParameterNullnessPropertyDatabase();
260         }
261         return unconditionalDerefParamDatabase;
262     }
263     
264     /* (non-Javadoc)
265      * @see edu.umd.cs.findbugs.ba.AnalysisContext#getInnerClassAccessMap()
266      */

267     @Override JavaDoc
268     public InnerClassAccessMap getInnerClassAccessMap() {
269         if (innerClassAccessMap == null) {
270             innerClassAccessMap = InnerClassAccessMap.create();
271         }
272         return innerClassAccessMap;
273     }
274
275             
276
277 }
278
Popular Tags