1 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 ; 29 import java.io.IOException ; 30 import java.io.OutputStream ; 31 import java.net.URL ; 32 import java.security.AllPermission ; 33 import java.security.PermissionCollection ; 34 import java.security.Permissions ; 35 import java.security.ProtectionDomain ; 36 import java.util.*; 37 38 42 class MDRClassLoader extends ClassLoader { 43 private static final ProtectionDomain pd; 44 private static final HashMap suffixes; 45 private final JMIStreamFactory streamFactory = new StreamFactory(); 46 47 static { 48 PermissionCollection pc = new Permissions (); 49 pc.add(new AllPermission ()); 50 pd = new ProtectionDomain (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, ""); } 57 58 private final ClassLoaderProvider provider; 59 private Delegator parent; 60 61 private final HashMap packages = new HashMap(); 62 63 private final HashMap proxyClasses = new HashMap(); 65 private final HashMap instanceClasses = new HashMap(); 66 67 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 defineClass(String className, byte[] classFile) { 81 Class result; 82 if (provider == null || (result = provider.defineClass(className, classFile))== null) { 85 int i = className.lastIndexOf('.'); 86 String pkgName = className.substring(0, i); 87 Package 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 103 protected Class resolveInterface(StorableObject s, boolean proxy) { 104 String key = s.getMofId().toString(); 105 Map classes = proxy ? proxyClasses : instanceClasses; 106 Class result = null; 107 108 synchronized (s.getMdrStorage().getStorageByMofId(s.getMofId())) { 110 result = (Class ) classes.get(key); 111 if (result == null) try { 112 String metaName = (String ) s.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME); 113 String suffix = proxy ? (String ) suffixes.get(metaName) : ""; String ifcName = TagSupport.getTypeFullName(s) + suffix; 115 try { 116 result = loadClass(ifcName); 117 } catch (ClassNotFoundException 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 e) { 124 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 125 } 126 } 127 return result; 128 } 129 130 protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { 131 Class c = findLoadedClass(name); 132 if (c == null) { 133 try { 134 c = getDelegator().accessibleLoadClass(name, false); 135 } catch (ClassNotFoundException e) { 136 c = findClass(name); 139 } 140 } 141 if (resolve) { 142 resolveClass(c); 143 } 144 return c; 145 } 146 147 public URL getResource(String name) { 148 URL url; 149 url = getDelegator().getResource(name); 150 if (url == null) { 151 url = findResource(name); 153 } 154 return url; 155 } 156 157 protected Enumeration findResources(String name) throws IOException { 158 return getDelegator().getResources(name); 159 } 160 161 protected Package getPackage(String name) { 162 synchronized (packages) { 163 Package pkg = (Package ) 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 [] getPackages() { 175 Map map; 176 synchronized (packages) { 177 map = (Map) packages.clone(); 178 } 179 Package [] pkgs; 180 pkgs = getDelegator().accessibleGetPackages(); 181 if (pkgs != null) { 182 for (int i = 0; i < pkgs.length; i++) { 183 String pkgName = pkgs[i].getName(); 184 if (map.get(pkgName) == null) { 185 map.put(pkgName, pkgs[i]); 186 } 187 } 188 } 189 return (Package []) map.values().toArray(new Package [map.size()]); 190 } 191 192 protected Package definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) throws IllegalArgumentException { 193 synchronized (packages) { 194 Package pkg = getPackage(name); 195 if (pkg != null) { 196 throw new IllegalArgumentException (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 { 205 private final String className; 206 207 ClassOutputStream(List pkg, String className) { 208 StringBuffer temp = new StringBuffer (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 { 217 try { 218 loadClass(className); 219 } catch (ClassNotFoundException 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 { 228 private final ClassLoaderProvider provider; 229 private final ClassLoader 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 accessibleLoadClass(String name, boolean param) throws ClassNotFoundException { 242 return this.loadClass(name, param); 243 } 244 245 Package accessibleGetPackage(String name) { 246 return this.getPackage(name); 247 } 248 249 Package [] accessibleGetPackages() { 250 return this.getPackages(); 251 } 252 } 253 254 private final class StreamFactory extends JMIStreamFactory { 255 public OutputStream createStream(List pkg, String className, String extension) throws IOException { 256 if (!JMIStreamFactory.EXT_CLASS.equals(extension)) { 257 throw new IllegalArgumentException ("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 |