X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.reflection%2Fsrc%2Forg%2Fsimantics%2Fscl%2Freflection%2Finternal%2Fregistry%2FNamespace.java;h=daaa204dbe708c971969ba65a3ef68bb73390651;hp=45db1307027f5551039897b741ee1c87f74a532b;hb=91e878ce39c9db112d658b3236f29a13e12724e6;hpb=25b6c25959c1fb3c60bb41cd0e1f0808e7fc3769 diff --git a/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/Namespace.java b/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/Namespace.java old mode 100755 new mode 100644 index 45db13070..daaa204db --- a/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/Namespace.java +++ b/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/Namespace.java @@ -1,359 +1,359 @@ -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 classes = new ArrayList(); - ArrayList externalClasses = - new ArrayList(); - ArrayList externalMethods = - new ArrayList(); - volatile THashMap> types; - volatile THashMap 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>(); - - 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(); - - 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>() { - @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() { - @Override - public boolean execute(String name, TypedValue value) { - System.out.println(" " + name + " :: " + value.getType()); - return true; - } - }); - } - -} +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 classes = new ArrayList(); + ArrayList externalClasses = + new ArrayList(); + ArrayList externalMethods = + new ArrayList(); + volatile THashMap> types; + volatile THashMap 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>(); + + 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(); + + 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>() { + @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() { + @Override + public boolean execute(String name, TypedValue value) { + System.out.println(" " + name + " :: " + value.getType()); + return true; + } + }); + } + +}