KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > mdr > handlers > MDRClassLoader


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.mdr.handlers;
20
21 import org.netbeans.api.mdr.JMIStreamFactory;
22 import org.netbeans.lib.jmi.mapping.ClassFileMapper;
23 import org.netbeans.mdr.handlers.gen.TagSupport;
24 import org.netbeans.mdr.storagemodel.StorableObject;
25 import org.netbeans.mdr.util.DebugException;
26 import org.netbeans.mdr.util.Logger;
27 import org.netbeans.mdr.util.MOFConstants;
28 import java.io.ByteArrayOutputStream JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.io.OutputStream JavaDoc;
31 import java.net.URL JavaDoc;
32 import java.security.AllPermission JavaDoc;
33 import java.security.PermissionCollection JavaDoc;
34 import java.security.Permissions JavaDoc;
35 import java.security.ProtectionDomain JavaDoc;
36 import java.util.*;
37
38 /**
39  *
40  * @author Martin Matula
41  */

42 class MDRClassLoader extends ClassLoader JavaDoc {
43     private static final ProtectionDomain JavaDoc pd;
44     private static final HashMap suffixes;
45     private final JMIStreamFactory streamFactory = new StreamFactory();
46
47     static {
48         PermissionCollection JavaDoc pc = new Permissions JavaDoc();
49         pc.add(new AllPermission JavaDoc());
50         pd = new ProtectionDomain JavaDoc(null, pc);
51
52         suffixes = new HashMap(3, 1);
53         suffixes.put(MOFConstants.SH_MODEL_CLASS, MOFConstants.SH_MODEL_CLASS);
54         suffixes.put(MOFConstants.SH_MODEL_PACKAGE, MOFConstants.SH_MODEL_PACKAGE);
55         suffixes.put(MOFConstants.SH_MODEL_ASSOCIATION, ""); //NOI18N
56
}
57
58     private final ClassLoaderProvider provider;
59     private Delegator parent;
60
61     private final HashMap packages = new HashMap();
62
63     // class caches
64
private final HashMap proxyClasses = new HashMap();
65     private final HashMap instanceClasses = new HashMap();
66
67     /** Creates a new instance of MDRClassLoader */
68     MDRClassLoader(ClassLoaderProvider provider) {
69         super();
70         this.provider = provider;
71     }
72
73     private Delegator getDelegator() {
74         if (parent == null) {
75             parent = new Delegator(provider);
76         }
77         return (parent = parent.getDelegator());
78     }
79
80     protected Class JavaDoc defineClass(String JavaDoc className, byte[] classFile) {
81         Class JavaDoc result;
82         // try to define class using ClassLoaderProvider
83
// if the method returned null, define the class in this classloader
84
if (provider == null || (result = provider.defineClass(className, classFile))== null) {
85             int i = className.lastIndexOf('.');
86             String JavaDoc pkgName = className.substring(0, i);
87             Package JavaDoc pkg = getPackage(pkgName);
88             if (pkg == null) {
89                 definePackage(pkgName, null, null, null, null, null, null, null);
90             }
91             result = defineClass(className, classFile, 0, classFile.length, pd);
92         }
93         return result;
94     }
95
96     /** Resolves JMI interface for a repository object represented by a storable.
97      * If the interface cannot be found on the classpath, it will be dynamicaly
98      * generated based on the metamodel.
99      * @param s storable object representing the repository object.
100      * @param proxy indicates whether the interface to be generated corresponds to a proxy
101      * @return JMI interface for a given object.
102      */

103     protected Class JavaDoc resolveInterface(StorableObject s, boolean proxy) {
104         String JavaDoc key = s.getMofId().toString();
105         Map classes = proxy ? proxyClasses : instanceClasses;
106         Class JavaDoc result = null;
107
108         // [PENDING] synchronize on repository rather than on particular storages
109
synchronized (s.getMdrStorage().getStorageByMofId(s.getMofId())) {
110             result = (Class JavaDoc) classes.get(key);
111             if (result == null) try {
112                 String JavaDoc metaName = (String JavaDoc) s.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
113                 String JavaDoc suffix = proxy ? (String JavaDoc) suffixes.get(metaName) : ""; //NOI18N
114
String JavaDoc ifcName = TagSupport.getTypeFullName(s) + suffix;
115                 try {
116                     result = loadClass(ifcName);
117                 } catch (ClassNotFoundException JavaDoc e) {
118                     Logger.getDefault().log(Logger.WARNING, "Metamodel specific JMI class " + ifcName + " not found. Using bytecode generation to create it.");
119                     new ClassFileMapper(streamFactory).visitRefBaseObject(s.getMdrStorage().getRepository().getHandler(s.getOutermostPackage()));
120                     result = loadClass(ifcName);
121                 }
122                 classes.put(key, result);
123             } catch (Exception JavaDoc e) {
124                 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
125             }
126         }
127         return result;
128     }
129
130     protected Class JavaDoc loadClass(String JavaDoc name, boolean resolve) throws ClassNotFoundException JavaDoc {
131         Class JavaDoc c = findLoadedClass(name);
132         if (c == null) {
133             try {
134                 c = getDelegator().accessibleLoadClass(name, false);
135             } catch (ClassNotFoundException JavaDoc e) {
136                 // this will always throw exception in this implementation
137
// (all the classes should be loaded by calling defineClass directly)
138
c = findClass(name);
139             }
140         }
141         if (resolve) {
142             resolveClass(c);
143         }
144         return c;
145     }
146
147     public URL JavaDoc getResource(String JavaDoc name) {
148         URL JavaDoc url;
149         url = getDelegator().getResource(name);
150         if (url == null) {
151             // will always return null in this implementation
152
url = findResource(name);
153         }
154         return url;
155     }
156
157     protected Enumeration findResources(String JavaDoc name) throws IOException JavaDoc {
158         return getDelegator().getResources(name);
159     }
160
161     protected Package JavaDoc getPackage(String JavaDoc name) {
162     synchronized (packages) {
163         Package JavaDoc pkg = (Package JavaDoc) packages.get(name);
164         if (pkg == null) {
165                 pkg = getDelegator().accessibleGetPackage(name);
166         if (pkg != null) {
167             packages.put(name, pkg);
168         }
169         }
170         return pkg;
171     }
172     }
173
174     protected Package JavaDoc[] getPackages() {
175         Map map;
176         synchronized (packages) {
177             map = (Map) packages.clone();
178         }
179         Package JavaDoc[] pkgs;
180         pkgs = getDelegator().accessibleGetPackages();
181         if (pkgs != null) {
182             for (int i = 0; i < pkgs.length; i++) {
183                 String JavaDoc pkgName = pkgs[i].getName();
184                 if (map.get(pkgName) == null) {
185                     map.put(pkgName, pkgs[i]);
186                 }
187             }
188         }
189         return (Package JavaDoc[]) map.values().toArray(new Package JavaDoc[map.size()]);
190     }
191
192     protected Package JavaDoc definePackage(String JavaDoc name, String JavaDoc specTitle, String JavaDoc specVersion, String JavaDoc specVendor, String JavaDoc implTitle, String JavaDoc implVersion, String JavaDoc implVendor, URL JavaDoc sealBase) throws IllegalArgumentException JavaDoc {
193         synchronized (packages) {
194             Package JavaDoc pkg = getPackage(name);
195             if (pkg != null) {
196                 throw new IllegalArgumentException JavaDoc(name);
197             }
198             pkg = super.definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase);
199             packages.put(name, pkg);
200             return pkg;
201         }
202     }
203
204     private final class ClassOutputStream extends ByteArrayOutputStream JavaDoc {
205         private final String JavaDoc className;
206
207         ClassOutputStream(List pkg, String JavaDoc className) {
208             StringBuffer JavaDoc temp = new StringBuffer JavaDoc(32);
209             for (Iterator it = pkg.iterator(); it.hasNext();) {
210                 temp.append(it.next() + ".");
211             }
212             temp.append(className);
213             this.className = temp.toString();
214         }
215
216         public void close() throws IOException JavaDoc {
217             try {
218                 loadClass(className);
219             } catch (ClassNotFoundException JavaDoc e) {
220                 Logger.getDefault().log("Generating bytecode for JMI class: " + className);
221                 defineClass(className, this.toByteArray());
222             }
223             super.close();
224         }
225     }
226
227     private static final class Delegator extends ClassLoader JavaDoc {
228         private final ClassLoaderProvider provider;
229         private final ClassLoader JavaDoc parent;
230
231         Delegator(ClassLoaderProvider provider) {
232             super(provider == null ? Delegator.class.getClassLoader() : provider.getClassLoader());
233             this.parent = (provider == null ? Delegator.class.getClassLoader() : provider.getClassLoader());
234             this.provider = provider;
235         }
236
237         Delegator getDelegator() {
238             return ((provider == null || provider.getClassLoader() == parent) ? this : new Delegator(provider));
239         }
240
241         Class JavaDoc accessibleLoadClass(String JavaDoc name, boolean param) throws ClassNotFoundException JavaDoc {
242             return this.loadClass(name, param);
243         }
244
245         Package JavaDoc accessibleGetPackage(String JavaDoc name) {
246             return this.getPackage(name);
247         }
248
249         Package JavaDoc[] accessibleGetPackages() {
250             return this.getPackages();
251         }
252     }
253
254     private final class StreamFactory extends JMIStreamFactory {
255         public OutputStream JavaDoc createStream(List pkg, String JavaDoc className, String JavaDoc extension) throws IOException JavaDoc {
256             if (!JMIStreamFactory.EXT_CLASS.equals(extension)) {
257                 throw new IllegalArgumentException JavaDoc("ERROR: Wrong extension of the generated data: " + extension + ". Only bytecode data (i.e. extension \"class\" is accepted.");
258             }
259             return new ClassOutputStream(pkg, className);
260         }
261     }
262 }
263
Popular Tags