KickJava   Java API By Example, From Geeks To Geeks.

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


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.io.File JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30 import java.lang.ref.WeakReference JavaDoc;
31 import java.net.MalformedURLException JavaDoc;
32 import java.net.URL JavaDoc;
33 import java.net.URLClassLoader JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.StringTokenizer JavaDoc;
38 import java.util.logging.Level JavaDoc;
39 import java.util.logging.Logger JavaDoc;
40
41 /**
42  * *This is a factory for {@link ASMClassFile}. This is not a public class, as
43  * I expect users to use {@link ClassFileLoaderFactory} interface. This class
44  * internally uses the the standard Java ClassLoader to load the resource and
45  * construct ASMClassFile object out of it.
46  *
47  * @author Sanjeeb.Sahoo@Sun.COM
48  */

49 class ASMClassFileLoader implements ClassFileLoader {
50
51     private ClassLoader JavaDoc cl;
52     private static String JavaDoc resourceBundleName = "com.sun.enterprise.tools.verifier.apiscan.LocalStrings";
53     private static Logger JavaDoc logger = Logger.getLogger("apiscan.classfile", resourceBundleName); // NOI18N
54
private final static String JavaDoc myClassName = "ASMClassFileLoader"; // NOI18N
55
// cache of already loaded classes
56
private Map JavaDoc<String JavaDoc, WeakReference JavaDoc<ClassFile>> loadedClassesCache =
57             new HashMap JavaDoc<String JavaDoc, WeakReference JavaDoc<ClassFile>>();
58     /**
59      * Creates a new instance of ASMClassFileLoader.
60      *
61      * @param cp that will be used to create a new java.net.URLClassLoader. In
62      * subsequent load operations, this classloader will be used.
63      */

64     public ASMClassFileLoader(String JavaDoc cp) {
65         ArrayList JavaDoc<URL JavaDoc> urls = new ArrayList JavaDoc<URL JavaDoc>();
66         for (StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(cp, File.pathSeparator);
67              st.hasMoreTokens();) {
68             String JavaDoc entry = st.nextToken();
69             try {
70                 urls.add(new File JavaDoc(entry).toURI().toURL());
71             } catch (MalformedURLException JavaDoc e) {
72                 logger.logp(Level.WARNING, myClassName, "init<>", getClass().getName() + ".exception1", new Object JavaDoc[]{entry});
73                 logger.log(Level.WARNING, "", e);
74             }
75         }
76         //We do not want system class loader or even extension class loadera s our parent.
77
//We want only boot class loader as our parent. Boot class loader is represented as null.
78
cl = new URLClassLoader JavaDoc((URL JavaDoc[]) urls.toArray(new URL JavaDoc[0]), null);
79     }
80
81     /**
82      * Creates a new instance of ASMClassFileLoader.
83      *
84      * @param cl is the classloader that will be used in subsequent load
85      * operations.
86      */

87     public ASMClassFileLoader(ClassLoader JavaDoc cl) {
88         this.cl = cl;
89     }
90
91     //See corresponding method of ClassFileLoader
92
public ClassFile load(String JavaDoc externalClassName) throws IOException JavaDoc {
93         logger.entering("ASMClassFileLoader", "load", externalClassName); // NOI18N
94
WeakReference JavaDoc<ClassFile> cachedCF = loadedClassesCache.get(externalClassName);
95         if(cachedCF!=null){
96             ClassFile cf = cachedCF.get();
97             if(cf!=null){
98                 return cf;
99             } else {
100                 logger.logp(Level.FINE, "ASMClassFileLoader", "load", // NOI18N
101
"{0} has been garbage collected from cache!", externalClassName); // NOI18N
102
}
103         }
104         return load0(externalClassName);
105     }
106
107     private ClassFile load0(String JavaDoc externalClassName) throws IOException JavaDoc {
108         //URLClassLoader library expects me to pass in internal form.
109
String JavaDoc internalClassName = externalClassName.replace('.', '/');
110         InputStream JavaDoc is = cl.getResourceAsStream(internalClassName + ".class");
111         //URLClassLoader returns null if resource is not found.
112
if (is == null) throw new IOException JavaDoc(
113                 "Not able to load " + internalClassName + ".class");
114         try {
115             ClassFile cf = new ASMClassFile(is);
116             matchClassSignature(cf, externalClassName);
117             loadedClassesCache.put(externalClassName,
118                     new WeakReference JavaDoc<ClassFile>(cf));
119             return cf;
120         } finally {
121             is.close();
122         }
123
124     }
125
126     //This method is neede to be protected against users who are passing us
127
//internal class names instead of external class names or
128
//when the file actually represents some other class, but it isnot
129
//available in in proper package hierarchy.
130
private void matchClassSignature(ClassFile cf, String JavaDoc externalClassName)
131             throws IOException JavaDoc {
132         String JavaDoc nameOfLoadedClass = cf.getName();
133         if (!nameOfLoadedClass.equals(externalClassName)) {
134             throw new IOException JavaDoc(externalClassName + ".class represents " +
135                     cf.getName() +
136                     ". Perhaps your package name is incorrect or you passed the " +
137                     "name using internal form instead of using external form.");
138         }
139     }
140 }
141
Popular Tags