648e314d9a2f95c9dc659615514f0133c1efbf64
[simantics/platform.git] / bundles / org.simantics.scl.reflection / src / org / simantics / scl / reflection / internal / registry / BindingRegistry.java
1 package org.simantics.scl.reflection.internal.registry;
2
3 import gnu.trove.map.hash.THashMap;
4 import gnu.trove.procedure.TObjectObjectProcedure;
5
6 import org.eclipse.core.runtime.IConfigurationElement;
7 import org.eclipse.core.runtime.IContributor;
8 import org.eclipse.core.runtime.Platform;
9 import org.eclipse.core.runtime.spi.RegistryContributor;
10 import org.osgi.framework.Bundle;
11 import org.simantics.scl.compiler.types.TCon;
12 import org.simantics.scl.reflection.OntologyVersions;
13 import org.simantics.scl.reflection.TypeNotFoundException;
14 import org.simantics.scl.reflection.TypedValue;
15 import org.simantics.scl.reflection.ValueNotFoundException;
16 import org.simantics.scl.reflection.internal.Activator;
17
18 public class BindingRegistry {
19
20     private static boolean DEBUG_INIT = false;
21
22     private static THashMap<String, Namespace> namespaces =
23             new THashMap<String, Namespace>();
24         
25     public static TypedValue getValue(String path, String name) throws ValueNotFoundException {
26         Namespace namespace = namespaces.get(path);
27         if(namespace == null)
28             throw new ValueNotFoundException("Didn't find namespace " + path + ".");
29         return namespace.getValue(name);
30     }
31     
32     public static Class<?> getClass(TCon type) throws TypeNotFoundException {
33         Namespace namespace = namespaces.get(type.module);
34         if(namespace == null)
35             throw new TypeNotFoundException("Didn't find namespace " + type.module + ".");
36         return namespace.getClass(type.name);
37     }   
38
39     /*
40      * Called directly only for testing 
41      */
42     public static void initialize() {
43         namespaces.clear();
44         IConfigurationElement[] elements = 
45                 Platform.getExtensionRegistry().getConfigurationElementsFor("org.simantics.scl.reflection.binding");        
46         for(IConfigurationElement element : elements) {
47             Bundle bundle = getBundle(element);
48             findBindings(bundle, null, element, null);
49         }
50     }
51     
52     public static void primeBindingRegistry() {
53         for (Namespace ns : namespaces.values()) {
54             ns.initializeValues();
55         }
56     }
57     
58     static {
59         initialize();
60         if (DEBUG_INIT) {
61             namespaces.forEachEntry(new TObjectObjectProcedure<String, Namespace>() {
62
63                 @Override
64                 public boolean execute(String name, Namespace namespace) {
65                     System.out.println(name);
66                     namespace.print();
67                     return true;
68                 }
69             });
70         }
71     }
72     
73     private static Bundle getBundle(IConfigurationElement element) {
74         IContributor contributor = element.getContributor();
75         if(contributor instanceof RegistryContributor) {
76             long id = Long.parseLong(((RegistryContributor) contributor).getActualId());
77             return Activator.getInstance().getContext().getBundle(id);
78         }
79         else
80             return Platform.getBundle(contributor.getName());
81     }
82
83     private static Namespace getOrCreateNamespace(String path, ImportSeq importSeq) {
84         Namespace namespace = namespaces.get(path);
85         if(namespace == null) {
86             namespace = new Namespace(path, importSeq);
87             namespaces.put(path, namespace);
88         }
89         return namespace;
90     }
91     
92     private static void findBindings(
93             Bundle bundle,
94             String path,
95             IConfigurationElement element,
96             ImportSeq importSeq) {
97         String elementName = element.getName();        
98         if(elementName.equals("namespace")) {
99             if(path == null)
100                 path = OntologyVersions.getInstance().currentVersion(element.getAttribute("path"));
101             else
102                 path = OntologyVersions.getInstance().currentVersion(path + "/" + element.getAttribute("path"));
103             if(path.endsWith("/"))
104                 path = path.substring(0, path.length()-1);
105             for(IConfigurationElement childElement : element.getChildren())
106                 if(childElement.getName().equals("import")) {
107                     String path_ = OntologyVersions.getInstance().currentVersion(childElement.getAttribute("path"));
108                     String localName = childElement.getAttribute("localName");
109                     importSeq = new ImportSeq(importSeq, localName, path_);
110                 }
111             for(IConfigurationElement childElement : element.getChildren())
112                 findBindings(bundle, path, childElement, importSeq);
113         }
114         else if(elementName.equals("class")) {
115             String className = element.getAttribute("className");
116             getOrCreateNamespace(path, importSeq)
117                 .addClass(new Entry(bundle, className));
118         }
119         else if(elementName.equals("externalClass")) {
120             String className = element.getAttribute("className");
121             String alternativeName = element.getAttribute("alternativeName");
122             getOrCreateNamespace(path, importSeq).addExternalClass(
123                     new ExternalClass(bundle, className, alternativeName)
124                     );
125         }
126         else if(elementName.equals("externalMethod")) {
127             String className = element.getAttribute("className");
128             String methodName = element.getAttribute("methodName");
129             String alternativeName = element.getAttribute("alternativeName");
130             getOrCreateNamespace(path, importSeq).addExternalMethod(
131                     new ExternalMethod(bundle, className, methodName, alternativeName)
132                     );
133         }
134     } 
135 }