]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/ExpressionClassLoader.java
Merge remote-tracking branch 'origin/master' into private/antti2
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / runtime / ExpressionClassLoader.java
index bb2e5efc0a7deb57fc5081c9918a7683f40775c6..dbfafe19bc325fdf41852a04663db13f1053189f 100644 (file)
@@ -1,17 +1,17 @@
 package org.simantics.scl.compiler.runtime;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.util.Map;
 
 import org.simantics.scl.compiler.constants.Constant;
 
+import gnu.trove.map.hash.THashMap;
+
 public class ExpressionClassLoader extends ClassLoader implements MutableClassLoader {
     public static final boolean VALIDATE_CLASS_NAMES = true;
     public static final boolean TRACE_CLASS_CREATION = false;
     
     String basePackageName;
-    THashMap<String, byte[]> localClasses = new THashMap<String, byte[]>(); 
+    public THashMap<String, byte[]> localClasses = new THashMap<String, byte[]>(); 
     THashMap<String, RuntimeModule> runtimeModuleMap;
     int transientPackageId = 0;
     THashMap<Constant,Object> valueCache = new THashMap<Constant,Object>(); 
@@ -57,7 +57,40 @@ public class ExpressionClassLoader extends ClassLoader implements MutableClassLo
         if(bytes == null)
             throw new ClassNotFoundException(name);
 
-        return defineClass(name, bytes, 0, bytes.length);
+        clazz = defineClass(name, bytes, 0, bytes.length);
+        resolveClass(clazz);
+        
+        return clazz;
+        
+    }
+    
+    @Override
+    public byte[] getBytes(String name) {
+        // Non-SCL classes are not handled here
+        if(!name.startsWith(SCL_PACKAGE_PREFIX))
+            return null;
+
+        // Determine the id of the class loader which is responsible of the class
+        String requestedModuleName = RuntimeModule.extractClassLoaderId(name);
+
+        // Is class defined locally in this class loader?
+        if(requestedModuleName.equals(basePackageName)) {
+            String internalName = name.replace('.', '/');
+            byte[] bytes = localClasses.get(internalName);
+            if(bytes != null)
+                return bytes;
+            return localClasses.get(internalName);
+        }
+        
+        // Find suitable class loader that has this class locally
+        {
+            RuntimeModule parentModule = runtimeModuleMap.get(requestedModuleName);
+            if(parentModule == null)
+                return null;
+
+            // Find the class from the ancestor class loader
+            return parentModule.classLoader.getBytes(name);
+        }
     }
     
     private Class<?> getClass(String name) throws ClassNotFoundException {