(refs #7374) Created CommandSessionWithModules 33/733/1
authorHannu Niemistö <hannu.niemisto@semantum.fi>
Thu, 20 Jul 2017 08:28:54 +0000 (11:28 +0300)
committerHannu Niemistö <hannu.niemisto@semantum.fi>
Thu, 20 Jul 2017 08:28:54 +0000 (11:28 +0300)
Change-Id: I6706caaf92018e4ccbf4ad11bd9a58789085fb6a

bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSessionWithModules.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSessionWithModules.java [new file with mode: 0644]

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 (file)
index 0000000..5ca800a
--- /dev/null
@@ -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> 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);
+    }
+}
index 939010d40bc9392db981081bfbdb52496344fcf2..61a1d2c958526db87ef442d0155bafe1bbf6a602 100644 (file)
@@ -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<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() {
     }
     
@@ -36,6 +40,12 @@ public class MapModuleSourceRepository implements ModuleSourceRepository {
     
     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) {
@@ -49,6 +59,29 @@ public class MapModuleSourceRepository implements ModuleSourceRepository {
     @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);
     }
 
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 (file)
index 0000000..9e8c14e
--- /dev/null
@@ -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());
+        }
+    }
+}