KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > verifier > apiscan > classfile > BCELClosureCompilerImpl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * BCELClosureCompilerImpl.java
26  *
27  * Created on August 13, 2004, 3:34 PM
28  */

29
30 package com.sun.enterprise.tools.verifier.apiscan.classfile;
31
32 import java.io.File JavaDoc;
33 import java.io.IOException JavaDoc;
34 import java.util.*;
35 import java.util.logging.Level JavaDoc;
36
37 /**
38  * An implementation of {@link ClosureCompilerImplBase} based on
39  * BCEL.
40  *
41  * @author Sanjeeb.Sahoo@Sun.COM
42  */

43 public class BCELClosureCompilerImpl extends ClosureCompilerImplBase {
44
45     /*
46      * Earlier this class used to be called as ClosureCompilerImpl.
47      * So to get the history of this file, use above name in CVS
48      */

49
50     private Stack<ClassFile> callStack = new Stack<ClassFile>();
51
52     private HashSet<String JavaDoc> closure = new HashSet<String JavaDoc>();
53
54     private HashSet<String JavaDoc> nativeMethods = new HashSet<String JavaDoc>();
55
56     //map of refencing path to list of not found classes.
57
private Map<String JavaDoc, List<String JavaDoc>> failed = new HashMap<String JavaDoc, List<String JavaDoc>>();
58
59     private static final String JavaDoc myClassName = "BCELClosureCompilerImpl"; // NOI18N
60

61     /**
62      * @param loader the ClassFileLoader that is used to load the referenced
63      * classes.
64      */

65     public BCELClosureCompilerImpl(ClassFileLoader loader) {
66         super(loader);
67     }
68
69     //See corresponding method of ClosureCompiler for javadocs
70
public boolean buildClosure(String JavaDoc className) {
71         logger.entering(myClassName, "buildClosure", className); // NOI18N
72
ClassFile cf;
73         if (!needToBuildClosure(className))
74             return true;
75         try {
76             cf = loader.load(className);
77         } catch (IOException JavaDoc e) {
78             handleFailure(className);
79             return false;
80         }
81         return buildClosure(cf);
82     }
83
84     /**
85      * @param cf class file whose closure needs to be computed. The behavior is
86      * same as the other buildClosure() method.
87      */

88     private boolean buildClosure(ClassFile cf) {
89         boolean result = true;
90         callStack.push(cf);
91         if (needToBuildClosure(cf.getName())) {
92             visitedClasses.add(cf.getName());
93             Collection<String JavaDoc> names = cf.getAllReferencedClassNames();
94             closure.addAll(names);
95             // TODO: We should not be doing this here. Its just a quick &
96
// dirty solution.
97
for(Method m : cf.getMethods()) {
98                 if(m.isNative()) {
99                     final String JavaDoc methodDesc =
100                             m.getOwningClass().getName()+ "." + m.getName(); // NOI18N
101
nativeMethods.add(methodDesc);
102                 }
103             }
104             for (Iterator i = names.iterator(); i.hasNext();) {
105                 String JavaDoc nextExternalName = (String JavaDoc) i.next();
106                 if (!needToBuildClosure(nextExternalName)) continue;
107                 ClassFile next;
108                 try {
109                     next = loader.load(nextExternalName);
110                 } catch (IOException JavaDoc e) {
111                     result = false;
112                     handleFailure(nextExternalName);
113                     continue;
114                 }
115                 boolean newresult = buildClosure(next);//recurssive call
116
result = newresult && result;
117             }
118         }
119         callStack.pop();
120         return result;
121     }
122
123     private void handleFailure(String JavaDoc referencedClass) {
124         String JavaDoc referencingPath = "";
125         try {
126             StringBuilder JavaDoc referencingPathBuffer = new StringBuilder JavaDoc();
127             for (Iterator i = callStack.iterator(); i.hasNext();) {
128                 if (referencingPathBuffer.length() != 0)
129                     referencingPathBuffer.append(File.separator);
130                 referencingPathBuffer.append(((ClassFile) i.next()).getName());
131             }
132             referencingPath = referencingPathBuffer.toString();
133         } catch (EmptyStackException e) {
134         }
135         logger.finer(
136                 "Could not locate " + referencingPath + File.separator + // NOI18N
137
referencedClass);
138         List<String JavaDoc> failedList = failed.get(referencingPath);
139         if (failedList == null) {
140             failedList = new ArrayList<String JavaDoc>();
141             failed.put(referencingPath, failedList);
142         }
143         failedList.add(referencedClass);
144     }
145
146     //See corresponding method of ClosureCompiler for javadocs
147
public Collection getClosure() {
148         return Collections.unmodifiableCollection(closure);
149     }
150
151     //See corresponding method of ClosureCompiler for javadocs
152
public Map getFailed() {
153         return Collections.unmodifiableMap(failed);
154     }
155     
156     /**
157      * Reset the closure for next closure computation.
158      * Clear the internal cache. It includes the result it has collected since
159      * last reset(). But it does not clear the excludedd list. If you want to
160      * reset the excluded list, create a new ClosureCompiler.
161      */

162     public void reset() {
163         closure.clear();
164         visitedClasses.clear();
165         failed.clear();
166         nativeMethods.clear();
167     }
168
169     public Collection<String JavaDoc> getNativeMethods() {
170         return Collections.unmodifiableCollection(nativeMethods);
171     }
172
173     public String JavaDoc toString() {
174         StringBuilder JavaDoc sb=new StringBuilder JavaDoc();
175         if(logger.isLoggable(Level.FINER)){
176             sb.append("\n<Closure>"); // NOI18N
177

178             sb.append("\n\t<ExcludedClasses>"); // NOI18N
179
for(Iterator i=excludedClasses.iterator(); i.hasNext();) {
180                 sb.append("\n\t\t"); // NOI18N
181
sb.append((String JavaDoc)i.next());
182             }
183             sb.append("\n\t</ExcludedClasses>"); // NOI18N
184

185             sb.append("\n\t<ExcludedPackages>"); // NOI18N
186
for(Iterator i=excludedPackages.iterator(); i.hasNext();){
187                 sb.append("\n\t\t"); // NOI18N
188
sb.append((String JavaDoc)i.next());
189             }
190             sb.append("\n\t</ExcludedPackages>"); // NOI18N
191

192             sb.append("\n\t<ExcludedPatterns>"); // NOI18N
193
for(Iterator i=excludedPatterns.iterator(); i.hasNext();){
194                 sb.append("\n\t\t"); // NOI18N
195
sb.append((String JavaDoc)i.next());
196             }
197             sb.append("\n\t</ExcludedPatterns>"); // NOI18N
198

199             sb.append("\n\t<Classes>"); // NOI18N
200
for(Iterator i=closure.iterator(); i.hasNext();){
201                 sb.append("\n\t\t"); // NOI18N
202
sb.append((String JavaDoc)i.next());
203             }
204             sb.append("\n\t</Classes>"); // NOI18N
205
}
206         sb.append("\n\t<Failed>"); // NOI18N
207
for(Iterator i=failed.entrySet().iterator(); i.hasNext();) {
208             Map.Entry referencingPathToFailedList=(Map.Entry)i.next();
209             sb.append("\n\t\t"); // NOI18N
210
sb.append("<ReferencingPath>"); // NOI18N
211
sb.append("\n\t\t\t"); // NOI18N
212
sb.append(referencingPathToFailedList.getKey());
213             sb.append("\n\t\t"); // NOI18N
214
sb.append("</ReferencingPath>"); // NOI18N
215
sb.append("\n\t\t"); // NOI18N
216
sb.append("<Classes>"); // NOI18N
217
for(Iterator iii=((List)referencingPathToFailedList.getValue()).iterator(); iii.hasNext();){
218                 sb.append("\n\t\t\t"); // NOI18N
219
sb.append((String JavaDoc)iii.next());
220             }
221             sb.append("\n\t\t"); // NOI18N
222
sb.append("</Classes>"); // NOI18N
223
}
224         sb.append("\n\t</Failed>"); // NOI18N
225

226         sb.append("\n\t<NativeMethods>"); // NOI18N
227
for(String JavaDoc s : nativeMethods) {
228             sb.append("\n\t\t"); // NOI18N
229
sb.append(s);
230         }
231         sb.append("\n\t</NativeMethods>"); // NOI18N
232

233         if(logger.isLoggable(Level.FINER)){
234             sb.append("\n</Closure>"); // NOI18N
235
}
236         return sb.toString();
237     }
238
239 }
240
Popular Tags