KickJava   Java API By Example, From Geeks To Geeks.

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


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 package com.sun.enterprise.tools.verifier.apiscan.classfile;
26
27 import java.util.*;
28 import java.util.logging.Logger JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.io.File JavaDoc;
31
32 /**
33  * This is single most important class of the apiscan package. This class is
34  * used to compute the complete closure of a set of classes. It uses {@link
35  * ClassFile} to find out dependencies of a class. For each references class
36  * name, it loads the corresponding ClassFile using the ClassFileLoader passed
37  * to it in constructor. Then it recurssively computes the dependencies until it
38  * visits either Java primitive classes or the class name matches the exclude
39  * list. Example of using this class is given below...
40  * <blockquote><pre>
41  * String classpath="your own classpath";
42  * ClassFileLoader cfl=ClassFileLoaderFactory.newInstance(new
43  * Object[]{classpath});
44  * ClosureCompilerImpl cc=new ClosureCompilerImpl(cfl);
45  * cc.addExcludePattern("java.");//exclude all classes that start with java.
46  * Most of the J2SE classes will be excluded thus.
47   * cc.addExcludePattern("javax.");//Most of the J2EE classes can be excluded
48  * like this.
49  * cc.addExcludePackage("org.omg.CORBA");//Exclude classes whose package name is
50  * org.omg.CORBA
51  * cc.addExcludeClass("mypackage.Foo");//Exclude class whose name is
52  * myPackage.Foo
53  * boolean successful=cc.buildClosure("a.b.MyEjb");
54  * successful=cc.buildClosure("a.b.YourEjb") && successful; //note the order of
55  * &&.
56  * Collection closure=cc.getClosure();//now closure contains the union of
57  * closure for the two classes.
58  * Map failed=cc.getFailed();//now failure contains the union of failures for
59  * the two classes.
60  * cc.reset();//clear the results collected so far so that we can start afresh.
61  * //Now you can again start computing closure of another set of classes.
62  * //The excluded stuff are still valid.
63  * </pre></blockquote>
64  *
65  * @author Sanjeeb.Sahoo@Sun.COM
66  */

