]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java
Guard graph SCL module compilation
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / GraphModuleSourceRepository.java
index 3edc7bfeae28dd2a696dc9c3bd1d9d984c00de5d..a70844cd375c8956adb593cb71406e92d782e963 100644 (file)
-package org.simantics.modeling.scl;\r
-\r
-import java.util.Collection;\r
-\r
-import org.simantics.Simantics;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.RequestProcessorSpecific;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.request.UnaryRead;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.procedure.SyncListener;\r
-import org.simantics.db.request.Read;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.modeling.ModelingUtils;\r
-import org.simantics.scl.compiler.module.repository.UpdateListener;\r
-import org.simantics.scl.compiler.source.ModuleSource;\r
-import org.simantics.scl.compiler.source.StringModuleSource;\r
-import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;\r
-import org.simantics.scl.runtime.SCLContext;\r
-import org.simantics.structural2.utils.StructuralUtils;\r
-import org.simantics.scl.runtime.tuple.Tuple0;\r
-\r
-import gnu.trove.procedure.TObjectProcedure;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-public enum GraphModuleSourceRepository implements ModuleSourceRepository {\r
-    INSTANCE;\r
-\r
-    @Override\r
-    public ModuleSource getModuleSource(final String moduleName, UpdateListener listener) {\r
-        if(!moduleName.startsWith("http://"))\r
-            return null;\r
-\r
-        Object graph = SCLContext.getCurrent().get("graph");\r
-        RequestProcessorSpecific requestProcessor;\r
-        if(graph instanceof ReadGraph)\r
-            requestProcessor = (ReadGraph)graph;\r
-        else\r
-            requestProcessor = Simantics.getSession();\r
-\r
-        Read<ModuleSource> request = new ReadModuleSource(moduleName);\r
-\r
-        try {\r
-            if(listener != null)\r
-                return requestProcessor.syncRequest(request, new ModuleListener(listener, moduleName));\r
-            else\r
-                return requestProcessor.syncRequest(request);\r
-        } catch (DatabaseException e) {\r
-            e.printStackTrace();\r
-            return null;\r
-        }\r
-    }\r
-\r
-    static class ModuleListener implements SyncListener<ModuleSource> {\r
-        UpdateListener listener;\r
-        boolean alreadyExecutedOnce;\r
-        final String moduleName;\r
-        public ModuleListener(UpdateListener listener, String moduleName) {\r
-            this.listener = listener;\r
-            this.moduleName = moduleName;\r
-        }\r
-        @Override\r
-        public boolean isDisposed() {\r
-            return listener == null;\r
-        }\r
-        private void fireUpdate(ReadGraph graph) {\r
-            if(listener != null) {\r
-                SCLContext context = SCLContext.getCurrent();\r
-                Object oldGraph = context.put("graph", graph);\r
-                try {\r
-                    listener.notifyAboutUpdate();\r
-                } finally {\r
-                    listener = null;\r
-                    context.put("graph", oldGraph);\r
-                }\r
-            }\r
-        }\r
-        @Override\r
-        public void execute(ReadGraph graph, ModuleSource result)\r
-                throws DatabaseException {\r
-            if(alreadyExecutedOnce)\r
-                fireUpdate(graph);\r
-            else\r
-                alreadyExecutedOnce = true;\r
-        }\r
-        @Override\r
-        public void exception(ReadGraph graph, Throwable t)\r
-                throws DatabaseException {\r
-            t.printStackTrace();\r
-            if(alreadyExecutedOnce && listener != null)\r
-                fireUpdate(graph);\r
-        }\r
-    };\r
-    \r
-    public static class GraphModuleSource extends StringModuleSource {\r
-\r
-        private final boolean immutable;\r
-\r
-        public GraphModuleSource(String moduleName, ClassLoader classLoader, String moduleText, boolean immutable) {\r
-            super(moduleName, classLoader, moduleText);\r
-            this.immutable = immutable;\r
-        }\r
-        \r
-        @Override\r
-        public boolean isUpdateable() {\r
-            return !immutable;\r
-        }\r
-        \r
-        @Override\r
-        public void update(String newSourceText) {\r
-            try {\r
-                Simantics.getSession().syncRequest(new WriteModuleSource(getModuleName(), newSourceText));\r
-            } catch (DatabaseException e) {\r
-                e.printStackTrace();\r
-            }\r
-        }\r
-    }\r
-\r
-    static class ReadModuleSource extends UnaryRead<String, ModuleSource> {\r
-        public ReadModuleSource(String moduleName) {\r
-            super(moduleName);\r
-        }\r
-\r
-        @Override\r
-        public ModuleSource perform(ReadGraph graph) throws DatabaseException {\r
-            Resource moduleResource = graph.getPossibleResource(parameter);\r
-            if(moduleResource == null)\r
-                return null;\r
-            Layer0 L0 = Layer0.getInstance(graph);\r
-            if(!graph.isInstanceOf(moduleResource, L0.SCLModule))\r
-                return null;\r
-            String text = graph.getRelatedValue(moduleResource, L0.SCLModule_definition);\r
-            boolean immutable = StructuralUtils.isImmutable(graph, moduleResource);\r
-            return new GraphModuleSource(parameter, getClass().getClassLoader(), text, immutable);\r
-        }\r
-    }\r
-    \r
-    static class WriteModuleSource extends WriteRequest {\r
-        private final String moduleURI;\r
-        private final String sourceText;\r
-        \r
-        public WriteModuleSource(String moduleURI, String sourceText) {\r
-            this.moduleURI = moduleURI;\r
-            this.sourceText = sourceText;\r
-        }\r
-\r
-        @Override\r
-        public void perform(WriteGraph graph) throws DatabaseException {\r
-            Resource moduleResource = graph.getPossibleResource(moduleURI);\r
-            if(moduleResource == null)\r
-                return;\r
-            Layer0 L0 = Layer0.getInstance(graph);\r
-            if(!graph.isInstanceOf(moduleResource, L0.SCLModule))\r
-                return;\r
-            graph.claimLiteral(moduleResource, L0.SCLModule_definition, sourceText);\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void forAllModules(TObjectProcedure<String> procedure) {\r
-        THashSet<String> moduleURIs;\r
-        try {\r
-            moduleURIs = Simantics.getSession().syncRequest(new Read<THashSet<String>>() {\r
-                @Override\r
-                public THashSet<String> perform(ReadGraph graph)\r
-                        throws DatabaseException {\r
-                    THashSet<String> result = new THashSet<String>(); \r
-                    Resource projectResource = Simantics.getProjectResource();\r
-                    Layer0 L0 = Layer0.getInstance(graph);\r
-                    for(Resource model : graph.getObjects(projectResource, L0.ConsistsOf)) {\r
-                        if(graph.isInstanceOf(model, L0.IndexRoot)) {\r
-                            for(Resource module : ModelingUtils.searchByType(graph, model, L0.SCLModule))\r
-                                result.add(graph.getURI(module));\r
-                        }\r
-                    }\r
-                    \r
-                    Collection<Resource> ontologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE);\r
-                    for (Resource ontology : ontologies) {\r
-                        for(Resource module : ModelingUtils.searchByType(graph, ontology, L0.SCLModule))\r
-                            result.add(graph.getURI(module));\r
-                    }\r
-                    \r
-                    return result;\r
-                }\r
-            });\r
-            moduleURIs.forEach(procedure);\r
-        } catch (DatabaseException e) {\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void checkUpdates() {\r
-    }\r
-\r
-    @Override\r
-    public String getDocumentation(String documentationName) {\r
-        return null;\r
-    }\r
-\r
-    @Override\r
-    public void forAllDocumentations(TObjectProcedure<String> procedure) {\r
-    }\r
-\r
-    @Override\r
-    public void clear() {\r
-    }\r
-}\r
+package org.simantics.modeling.scl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.SyncListener;
+import org.simantics.db.request.Read;
+import org.simantics.db.request.ReadExt;
+import org.simantics.db.request.RequestFlags;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingUtils;
+import org.simantics.modeling.internal.Activator;
+import org.simantics.modeling.scl.ontologymodule.OntologyModuleSourceRepository;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
+import org.simantics.scl.compiler.module.repository.UpdateListener;
+import org.simantics.scl.compiler.module.repository.UpdateListener.Observable;
+import org.simantics.scl.compiler.source.ModuleSource;
+import org.simantics.scl.compiler.source.StringModuleSource;
+import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
+import org.simantics.scl.osgi.internal.OsgiJavaReferenceValidatorFactory;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.tuple.Tuple0;
+import org.simantics.structural2.utils.StructuralUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import gnu.trove.procedure.TObjectProcedure;
+import gnu.trove.set.hash.THashSet;
+
+public enum GraphModuleSourceRepository implements ModuleSourceRepository {
+    INSTANCE; 
+    
+    private static final Logger LOGGER = LoggerFactory.getLogger(OntologyModuleSourceRepository.class);
+
+    private static final OsgiJavaReferenceValidatorFactory REFERENCE_VALIDATOR_FACTORY = new OsgiJavaReferenceValidatorFactory(Activator.getContext().getBundle());
+
+    @Override
+    public ModuleSource getModuleSource(final String moduleName, UpdateListener listener) {
+        if(!moduleName.startsWith("http://"))
+            return null; // Don't do a graph request if this cannot be a resource
+
+        Read<ModuleSource> request = new ReadModuleSource(moduleName);
+
+        try {
+            if(listener != null)
+                return Simantics.getAvailableRequestProcessor().syncRequest(request, new ModuleListener(listener, moduleName));
+            else
+                return Simantics.getAvailableRequestProcessor().syncRequest(request);
+        } catch (DatabaseException e) {
+            LOGGER.error("Failed to read graph module {}.",  moduleName, e);
+            return null;
+        }
+    }
+
+    static class ModuleListener implements SyncListener<ModuleSource>, Observable {
+        UpdateListener listener;
+        boolean alreadyExecutedOnce;
+        final String moduleName;
+        public ModuleListener(UpdateListener listener, String moduleName) {
+            this.listener = listener;
+            this.listener.addObservable(this);
+            this.moduleName = moduleName;
+        }
+        @Override
+        public void removeListener(UpdateListener listener) {
+            this.listener = null;
+        }
+        @Override
+        public boolean isDisposed() {
+            return listener == null;
+        }
+        private void fireUpdate(ReadGraph graph) {
+            if(listener != null) {
+                SCLContext context = SCLContext.getCurrent();
+                Object oldGraph = context.put("graph", graph);
+                try {
+                    listener.notifyAboutUpdate();
+                } finally {
+                    listener = null;
+                    context.put("graph", oldGraph);
+                }
+            }
+        }
+        @Override
+        public void execute(ReadGraph graph, ModuleSource result)
+                throws DatabaseException {
+            if(alreadyExecutedOnce)
+                fireUpdate(graph);
+            else
+                alreadyExecutedOnce = true;
+        }
+        @Override
+        public void exception(ReadGraph graph, Throwable t)
+                throws DatabaseException {
+            LOGGER.error("Could not listen {}", this, t);
+            if(alreadyExecutedOnce && listener != null)
+                fireUpdate(graph);
+        }
+
+        @Override
+        public String toString() {
+            return moduleName + " " + listener + " (" + alreadyExecutedOnce + ") [" + getClass().toString() + "]";
+        }
+    };
+    
+    public static class GraphModuleSource extends StringModuleSource {
+
+        private final boolean immutable;
+
+        public GraphModuleSource(String moduleName, ClassLoader classLoader, String moduleText, boolean immutable) {
+            super(moduleName, classLoader, moduleText);
+            this.immutable = immutable;
+        }
+        
+        @Override
+        public boolean isUpdateable() {
+            return !immutable;
+        }
+        
+        @Override
+        public void update(String newSourceText) {
+            try {
+                Simantics.getSession().syncRequest(new WriteModuleSource(getModuleName(), newSourceText));
+            } catch (DatabaseException e) {
+                LOGGER.error("Could not update {} with newSourceText {}", this, newSourceText);
+            }
+        }
+        
+        @Override
+        public JavaReferenceValidatorFactory getJavaReferenceValidatorFactory() {
+            return REFERENCE_VALIDATOR_FACTORY;
+        }
+    }
+
+    static class PossibleResourceIU extends UnaryRead<String,Resource> implements ReadExt {
+
+        public PossibleResourceIU(String parameter) {
+            super(parameter);
+        }
+
+        @Override
+        public Resource perform(ReadGraph graph) throws DatabaseException {
+            return graph.getPossibleResource(parameter);
+        }
+
+        @Override
+        public boolean isImmutable(ReadGraph graph) throws DatabaseException {
+            return false;
+        }
+
+        @Override
+        public int getType() {
+            return RequestFlags.IMMEDIATE_UPDATE;
+        }
+        
+    }
+    
+    static class ReadModuleSource extends UnaryRead<String, ModuleSource> {
+        public ReadModuleSource(String moduleName) {
+            super(moduleName);
+        }
+
+        @Override
+        public ModuleSource perform(ReadGraph graph) throws DatabaseException {
+            Resource moduleResource = graph.syncRequest(new PossibleResourceIU(parameter));
+            if(moduleResource == null)
+                return null;
+            Layer0 L0 = Layer0.getInstance(graph);
+            if(!graph.isInstanceOf(moduleResource, L0.SCLModule))
+                return null;
+            String text = graph.getRelatedValue(moduleResource, L0.SCLModule_definition);
+            boolean immutable = StructuralUtils.isImmutable(graph, moduleResource);
+            return new GraphModuleSource(parameter, getClass().getClassLoader(), text, immutable);
+        }
+    }
+    
+    static class WriteModuleSource extends WriteRequest {
+        private final String moduleURI;
+        private final String sourceText;
+        
+        public WriteModuleSource(String moduleURI, String sourceText) {
+            this.moduleURI = moduleURI;
+            this.sourceText = sourceText;
+        }
+
+        @Override
+        public void perform(WriteGraph graph) throws DatabaseException {
+            Resource moduleResource = graph.getPossibleResource(moduleURI);
+            if(moduleResource == null)
+                return;
+            Layer0 L0 = Layer0.getInstance(graph);
+            if(!graph.isInstanceOf(moduleResource, L0.SCLModule))
+                return;
+            graph.claimLiteral(moduleResource, L0.SCLModule_definition, sourceText);
+        }
+    }
+
+    private THashSet<String> getAllModules(ReadGraph graph) throws DatabaseException {
+        THashSet<String> result = new THashSet<String>(); 
+        Resource projectResource = Simantics.getProjectResource();
+        Layer0 L0 = Layer0.getInstance(graph);
+        for(Resource model : graph.getObjects(projectResource, L0.ConsistsOf)) {
+            if(graph.isInstanceOf(model, L0.IndexRoot)) {
+                for(Resource module : ModelingUtils.searchByType(graph, model, L0.SCLModule))
+                    result.add(graph.getURI(module));
+            }
+        }
+        
+        Collection<Resource> ontologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE);
+        for (Resource ontology : ontologies) {
+            for(Resource module : ModelingUtils.searchByType(graph, ontology, L0.SCLModule))
+                try {
+                    result.add(graph.getURI(module));
+                } catch(DatabaseException e) {
+                    LOGGER.error("Failed to find uri for " + module + ".");
+                }
+        }
+        
+        return result;
+    }
+    
+    @Override
+    public void forAllModules(TObjectProcedure<String> procedure) {
+        THashSet<String> moduleURIs = null;
+        try {
+            moduleURIs = Simantics.getAvailableRequestProcessor().syncRequest(new Read<THashSet<String>>() {
+                @Override
+                public THashSet<String> perform(ReadGraph graph)
+                        throws DatabaseException {
+                    return getAllModules(graph);
+                }
+            });
+            moduleURIs.forEach(procedure);
+        } catch (DatabaseException e) {
+            LOGGER.error("Could not execute procedure {} for all modules {}", procedure, String.valueOf(moduleURIs), e);
+        }
+    }
+    
+    @Override
+    public Collection<String> getModuleNames() {
+        ArrayList<String> result = new ArrayList<>();
+        forAllModules((String name) -> {
+            result.add(name);
+            return true;
+        });
+        return result;
+    }
+}