--- /dev/null
+package org.simantics.scl.reflection.internal.registry;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.procedure.TObjectObjectProcedure;\r
+\r
+import org.eclipse.core.runtime.IConfigurationElement;\r
+import org.eclipse.core.runtime.IContributor;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.core.runtime.spi.RegistryContributor;\r
+import org.osgi.framework.Bundle;\r
+import org.simantics.scl.compiler.types.TCon;\r
+import org.simantics.scl.reflection.OntologyVersions;\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.internal.Activator;\r
+\r
+public class BindingRegistry {\r
+\r
+ private static boolean DEBUG_INIT = false;\r
+\r
+ private static THashMap<String, Namespace> namespaces =\r
+ new THashMap<String, Namespace>();\r
+ \r
+ public static TypedValue getValue(String path, String name) throws ValueNotFoundException {\r
+ Namespace namespace = namespaces.get(path);\r
+ if(namespace == null)\r
+ throw new ValueNotFoundException("Didn't find namespace " + path + ".");\r
+ return namespace.getValue(name);\r
+ }\r
+ \r
+ public static Class<?> getClass(TCon type) throws TypeNotFoundException {\r
+ Namespace namespace = namespaces.get(type.module);\r
+ if(namespace == null)\r
+ throw new TypeNotFoundException("Didn't find namespace " + type.module + ".");\r
+ return namespace.getClass(type.name);\r
+ } \r
+\r
+ /*\r
+ * Called directly only for testing \r
+ */\r
+ public static void initialize() {\r
+ namespaces.clear();\r
+ IConfigurationElement[] elements = \r
+ Platform.getExtensionRegistry().getConfigurationElementsFor("org.simantics.scl.reflection.binding"); \r
+ for(IConfigurationElement element : elements) {\r
+ Bundle bundle = getBundle(element);\r
+ findBindings(bundle, null, element, null);\r
+ }\r
+ }\r
+ \r
+ static {\r
+ initialize();\r
+ if (DEBUG_INIT) {\r
+ namespaces.forEachEntry(new TObjectObjectProcedure<String, Namespace>() {\r
+\r
+ @Override\r
+ public boolean execute(String name, Namespace namespace) {\r
+ System.out.println(name);\r
+ namespace.print();\r
+ return true;\r
+ }\r
+ });\r
+ }\r
+ }\r
+ \r
+ private static Bundle getBundle(IConfigurationElement element) {\r
+ IContributor contributor = element.getContributor();\r
+ if(contributor instanceof RegistryContributor) {\r
+ long id = Long.parseLong(((RegistryContributor) contributor).getActualId());\r
+ return Activator.getInstance().getContext().getBundle(id);\r
+ }\r
+ else\r
+ return Platform.getBundle(contributor.getName());\r
+ }\r
+\r
+ private static Namespace getOrCreateNamespace(String path, ImportSeq importSeq) {\r
+ Namespace namespace = namespaces.get(path);\r
+ if(namespace == null) {\r
+ namespace = new Namespace(path, importSeq);\r
+ namespaces.put(path, namespace);\r
+ }\r
+ return namespace;\r
+ }\r
+ \r
+ private static void findBindings(\r
+ Bundle bundle,\r
+ String path,\r
+ IConfigurationElement element,\r
+ ImportSeq importSeq) {\r
+ String elementName = element.getName(); \r
+ if(elementName.equals("namespace")) {\r
+ if(path == null)\r
+ path = OntologyVersions.getInstance().currentVersion(element.getAttribute("path"));\r
+ else\r
+ path = OntologyVersions.getInstance().currentVersion(path + "/" + element.getAttribute("path"));\r
+ if(path.endsWith("/"))\r
+ path = path.substring(0, path.length()-1);\r
+ for(IConfigurationElement childElement : element.getChildren())\r
+ if(childElement.getName().equals("import")) {\r
+ String path_ = OntologyVersions.getInstance().currentVersion(childElement.getAttribute("path"));\r
+ String localName = childElement.getAttribute("localName");\r
+ importSeq = new ImportSeq(importSeq, localName, path_);\r
+ }\r
+ for(IConfigurationElement childElement : element.getChildren())\r
+ findBindings(bundle, path, childElement, importSeq);\r
+ }\r
+ else if(elementName.equals("class")) {\r
+ String className = element.getAttribute("className");\r
+ getOrCreateNamespace(path, importSeq)\r
+ .addClass(new Entry(bundle, className));\r
+ }\r
+ else if(elementName.equals("externalClass")) {\r
+ String className = element.getAttribute("className");\r
+ String alternativeName = element.getAttribute("alternativeName");\r
+ getOrCreateNamespace(path, importSeq).addExternalClass(\r
+ new ExternalClass(bundle, className, alternativeName)\r
+ );\r
+ }\r
+ else if(elementName.equals("externalMethod")) {\r
+ String className = element.getAttribute("className");\r
+ String methodName = element.getAttribute("methodName");\r
+ String alternativeName = element.getAttribute("alternativeName");\r
+ getOrCreateNamespace(path, importSeq).addExternalMethod(\r
+ new ExternalMethod(bundle, className, methodName, alternativeName)\r
+ );\r
+ }\r
+ } \r
+}\r