--- /dev/null
+package org.simantics.modeling.scl;\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
+\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
+ public GraphModuleSource(String moduleName, ClassLoader classLoader, String moduleText) {\r
+ super(moduleName, classLoader, moduleText);\r
+ }\r
+ \r
+ @Override\r
+ public boolean isUpdateable() {\r
+ return true;\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
+ return new GraphModuleSource(parameter, getClass().getClassLoader(), text);\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
+ 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