--- /dev/null
+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> 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);
+ }
+}
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;
THashMap<String, ModuleSource> modules = new THashMap<String, ModuleSource>();
THashMap<String, String> documentations = new THashMap<String, String>();
+ THashMap<String, ArrayList<UpdateListener>> listeners = new THashMap<String, ArrayList<UpdateListener>>();
+
public MapModuleSourceRepository() {
}
public void addModuleDescriptor(ModuleSource descriptor) {
modules.put(descriptor.getModuleName(), descriptor);
+ synchronized (listeners) {
+ ArrayList<UpdateListener> list = listeners.get(descriptor.getModuleName());
+ if(list != null)
+ for(UpdateListener listener : list.toArray(new UpdateListener[list.size()]))
+ listener.notifyAboutUpdate();
+ }
}
public void addModule(Module module) {
@Override
public ModuleSource getModuleSource(String moduleName,
UpdateListener listener) {
+ if(listener != null) {
+ synchronized(listeners) {
+ ArrayList<UpdateListener> list = listeners.get(moduleName);
+ if(list == null) {
+ list = new ArrayList<UpdateListener>(2);
+ listeners.put(moduleName, list);
+ }
+ list.add(listener);
+ }
+ listener.addObservable(new Observable() {
+ @Override
+ public void removeListener(UpdateListener listener) {
+ synchronized(listeners) {
+ ArrayList<UpdateListener> list = listeners.get(moduleName);
+ if(list != null) {
+ list.remove(listener);
+ if(list.isEmpty())
+ listeners.remove(moduleName);
+ }
+ }
+ }
+ });
+ }
return modules.get(moduleName);
}
--- /dev/null
+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());
+ }
+ }
+}