67 public class ClosureCompilerImpl implements ClosureCompiler {
68
69    /*
70     * BRIDGE design pattern.
71     * This is an abstraction. It delegates to an implementation.
72     * It is bound to an implementation at runtime. See the constructor.
73     */

74
75     /**
76      * an implementation to whom this abstraction delegates.
77      * refer to bridge design pattern.
78      */

79     private ClosureCompilerImplBase imp;
80     private static String JavaDoc resourceBundleName = "com.sun.enterprise.tools.verifier.apiscan.LocalStrings";
81     private static Logger JavaDoc logger = Logger.getLogger("apiscan.classfile", resourceBundleName); // NOI18N
82
private static final String JavaDoc myClassName = "ClosureCompilerImpl"; // NOI18N
83

84     /**
85      * @param loader the ClassFileLoader that is used to load the referenced
86      * classes.
87      */

88     public ClosureCompilerImpl(ClassFileLoader loader) {
89         /*
90          * See how it binds to a runtime implementation
91          * TODO: Ideally we should introduce an AbstractFactory for
92          * both ClassFileLoader & ClassClosureCompiler product types.
93          */

94         if(loader instanceof ASMClassFileLoader){
95             imp = new ASMClosureCompilerImpl(loader);
96         } else if(loader instanceof BCELClassFileLoader ||
97                 loader instanceof BCELClassFileLoader1) {
98             imp = new BCELClosureCompilerImpl(loader);
99         } else {
100             throw new RuntimeException JavaDoc("Unknown loader type [" + loader + "]");
101         }
102     }
103
104     /**
105      * I don't expect this constructor to be used. Only defined for
106      * testing purpose.
107      * @param imp the implementation in the bridge design pattern.
108      */

109     public ClosureCompilerImpl(ClosureCompilerImplBase imp) {
110         this.imp = imp;
111     }
112
113     /**
114      * @param className the class name to be excluded from closure
115      * computation. It is in the external class name format
116      * (i.e. java.util.Map$Entry instead of java.util.Map.Entry).
117      * When the closure compiler sees a class matches this
118      * name, it does not try to compute its closure any
119      * more. It merely adds this name to the closure. So the
120      * final closure will contain this class name, but not
121      * its dependencies.
122      */

123     public void addExcludedClass(String JavaDoc className) {
124         imp.addExcludedClass(className);
125     }
126
127     //takes in external format, i.e. java.util
128
/**
129      * @param pkgName the package name of classes to be excluded from
130      * closure computation. It is in the external format
131      * (i.e. java.lang (See no trailing '.'). When the
132      * closure compiler sees a class whose package name
133      * matches this name, it does not try to compute the
134      * closure of that class any more. It merely adds that
135      * class name to the closure. So the final closure will
136      * contain that class name, but not its dependencies.
137      */

138     public void addExcludedPackage(String JavaDoc pkgName) {
139         imp.addExcludedPackage(pkgName);
140     }
141
142     /**
143      * @param pattern the pattern for the names of classes to be excluded from
144      * closure computation. It is in the external format (i.e.
145      * org.apache.). When the closure compiler sees a class whose
146      * name begins with this pattern, it does not try to compute
147      * the closure of that class any more. It merely adds that
148      * class name to the closure. So the final closure will
149      * contain that class name, but not its dependencies. Among
150      * all the excluded list, it is given the lowest priority in
151      * search order.
152      */

153     public void addExcludedPattern(String JavaDoc pattern) {
154         imp.addExcludedPattern(pattern);
155     }
156
157     //See corresponding method of ClosureCompiler for javadocs
158
public boolean buildClosure(String JavaDoc className) {
159         logger.entering(myClassName, "buildClosure", className); // NOI18N
160
return imp.buildClosure(className);
161     }
162
163     /**
164      * @param jar whose classes it will try to build closure of. This is a
165      * convenience method which iterates over all the entries in a
166      * jar file and computes their closure.
167      */

168     public boolean buildClosure(java.util.jar.JarFile JavaDoc jar) throws IOException JavaDoc {
169         return imp.buildClosure(jar);
170     }
171
172     //See corresponding method of ClosureCompiler for javadocs
173
public Collection getClosure() {
174         return imp.getClosure();
175     }
176
177     //See corresponding method of ClosureCompiler for javadocs
178
public Map getFailed() {
179         return imp.getFailed();
180     }
181
182     /**
183      * Reset the closure for next closure computation.
184      * Clear the internal cache. It includes the result it has collected since
185      * last reset(). But it does not clear the excludedd list. If you want to
186      * reset the excluded list, create a new ClosureCompiler.
187      */

188     public void reset() {
189         imp.reset();
190     }
191
192     public Collection<String JavaDoc> getNativeMethods() {
193         return imp.getNativeMethods();
194     }
195
196     public String JavaDoc toString() {
197         return imp.toString();
198     }
199
200     public static void main(String JavaDoc[] args) {
201         if (args.length < 2) {
202             System.out.println(
203                     "Usage : java " + com.sun.enterprise.tools.verifier.apiscan.classfile.ClosureCompilerImpl.class.getName() + // NOI18N
204
" <classpath> <external class name(s)>"); // NOI18N
205
System.out.println("Example: to find the closure of " + // NOI18N
206
"mypkg.MySessionBean which is packaged in myejb.jar run\n" + // NOI18N
207
" java " + com.sun.enterprise.tools.verifier.apiscan.classfile.ClosureCompilerImpl.class.getName() + // NOI18N
208
" path_to_j2ee.jar"+File.pathSeparator+"path_to_myejb.jar"+ // NOI18N
209
" mypkg.MySessionBean"); // NOI18N
210
System.exit(1);
211         }
212
213         String JavaDoc cp=args[0];
214         System.out.println("Using classpath " + cp); // NOI18N
215
ClassFileLoader cfl = ClassFileLoaderFactory.newInstance(
216                 new Object JavaDoc[]{cp});
217         ClosureCompilerImpl closure = new ClosureCompilerImpl(cfl);
218         closure.addExcludedPattern("java."); // NOI18N
219
for (int i = 1; i < args.length; i++) {
220             String JavaDoc clsName = args[i];
221             System.out.println("Building closure for " + clsName); // NOI18N
222
closure.reset();
223             closure.buildClosure(clsName);
224             System.out.println("The closure is [" + closure+"\n]"); // NOI18N
225
}
226     }
227
228 }
229
Popular Tags