|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.mdr.handlers; import org.netbeans.api.mdr.JMIStreamFactory; import org.netbeans.lib.jmi.mapping.ClassFileMapper; import org.netbeans.mdr.handlers.gen.TagSupport; import org.netbeans.mdr.storagemodel.StorableObject; import org.netbeans.mdr.util.DebugException; import org.netbeans.mdr.util.Logger; import org.netbeans.mdr.util.MOFConstants; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URL; import java.security.AllPermission; import java.security.PermissionCollection; import java.security.Permissions; import java.security.ProtectionDomain; import java.util.*; /** * * @author Martin Matula */ class MDRClassLoader extends ClassLoader { private static final ProtectionDomain pd; private static final HashMap suffixes; private final JMIStreamFactory streamFactory = new StreamFactory(); static { PermissionCollection pc = new Permissions(); pc.add(new AllPermission()); pd = new ProtectionDomain(null, pc); suffixes = new HashMap(3, 1); suffixes.put(MOFConstants.SH_MODEL_CLASS, MOFConstants.SH_MODEL_CLASS); suffixes.put(MOFConstants.SH_MODEL_PACKAGE, MOFConstants.SH_MODEL_PACKAGE); suffixes.put(MOFConstants.SH_MODEL_ASSOCIATION, ""); //NOI18N } private final ClassLoaderProvider provider; private Delegator parent; private final HashMap packages = new HashMap(); // class caches private final HashMap proxyClasses = new HashMap(); private final HashMap instanceClasses = new HashMap(); /** Creates a new instance of MDRClassLoader */ MDRClassLoader(ClassLoaderProvider provider) { super(); this.provider = provider; } private Delegator getDelegator() { if (parent == null) { parent = new Delegator(provider); } return (parent = parent.getDelegator()); } protected Class defineClass(String className, byte[] classFile) { Class result; // try to define class using ClassLoaderProvider // if the method returned null, define the class in this classloader if (provider == null || (result = provider.defineClass(className, classFile))== null) { int i = className.lastIndexOf('.'); String pkgName = className.substring(0, i); Package pkg = getPackage(pkgName); if (pkg == null) { definePackage(pkgName, null, null, null, null, null, null, null); } result = defineClass(className, classFile, 0, classFile.length, pd); } return result; } /** Resolves JMI interface for a repository object represented by a storable. * If the interface cannot be found on the classpath, it will be dynamicaly * generated based on the metamodel. * @param s storable object representing the repository object. * @param proxy indicates whether the interface to be generated corresponds to a proxy * @return JMI interface for a given object. */ protected Class resolveInterface(StorableObject s, boolean proxy) { String key = s.getMofId().toString(); Map classes = proxy ? proxyClasses : instanceClasses; Class result = null; // [PENDING] synchronize on repository rather than on particular storages synchronized (s.getMdrStorage().getStorageByMofId(s.getMofId())) { result = (Class) classes.get(key); if (result == null) try { String metaName = (String) s.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME); String suffix = proxy ? (String) suffixes.get(metaName) : ""; //NOI18N String ifcName = TagSupport.getTypeFullName(s) + suffix; try { result = loadClass(ifcName); } catch (ClassNotFoundException e) { Logger.getDefault().log(Logger.WARNING, "Metamodel specific JMI class " + ifcName + " not found. Using bytecode generation to create it."); new ClassFileMapper(streamFactory).visitRefBaseObject(s.getMdrStorage().getRepository().getHandler(s.getOutermostPackage())); result = loadClass(ifcName); } classes.put(key, result); } catch (Exception e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } } return result; } protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class c = findLoadedClass(name); if (c == null) { try { c = getDelegator().accessibleLoadClass(name, false); } catch (ClassNotFoundException e) { // this will always throw exception in this implementation // (all the classes should be loaded by calling defineClass directly) c = findClass(name); } } if (resolve) { resolveClass(c); } return c; } public URL getResource(String name) { URL url; url = getDelegator().getResource(name); if (url == null) { // will always return null in this implementation url = findResource(name); } return url; } protected Enumeration findResources(String name) throws IOException { return getDelegator().getResources(name); } protected Package getPackage(String name) { synchronized (packages) { Package pkg = (Package) packages.get(name); if (pkg == null) { pkg = getDelegator().accessibleGetPackage(name); if (pkg != null) { packages.put(name, pkg); } } return pkg; } } protected Package[] getPackages() { Map map; synchronized (packages) { map = (Map) packages.clone(); } Package[] pkgs; pkgs = getDelegator().accessibleGetPackages(); if (pkgs != null) { for (int i = 0; i < pkgs.length; i++) { String pkgName = pkgs[i].getName(); if (map.get(pkgName) == null) { map.put(pkgName, pkgs[i]); } } } return (Package[]) map.values().toArray(new Package[map.size()]); } protected Package definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) throws IllegalArgumentException { synchronized (packages) { Package pkg = getPackage(name); if (pkg != null) { throw new IllegalArgumentException(name); } pkg = super.definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase); packages.put(name, pkg); return pkg; } } private final class ClassOutputStream extends ByteArrayOutputStream { private final String className; ClassOutputStream(List pkg, String className) { StringBuffer temp = new StringBuffer(32); for (Iterator it = pkg.iterator(); it.hasNext();) { temp.append(it.next() + "."); } temp.append(className); this.className = temp.toString(); } public void close() throws IOException { try { loadClass(className); } catch (ClassNotFoundException e) { Logger.getDefault().log("Generating bytecode for JMI class: " + className); defineClass(className, this.toByteArray()); } super.close(); } } private static final class Delegator extends ClassLoader { private final ClassLoaderProvider provider; private final ClassLoader parent; Delegator(ClassLoaderProvider provider) { super(provider == null ? Delegator.class.getClassLoader() : provider.getClassLoader()); this.parent = (provider == null ? Delegator.class.getClassLoader() : provider.getClassLoader()); this.provider = provider; } Delegator getDelegator() { return ((provider == null || provider.getClassLoader() == parent) ? this : new Delegator(provider)); } Class accessibleLoadClass(String name, boolean param) throws ClassNotFoundException { return this.loadClass(name, param); } Package accessibleGetPackage(String name) { return this.getPackage(name); } Package[] accessibleGetPackages() { return this.getPackages(); } } private final class StreamFactory extends JMIStreamFactory { public OutputStream createStream(List pkg, String className, String extension) throws IOException { if (!JMIStreamFactory.EXT_CLASS.equals(extension)) { throw new IllegalArgumentException("ERROR: Wrong extension of the generated data: " + extension + ". Only bytecode data (i.e. extension \"class\" is accepted."); } return new ClassOutputStream(pkg, className); } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.