]> gerrit.simantics Code Review - simantics/3d.git/blob - 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
1 package org.simantics.g3d.scl;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import org.cojen.classfile.TypeDesc;
7 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
8 import org.simantics.scl.compiler.errors.Failable;
9 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
10 import org.simantics.scl.compiler.module.Module;
11 import org.simantics.scl.compiler.module.repository.ImportFailureException;
12 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
13 import org.simantics.scl.compiler.types.TCon;
14 import org.simantics.scl.compiler.types.Type;
15 import org.simantics.scl.osgi.SCLOsgi;
16
17 public class SCLUtil {
18     
19     static Map<TCon,Class<?>> typeMap = new HashMap<TCon, Class<?>>();
20  // copied from org.simantics.scl.db.SCLFunctions
21     public static Class<?> possibleFromDynamic(Type expectedType, String moduleName) {
22         
23         try {
24
25             
26             Failable<Module> failable = SCLOsgi.MODULE_REPOSITORY.getModule(moduleName);
27             Module module = failable.getResult();
28             
29             RuntimeEnvironment env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
30                     EnvironmentSpecification.of(moduleName, ""), module.getParentClassLoader());
31
32             JavaTypeTranslator tr = new JavaTypeTranslator(env.getEnvironment());
33             TypeDesc desc = tr.toTypeDesc(expectedType);
34             String className = desc.getFullName();
35             Class<?> clazz = env.getMutableClassLoader().loadClass(className);
36             return clazz;
37         } catch (ImportFailureException e) {
38             return null;
39         } catch (ClassNotFoundException e) {
40             return null;
41         }
42     }
43     
44     public static Class<?> possibleClass(TCon type) {
45         Class<?> clazz = typeMap.get(type);
46         if (clazz == null) {
47             clazz = possibleFromDynamic(type, type.module);
48             typeMap.put(type, clazz);
49         }
50         return clazz;
51     }
52     
53     public static boolean javaIsInstanceOf(org.simantics.scl.compiler.types.Type t, Object o) {
54         if (t instanceof TCon) {
55             Class<?> clazz = possibleClass((TCon)t);
56             if (clazz == null)
57                 return false;
58             if (!clazz.isAssignableFrom(o.getClass()))
59                 return false;
60      
61             return true;
62         }
63         return false;
64     }
65     
66     public static Object javaSafeCoerce(org.simantics.scl.compiler.types.Type t, Object o) {
67         if (t instanceof TCon) {
68             Class<?> clazz = possibleClass((TCon)t);
69             if (clazz == null)
70                 return null;
71             if (!clazz.isAssignableFrom(o.getClass()))
72                 return null;
73      
74             return o;
75         }
76         return null;
77     }
78
79 }