X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.modeling%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fscl%2FGraphModuleSourceRepository.java;h=a70844cd375c8956adb593cb71406e92d782e963;hp=a615634118fc2a586bfe4bae0e15c1ae4dd9b9b0;hb=4af526406642ed67a61c7cae4edc673a21aec8f5;hpb=86e91ef31d25e4d5950cae130754846d15119c61 diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java index a61563411..a70844cd3 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java @@ -1,205 +1,255 @@ -package org.simantics.modeling.scl; - -import java.util.Collection; - -import org.simantics.Simantics; -import org.simantics.db.ReadGraph; -import org.simantics.db.RequestProcessorSpecific; -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.layer0.Layer0; -import org.simantics.modeling.ModelingUtils; -import org.simantics.scl.compiler.module.repository.UpdateListener; -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.runtime.SCLContext; -import org.simantics.scl.runtime.tuple.Tuple0; - -import gnu.trove.procedure.TObjectProcedure; -import gnu.trove.set.hash.THashSet; - -public enum GraphModuleSourceRepository implements ModuleSourceRepository { - INSTANCE; - - @Override - public ModuleSource getModuleSource(final String moduleName, UpdateListener listener) { - if(!moduleName.startsWith("http://")) - return null; - - Object graph = SCLContext.getCurrent().get("graph"); - RequestProcessorSpecific requestProcessor; - if(graph instanceof ReadGraph) - requestProcessor = (ReadGraph)graph; - else - requestProcessor = Simantics.getSession(); - - Read request = new ReadModuleSource(moduleName); - - try { - if(listener != null) - return requestProcessor.syncRequest(request, new ModuleListener(listener, moduleName)); - else - return requestProcessor.syncRequest(request); - } catch (DatabaseException e) { - e.printStackTrace(); - return null; - } - } - - static class ModuleListener implements SyncListener { - UpdateListener listener; - boolean alreadyExecutedOnce; - final String moduleName; - public ModuleListener(UpdateListener listener, String moduleName) { - this.listener = listener; - this.moduleName = moduleName; - } - @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 { - t.printStackTrace(); - if(alreadyExecutedOnce && listener != null) - fireUpdate(graph); - } - }; - - public static class GraphModuleSource extends StringModuleSource { - - public GraphModuleSource(String moduleName, ClassLoader classLoader, String moduleText) { - super(moduleName, classLoader, moduleText); - } - - @Override - public boolean isUpdateable() { - return true; - } - - @Override - public void update(String newSourceText) { - try { - Simantics.getSession().syncRequest(new WriteModuleSource(getModuleName(), newSourceText)); - } catch (DatabaseException e) { - e.printStackTrace(); - } - } - } - - static class ReadModuleSource extends UnaryRead { - public ReadModuleSource(String moduleName) { - super(moduleName); - } - - @Override - public ModuleSource perform(ReadGraph graph) throws DatabaseException { - Resource moduleResource = graph.getPossibleResource(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); - return new GraphModuleSource(parameter, getClass().getClassLoader(), text); - } - } - - 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); - } - } - - @Override - public void forAllModules(TObjectProcedure procedure) { - THashSet moduleURIs; - try { - moduleURIs = Simantics.getSession().syncRequest(new Read>() { - @Override - public THashSet perform(ReadGraph graph) - throws DatabaseException { - THashSet result = new THashSet(); - 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 ontologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); - for (Resource ontology : ontologies) { - for(Resource module : ModelingUtils.searchByType(graph, ontology, L0.SCLModule)) - result.add(graph.getURI(module)); - } - - return result; - } - }); - moduleURIs.forEach(procedure); - } catch (DatabaseException e) { - e.printStackTrace(); - } - } - - @Override - public void checkUpdates() { - } - - @Override - public String getDocumentation(String documentationName) { - return null; - } - - @Override - public void forAllDocumentations(TObjectProcedure procedure) { - } - - @Override - public void clear() { - } -} +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 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, 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 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 { + 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 getAllModules(ReadGraph graph) throws DatabaseException { + THashSet result = new THashSet(); + 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 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 procedure) { + THashSet moduleURIs = null; + try { + moduleURIs = Simantics.getAvailableRequestProcessor().syncRequest(new Read>() { + @Override + public THashSet 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 getModuleNames() { + ArrayList result = new ArrayList<>(); + forAllModules((String name) -> { + result.add(name); + return true; + }); + return result; + } +}