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