]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.g3d/src/org/simantics/g3d/scl/SCLUtil.java
Safe SCL cast for Java objects
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / scl / SCLUtil.java
diff --git a/org.simantics.g3d/src/org/simantics/g3d/scl/SCLUtil.java b/org.simantics.g3d/src/org/simantics/g3d/scl/SCLUtil.java
new file mode 100644 (file)
index 0000000..9956346
--- /dev/null
@@ -0,0 +1,79 @@
+package org.simantics.g3d.scl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
+import org.simantics.scl.compiler.errors.Failable;
+import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
+import org.simantics.scl.compiler.module.Module;
+import org.simantics.scl.compiler.module.repository.ImportFailureException;
+import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
+import org.simantics.scl.compiler.types.TCon;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.osgi.SCLOsgi;
+
+public class SCLUtil {
+    
+    static Map<TCon,Class<?>> typeMap = new HashMap<TCon, Class<?>>();
+ // copied from org.simantics.scl.db.SCLFunctions
+    public static Class<?> possibleFromDynamic(Type expectedType, String moduleName) {
+        
+        try {
+
+            
+            Failable<Module> failable = SCLOsgi.MODULE_REPOSITORY.getModule(moduleName);
+            Module module = failable.getResult();
+            
+            RuntimeEnvironment env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
+                    EnvironmentSpecification.of(moduleName, ""), module.getParentClassLoader());
+
+            JavaTypeTranslator tr = new JavaTypeTranslator(env.getEnvironment());
+            TypeDesc desc = tr.toTypeDesc(expectedType);
+            String className = desc.getFullName();
+            Class<?> clazz = env.getMutableClassLoader().loadClass(className);
+            return clazz;
+        } catch (ImportFailureException e) {
+            return null;
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+    
+    public static Class<?> possibleClass(TCon type) {
+        Class<?> clazz = typeMap.get(type);
+        if (clazz == null) {
+            clazz = possibleFromDynamic(type, type.module);
+            typeMap.put(type, clazz);
+        }
+        return clazz;
+    }
+    
+    public static boolean javaIsInstanceOf(org.simantics.scl.compiler.types.Type t, Object o) {
+        if (t instanceof TCon) {
+            Class<?> clazz = possibleClass((TCon)t);
+            if (clazz == null)
+                return false;
+            if (!clazz.isAssignableFrom(o.getClass()))
+                return false;
+     
+            return true;
+        }
+        return false;
+    }
+    
+    public static Object javaSafeCoerce(org.simantics.scl.compiler.types.Type t, Object o) {
+        if (t instanceof TCon) {
+            Class<?> clazz = possibleClass((TCon)t);
+            if (clazz == null)
+                return null;
+            if (!clazz.isAssignableFrom(o.getClass()))
+                return null;
+     
+            return o;
+        }
+        return null;
+    }
+
+}