-package org.simantics.scl.reflection.internal.registry;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.procedure.TObjectObjectProcedure;\r
-\r
-import java.lang.reflect.Constructor;\r
-import java.lang.reflect.Field;\r
-import java.lang.reflect.Method;\r
-import java.lang.reflect.Modifier;\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;\r
-import org.simantics.scl.compiler.types.util.ITypeEnvironment;\r
-import org.simantics.scl.reflection.MinimalTypeBindingScheme;\r
-import org.simantics.scl.reflection.ReflectionUtils;\r
-import org.simantics.scl.reflection.TypeBindingScheme;\r
-import org.simantics.scl.reflection.TypeNotFoundException;\r
-import org.simantics.scl.reflection.TypedValue;\r
-import org.simantics.scl.reflection.ValueNotFoundException;\r
-import org.simantics.scl.reflection.annotations.SCLType;\r
-import org.simantics.scl.reflection.annotations.SCLValue;\r
-import org.simantics.scl.reflection.functions.ClassMethodFunction;\r
-import org.simantics.scl.reflection.functions.ClassMethodFunction3;\r
-import org.simantics.scl.reflection.functions.ConstructorFunction;\r
-import org.simantics.scl.reflection.functions.FieldAccessorFunction;\r
-import org.simantics.scl.reflection.functions.InstanceMethodFunction;\r
-import org.simantics.scl.reflection.internal.Activator;\r
-import org.simantics.scl.reflection.internal.typeRegistry.TypeRegistry;\r
-\r
-public class Namespace {\r
- String namespace;\r
- ImportSeq importSeq;\r
- ArrayList<Entry> classes = new ArrayList<Entry>();\r
- ArrayList<ExternalClass> externalClasses = \r
- new ArrayList<ExternalClass>();\r
- ArrayList<ExternalMethod> externalMethods = \r
- new ArrayList<ExternalMethod>();\r
- volatile THashMap<String, Class<?>> types;\r
- volatile THashMap<String, TypedValue> values; \r
- \r
- public Namespace(String namespace, ImportSeq importSeq) {\r
- this.namespace = namespace;\r
- this.importSeq = importSeq;\r
- }\r
-\r
- public void addClass(Entry e) {\r
- classes.add(e);\r
- }\r
- \r
- public void addExternalMethod(ExternalMethod e) {\r
- externalMethods.add(e);\r
- }\r
- \r
- public void addExternalClass(ExternalClass e) {\r
- externalClasses.add(e);\r
- }\r
- \r
- public Class<?> getClass(String name) throws TypeNotFoundException {\r
- if(types == null) {\r
- try {\r
- initializeTypes();\r
- } catch (Exception e) {\r
- throw new TypeNotFoundException(e);\r
- } \r
- }\r
- Class<?> type = types.get(name);\r
- if(type == null)\r
- throw new TypeNotFoundException("Didn't find type " + name + ".");\r
- return type;\r
- }\r
- \r
- public TypedValue getValue(String name) throws ValueNotFoundException {\r
- if(values == null) {\r
- try {\r
- initializeValues();\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- throw new ValueNotFoundException(e);\r
- } \r
- }\r
- TypedValue value = values.get(name);\r
- if(value == null)\r
- throw new ValueNotFoundException("Didn't find value " + name + ".");\r
- return value;\r
- }\r
- \r
- ITypeEnvironment typeEnvironment = new ITypeEnvironment() {\r
- \r
- @Override\r
- public Type resolve(String namespace, String name) {\r
- if(namespace == null) {\r
- if(TypeRegistry.isBuiltin(name))\r
- namespace = Types.BUILTIN;\r
- else if(types.contains(name))\r
- namespace = Namespace.this.namespace;\r
- else\r
- namespace = "";\r
- }\r
- else {\r
- for(ImportSeq cur = importSeq;cur != null;cur = cur.parent) {\r
- if(namespace.equals(cur.localName)) {\r
- namespace = cur.path;\r
- break;\r
- }\r
- }\r
- }\r
- return Types.con(namespace, name);\r
- }\r
- \r
- };\r
- \r
- private Type parseType(String typeText) throws SCLTypeParseException {\r
- return Types.closure(Types.parseType(typeEnvironment, typeText));\r
- }\r
-\r
- private synchronized void initializeTypes() {\r
- if(types == null) {\r
- types = new THashMap<String, Class<?>>();\r
- \r
- for(Entry entry : classes) {\r
- Class<?> clazz = entry.loadClass();\r
- if(clazz == null) {\r
- Activator.logError("Didn't find class " + entry.name + ".");\r
- continue;\r
- }\r
-\r
- SCLType sclType = clazz.getAnnotation(SCLType.class); \r
- if(sclType != null) {\r
- String name = sclType.name();\r
- if(name.isEmpty())\r
- name = clazz.getSimpleName();\r
- types.put(name, clazz);\r
- }\r
- }\r
- \r
- for(ExternalClass entry : externalClasses) {\r
- Class<?> clazz = entry.loadClass();\r
- if(clazz == null) {\r
- Activator.logError("Didn't find class " + entry.className + ".");\r
- continue;\r
- }\r
- \r
- String name = entry.alternativeName;\r
- if(name == null)\r
- name = clazz.getSimpleName();\r
- types.put(name, clazz);\r
- }\r
- } \r
- }\r
- \r
- private void handleMethod(TypeBindingScheme scheme, Class<?> clazz, Method method) {\r
- SCLValue sclValue = method.getAnnotation(SCLValue.class);\r
- if(sclValue != null) {\r
- String name = sclValue.name();\r
- if(name.isEmpty())\r
- name = method.getName(); \r
- Type type;\r
- try {\r
- type = parseType(sclValue.type());\r
- } catch (SCLTypeParseException e) {\r
- Activator.logError("Method " + method.getName() + " in class " + \r
- clazz.getCanonicalName() + " has invalid type declaration.", e\r
- );\r
- return;\r
- }\r
- try {\r
- if(ReflectionUtils.isCompatible(scheme, type, method)) {\r
- Object value;\r
- if(Modifier.isStatic(method.getModifiers())) {\r
- int arity = method.getParameterTypes().length;\r
- if(arity == 3)\r
- value = new ClassMethodFunction3(method);\r
- else\r
- value = new ClassMethodFunction(method);\r
- }\r
- else\r
- value = new InstanceMethodFunction(method);\r
- values.put(name, new TypedValue(type, value));\r
- }\r
- else {\r
- Activator.logError("Method " + method.getName() + " in class " + \r
- clazz.getCanonicalName() + " has incompatible SCL type in the SCLValue annotation."\r
- );\r
- ReflectionUtils.isCompatible(scheme, type, method);\r
- }\r
- } catch (TypeNotFoundException e) {\r
- Activator.logError("Couldn't find all types in the type declaration of method " + method.getName() + " in class " + \r
- clazz.getCanonicalName() + "."\r
- );\r
- }\r
- }\r
- }\r
- \r
- private void handleConstructor(TypeBindingScheme scheme, Class<?> clazz, Constructor<?> constr) {\r
- SCLValue sclValue = constr.getAnnotation(SCLValue.class);\r
- if(sclValue != null) {\r
- String name = sclValue.name();\r
- if(name.isEmpty())\r
- name = constr.getDeclaringClass().getSimpleName();\r
- Type type;\r
- try {\r
- type = parseType(sclValue.type());\r
- } catch (SCLTypeParseException e) {\r
- Activator.logError("Constructor in " + \r
- clazz.getCanonicalName() + " has invalid type declaration.", e\r
- );\r
- return;\r
- }\r
- try {\r
- if(ReflectionUtils.isCompatible(scheme, type, constr)) {\r
- Object value = new ConstructorFunction(constr);\r
- values.put(name, new TypedValue(type, value));\r
- }\r
- else {\r
- Activator.logError("Constructor of " + \r
- clazz.getCanonicalName() + " has incompatible SCL type in the SCLValue annotation."\r
- );\r
- }\r
- } catch (TypeNotFoundException e) {\r
- Activator.logError("Couldn't find all types in the type declaration of constructor in " + \r
- clazz.getCanonicalName() + "."\r
- );\r
- }\r
- }\r
- }\r
- \r
- private void handleField(TypeBindingScheme scheme, Class<?> clazz, Field field) {\r
- SCLValue sclValue = field.getAnnotation(SCLValue.class);\r
- if(sclValue != null) {\r
- String name = sclValue.name();\r
- if(name.isEmpty())\r
- name = field.getName();\r
- Type type;\r
- try {\r
- type = parseType(sclValue.type());\r
- } catch (SCLTypeParseException e) {\r
- Activator.logError("Field " + field.getName() + " in class " + \r
- clazz.getCanonicalName() + " has invalid type declaration.", e\r
- );\r
- return;\r
- }\r
- try {\r
- if(ReflectionUtils.isCompatible(scheme, type, field)) {\r
- Object value;\r
- if(Modifier.isStatic(field.getModifiers()))\r
- try {\r
- value = field.get(null);\r
- } catch (IllegalArgumentException e) {\r
- Activator.logError("Cannot read field " + field.getName() + " in class " + \r
- clazz.getCanonicalName() + ".", e\r
- );\r
- return;\r
- } catch (IllegalAccessException e) {\r
- Activator.logError("Cannot read field " + field.getName() + " in class " + \r
- clazz.getCanonicalName() + ".", e\r
- );\r
- return;\r
- }\r
- else\r
- value = new FieldAccessorFunction(field);\r
- values.put(name, new TypedValue(type, value));\r
- }\r
- else {\r
- Activator.logError("Field " + field.getName() + " in class " + \r
- clazz.getCanonicalName() + " has incompatible SCL type in the SCLValue annotation."\r
- );\r
- }\r
- } catch (TypeNotFoundException e) {\r
- Activator.logError("Couldn't find all types in the type declaration of field " + field.getName() + " in class " + \r
- clazz.getCanonicalName() + "."\r
- );\r
- }\r
- }\r
- } \r
- \r
- private synchronized void initializeValues() {\r
- if(values == null) {\r
- initializeTypes();\r
- TypeBindingScheme scheme = MinimalTypeBindingScheme.INSTANCE;\r
- \r
- values = new THashMap<String, TypedValue>();\r
- \r
- for(Entry entry : classes) {\r
- Class<?> clazz = entry.loadClass();\r
- \r
- if(clazz == null) {\r
- Activator.logError("Didn't find class " + entry.name + ".");\r
- continue;\r
- }\r
- \r
- for(Method method : clazz.getMethods()) {\r
- handleMethod(scheme, clazz, method);\r
- }\r
- \r
- for(Constructor<?> constr : clazz.getConstructors()) {\r
- handleConstructor(scheme, clazz, constr);\r
- }\r
- \r
- for(Field field : clazz.getFields()) {\r
- handleField(scheme, clazz, field);\r
- }\r
- }\r
- \r
- for(ExternalMethod entry : externalMethods) {\r
- Class<?> clazz = entry.loadClass();\r
- \r
- if(clazz == null) {\r
- Activator.logError("Didn't find class " + entry.className + ".");\r
- continue;\r
- }\r
- \r
- Method method = entry.getMethod(clazz);\r
- \r
- if(method == null) {\r
- Activator.logError("Didn't find method " + entry.methodName + \r
- " in class " + entry.className + ".");\r
- continue;\r
- }\r
- \r
- handleMethod(scheme, clazz, method);\r
- }\r
- } \r
- }\r
- \r
- public void print() { \r
- for(Entry entry : classes) {\r
- System.out.println(" " + entry.name + " (" + entry.bundle + ")");\r
- }\r
- try {\r
- initializeTypes();\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- throw new RuntimeException(e);\r
- } \r
- types.forEachEntry(new TObjectObjectProcedure<String, Class<?>>() { \r
- @Override\r
- public boolean execute(String name, Class<?> clazz) {\r
- System.out.println(" type " + name + " = " + clazz.getCanonicalName());\r
- return true;\r
- }\r
- });\r
- try {\r
- initializeValues();\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- throw new RuntimeException(e);\r
- } \r
- values.forEachEntry(new TObjectObjectProcedure<String, TypedValue>() { \r
- @Override\r
- public boolean execute(String name, TypedValue value) {\r
- System.out.println(" " + name + " :: " + value.getType());\r
- return true;\r
- }\r
- });\r
- }\r
- \r
-}\r
+package org.simantics.scl.reflection.internal.registry;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectObjectProcedure;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;
+import org.simantics.scl.compiler.types.util.ITypeEnvironment;
+import org.simantics.scl.reflection.MinimalTypeBindingScheme;
+import org.simantics.scl.reflection.ReflectionUtils;
+import org.simantics.scl.reflection.TypeBindingScheme;
+import org.simantics.scl.reflection.TypeNotFoundException;
+import org.simantics.scl.reflection.TypedValue;
+import org.simantics.scl.reflection.ValueNotFoundException;
+import org.simantics.scl.reflection.annotations.SCLType;
+import org.simantics.scl.reflection.annotations.SCLValue;
+import org.simantics.scl.reflection.functions.ClassMethodFunction;
+import org.simantics.scl.reflection.functions.ClassMethodFunction3;
+import org.simantics.scl.reflection.functions.ConstructorFunction;
+import org.simantics.scl.reflection.functions.FieldAccessorFunction;
+import org.simantics.scl.reflection.functions.InstanceMethodFunction;
+import org.simantics.scl.reflection.internal.Activator;
+import org.simantics.scl.reflection.internal.typeRegistry.TypeRegistry;
+
+public class Namespace {
+ String namespace;
+ ImportSeq importSeq;
+ ArrayList<Entry> classes = new ArrayList<Entry>();
+ ArrayList<ExternalClass> externalClasses =
+ new ArrayList<ExternalClass>();
+ ArrayList<ExternalMethod> externalMethods =
+ new ArrayList<ExternalMethod>();
+ volatile THashMap<String, Class<?>> types;
+ volatile THashMap<String, TypedValue> values;
+
+ public Namespace(String namespace, ImportSeq importSeq) {
+ this.namespace = namespace;
+ this.importSeq = importSeq;
+ }
+
+ public void addClass(Entry e) {
+ classes.add(e);
+ }
+
+ public void addExternalMethod(ExternalMethod e) {
+ externalMethods.add(e);
+ }
+
+ public void addExternalClass(ExternalClass e) {
+ externalClasses.add(e);
+ }
+
+ public Class<?> getClass(String name) throws TypeNotFoundException {
+ if(types == null) {
+ try {
+ initializeTypes();
+ } catch (Exception e) {
+ throw new TypeNotFoundException(e);
+ }
+ }
+ Class<?> type = types.get(name);
+ if(type == null)
+ throw new TypeNotFoundException("Didn't find type " + name + ".");
+ return type;
+ }
+
+ public TypedValue getValue(String name) throws ValueNotFoundException {
+ if(values == null) {
+ try {
+ initializeValues();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new ValueNotFoundException(e);
+ }
+ }
+ TypedValue value = values.get(name);
+ if(value == null)
+ throw new ValueNotFoundException("Didn't find value " + name + ".");
+ return value;
+ }
+
+ ITypeEnvironment typeEnvironment = new ITypeEnvironment() {
+
+ @Override
+ public Type resolve(String namespace, String name) {
+ if(namespace == null) {
+ if(TypeRegistry.isBuiltin(name))
+ namespace = Types.BUILTIN;
+ else if(types.contains(name))
+ namespace = Namespace.this.namespace;
+ else
+ namespace = "";
+ }
+ else {
+ for(ImportSeq cur = importSeq;cur != null;cur = cur.parent) {
+ if(namespace.equals(cur.localName)) {
+ namespace = cur.path;
+ break;
+ }
+ }
+ }
+ return Types.con(namespace, name);
+ }
+
+ };
+
+ private Type parseType(String typeText) throws SCLTypeParseException {
+ return Types.closure(Types.parseType(typeEnvironment, typeText));
+ }
+
+ private synchronized void initializeTypes() {
+ if(types == null) {
+ types = new THashMap<String, Class<?>>();
+
+ for(Entry entry : classes) {
+ Class<?> clazz = entry.loadClass();
+ if(clazz == null) {
+ Activator.logError("Didn't find class " + entry.name + ".");
+ continue;
+ }
+
+ SCLType sclType = clazz.getAnnotation(SCLType.class);
+ if(sclType != null) {
+ String name = sclType.name();
+ if(name.isEmpty())
+ name = clazz.getSimpleName();
+ types.put(name, clazz);
+ }
+ }
+
+ for(ExternalClass entry : externalClasses) {
+ Class<?> clazz = entry.loadClass();
+ if(clazz == null) {
+ Activator.logError("Didn't find class " + entry.className + ".");
+ continue;
+ }
+
+ String name = entry.alternativeName;
+ if(name == null)
+ name = clazz.getSimpleName();
+ types.put(name, clazz);
+ }
+ }
+ }
+
+ private void handleMethod(TypeBindingScheme scheme, Class<?> clazz, Method method) {
+ SCLValue sclValue = method.getAnnotation(SCLValue.class);
+ if(sclValue != null) {
+ String name = sclValue.name();
+ if(name.isEmpty())
+ name = method.getName();
+ Type type;
+ try {
+ type = parseType(sclValue.type());
+ } catch (SCLTypeParseException e) {
+ Activator.logError("Method " + method.getName() + " in class " +
+ clazz.getCanonicalName() + " has invalid type declaration.", e
+ );
+ return;
+ }
+ try {
+ if(ReflectionUtils.isCompatible(scheme, type, method)) {
+ Object value;
+ if(Modifier.isStatic(method.getModifiers())) {
+ int arity = method.getParameterTypes().length;
+ if(arity == 3)
+ value = new ClassMethodFunction3(method);
+ else
+ value = new ClassMethodFunction(method);
+ }
+ else
+ value = new InstanceMethodFunction(method);
+ values.put(name, new TypedValue(type, value));
+ }
+ else {
+ Activator.logError("Method " + method.getName() + " in class " +
+ clazz.getCanonicalName() + " has incompatible SCL type in the SCLValue annotation."
+ );
+ ReflectionUtils.isCompatible(scheme, type, method);
+ }
+ } catch (TypeNotFoundException e) {
+ Activator.logError("Couldn't find all types in the type declaration of method " + method.getName() + " in class " +
+ clazz.getCanonicalName() + "."
+ );
+ }
+ }
+ }
+
+ private void handleConstructor(TypeBindingScheme scheme, Class<?> clazz, Constructor<?> constr) {
+ SCLValue sclValue = constr.getAnnotation(SCLValue.class);
+ if(sclValue != null) {
+ String name = sclValue.name();
+ if(name.isEmpty())
+ name = constr.getDeclaringClass().getSimpleName();
+ Type type;
+ try {
+ type = parseType(sclValue.type());
+ } catch (SCLTypeParseException e) {
+ Activator.logError("Constructor in " +
+ clazz.getCanonicalName() + " has invalid type declaration.", e
+ );
+ return;
+ }
+ try {
+ if(ReflectionUtils.isCompatible(scheme, type, constr)) {
+ Object value = new ConstructorFunction(constr);
+ values.put(name, new TypedValue(type, value));
+ }
+ else {
+ Activator.logError("Constructor of " +
+ clazz.getCanonicalName() + " has incompatible SCL type in the SCLValue annotation."
+ );
+ }
+ } catch (TypeNotFoundException e) {
+ Activator.logError("Couldn't find all types in the type declaration of constructor in " +
+ clazz.getCanonicalName() + "."
+ );
+ }
+ }
+ }
+
+ private void handleField(TypeBindingScheme scheme, Class<?> clazz, Field field) {
+ SCLValue sclValue = field.getAnnotation(SCLValue.class);
+ if(sclValue != null) {
+ String name = sclValue.name();
+ if(name.isEmpty())
+ name = field.getName();
+ Type type;
+ try {
+ type = parseType(sclValue.type());
+ } catch (SCLTypeParseException e) {
+ Activator.logError("Field " + field.getName() + " in class " +
+ clazz.getCanonicalName() + " has invalid type declaration.", e
+ );
+ return;
+ }
+ try {
+ if(ReflectionUtils.isCompatible(scheme, type, field)) {
+ Object value;
+ if(Modifier.isStatic(field.getModifiers()))
+ try {
+ value = field.get(null);
+ } catch (IllegalArgumentException e) {
+ Activator.logError("Cannot read field " + field.getName() + " in class " +
+ clazz.getCanonicalName() + ".", e
+ );
+ return;
+ } catch (IllegalAccessException e) {
+ Activator.logError("Cannot read field " + field.getName() + " in class " +
+ clazz.getCanonicalName() + ".", e
+ );
+ return;
+ }
+ else
+ value = new FieldAccessorFunction(field);
+ values.put(name, new TypedValue(type, value));
+ }
+ else {
+ Activator.logError("Field " + field.getName() + " in class " +
+ clazz.getCanonicalName() + " has incompatible SCL type in the SCLValue annotation."
+ );
+ }
+ } catch (TypeNotFoundException e) {
+ Activator.logError("Couldn't find all types in the type declaration of field " + field.getName() + " in class " +
+ clazz.getCanonicalName() + "."
+ );
+ }
+ }
+ }
+
+ private synchronized void initializeValues() {
+ if(values == null) {
+ initializeTypes();
+ TypeBindingScheme scheme = MinimalTypeBindingScheme.INSTANCE;
+
+ values = new THashMap<String, TypedValue>();
+
+ for(Entry entry : classes) {
+ Class<?> clazz = entry.loadClass();
+
+ if(clazz == null) {
+ Activator.logError("Didn't find class " + entry.name + ".");
+ continue;
+ }
+
+ for(Method method : clazz.getMethods()) {
+ handleMethod(scheme, clazz, method);
+ }
+
+ for(Constructor<?> constr : clazz.getConstructors()) {
+ handleConstructor(scheme, clazz, constr);
+ }
+
+ for(Field field : clazz.getFields()) {
+ handleField(scheme, clazz, field);
+ }
+ }
+
+ for(ExternalMethod entry : externalMethods) {
+ Class<?> clazz = entry.loadClass();
+
+ if(clazz == null) {
+ Activator.logError("Didn't find class " + entry.className + ".");
+ continue;
+ }
+
+ Method method = entry.getMethod(clazz);
+
+ if(method == null) {
+ Activator.logError("Didn't find method " + entry.methodName +
+ " in class " + entry.className + ".");
+ continue;
+ }
+
+ handleMethod(scheme, clazz, method);
+ }
+ }
+ }
+
+ public void print() {
+ for(Entry entry : classes) {
+ System.out.println(" " + entry.name + " (" + entry.bundle + ")");
+ }
+ try {
+ initializeTypes();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ types.forEachEntry(new TObjectObjectProcedure<String, Class<?>>() {
+ @Override
+ public boolean execute(String name, Class<?> clazz) {
+ System.out.println(" type " + name + " = " + clazz.getCanonicalName());
+ return true;
+ }
+ });
+ try {
+ initializeValues();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ values.forEachEntry(new TObjectObjectProcedure<String, TypedValue>() {
+ @Override
+ public boolean execute(String name, TypedValue value) {
+ System.out.println(" " + name + " :: " + value.getType());
+ return true;
+ }
+ });
+ }
+
+}