From 06ff9fed57c2eeccdcd9167b9f41504cfbe2c49d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Hannu=20Niemist=C3=B6?= Date: Thu, 20 Jul 2017 11:28:54 +0300 Subject: [PATCH] (refs #7374) Created CommandSessionWithModules Change-Id: I6706caaf92018e4ccbf4ad11bd9a58789085fb6a --- .../commands/CommandSessionWithModules.java | 88 +++++++++++++++++++ .../repository/MapModuleSourceRepository.java | 33 +++++++ .../tests/TestCommandSessionWithModules.java | 31 +++++++ 3 files changed, 152 insertions(+) create mode 100644 bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSessionWithModules.java create mode 100644 tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSessionWithModules.java diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSessionWithModules.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSessionWithModules.java new file mode 100644 index 000000000..5ca800a21 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSessionWithModules.java @@ -0,0 +1,88 @@ +package org.simantics.scl.compiler.commands; + + +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; + +import org.simantics.scl.compiler.errors.Failable; +import org.simantics.scl.compiler.errors.Failure; +import org.simantics.scl.compiler.module.Module; +import org.simantics.scl.compiler.module.repository.ModuleRepository; +import org.simantics.scl.compiler.module.repository.UpdateListener; +import org.simantics.scl.compiler.source.StringModuleSource; +import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository; +import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler; +import org.simantics.scl.runtime.reporting.SCLReportingHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CommandSessionWithModules { + private static final Logger LOGGER = LoggerFactory.getLogger(CommandSessionWithModules.class); + + private MapModuleSourceRepository localModuleSourceRepository; + private ModuleRepository moduleRepository; + private CommandSession commandSession; + + private static final SCLReportingHandler DEFAULT_REPORTING_HANDLER = new AbstractSCLReportingHandler() { + @Override + public void print(String text) { + CommandSessionWithModules.LOGGER.info(text); + } + }; + + public CommandSessionWithModules(ModuleRepository parentRepository) { + this.localModuleSourceRepository = new MapModuleSourceRepository(); + this.moduleRepository = new ModuleRepository(parentRepository, localModuleSourceRepository); + this.commandSession = new CommandSession(moduleRepository, DEFAULT_REPORTING_HANDLER); + this.commandSession.setDependenciesListener(new UpdateListener() { + @Override + public void notifyAboutUpdate() { + commandSession.updateRuntimeEnvironment(true); + } + }); + } + + public CommandSession getCommandSession() { + return commandSession; + } + + /** + * Puts the given module to the local module repository. Returns null, if the + * compilation of the module succeeded or a string containing the compilation + * errors, if it failed. + */ + public String putModule(String moduleName, String moduleText) { + StringModuleSource moduleSource = new StringModuleSource(moduleName, moduleText); + synchronized(localModuleSourceRepository) { + localModuleSourceRepository.addModuleDescriptor(moduleSource); + } + Failable module = moduleRepository.getModule(moduleName); + if(module.didSucceed()) + return null; + else + return ((Failure)module).toString(moduleText); + } + + /** + * Runs commands read from commandReader and writes responses to + * responseWriter. + */ + public void runCommands(Reader commandReader, Writer responseWriter) { + SCLReportingHandler handler = new AbstractSCLReportingHandler() { + @Override + public void printCommand(String command) { + // Don't echo commands + } + @Override + public void print(String text) { + try { + responseWriter.write(text + "\n"); + } catch (IOException e) { + CommandSessionWithModules.LOGGER.error("Writing reponse failed.", e); + } + } + }; + commandSession.execute(commandReader, handler); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java index 939010d40..61a1d2c95 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java @@ -1,9 +1,11 @@ package org.simantics.scl.compiler.source.repository; +import java.util.ArrayList; import java.util.Collection; import org.simantics.scl.compiler.module.Module; 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.PrecompiledModuleSource; @@ -21,6 +23,8 @@ public class MapModuleSourceRepository implements ModuleSourceRepository { THashMap modules = new THashMap(); THashMap documentations = new THashMap(); + THashMap> listeners = new THashMap>(); + public MapModuleSourceRepository() { } @@ -36,6 +40,12 @@ public class MapModuleSourceRepository implements ModuleSourceRepository { public void addModuleDescriptor(ModuleSource descriptor) { modules.put(descriptor.getModuleName(), descriptor); + synchronized (listeners) { + ArrayList list = listeners.get(descriptor.getModuleName()); + if(list != null) + for(UpdateListener listener : list.toArray(new UpdateListener[list.size()])) + listener.notifyAboutUpdate(); + } } public void addModule(Module module) { @@ -49,6 +59,29 @@ public class MapModuleSourceRepository implements ModuleSourceRepository { @Override public ModuleSource getModuleSource(String moduleName, UpdateListener listener) { + if(listener != null) { + synchronized(listeners) { + ArrayList list = listeners.get(moduleName); + if(list == null) { + list = new ArrayList(2); + listeners.put(moduleName, list); + } + list.add(listener); + } + listener.addObservable(new Observable() { + @Override + public void removeListener(UpdateListener listener) { + synchronized(listeners) { + ArrayList list = listeners.get(moduleName); + if(list != null) { + list.remove(listener); + if(list.isEmpty()) + listeners.remove(moduleName); + } + } + } + }); + } return modules.get(moduleName); } diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSessionWithModules.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSessionWithModules.java new file mode 100644 index 000000000..9e8c14ecb --- /dev/null +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSessionWithModules.java @@ -0,0 +1,31 @@ +package org.simantics.scl.compiler.tests; + +import java.io.StringReader; +import java.io.StringWriter; + +import org.junit.Assert; +import org.junit.Test; +import org.simantics.scl.compiler.commands.CommandSessionWithModules; +import org.simantics.scl.osgi.SCLOsgi; + +public class TestCommandSessionWithModules { + @Test + public void testCommandSessionWithModules() { + CommandSessionWithModules session = new CommandSessionWithModules(SCLOsgi.MODULE_REPOSITORY); + session.putModule("My/Test/Module", "someValue = 13"); + + { + StringWriter writer = new StringWriter(); + session.runCommands(new StringReader("import \"My/Test/Module\"\nsomeValue"), writer); + Assert.assertEquals("13\n", writer.toString()); + } + + session.putModule("My/Test/Module", "someValue = 14"); + + { + StringWriter writer = new StringWriter(); + session.runCommands(new StringReader("someValue\nsomeValue+1"), writer); + Assert.assertEquals("14\n15\n", writer.toString()); + } + } +} -- 2.47.1