]> git.argeo.org Git - gpl/argeo-slc.git/commitdiff
Introduce local osgi resource edition
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 16 Feb 2010 20:14:56 +0000 (20:14 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 16 Feb 2010 20:14:56 +0000 (20:14 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@3364 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/ExecutionResources.java
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/FileExecutionResources.java
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java
runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionResources.java [new file with mode: 0644]
runtime/org.argeo.slc.support.osgi/src/main/resources/org/argeo/slc/osgi/execution.xml

index 53f5af79af837377fe9f409863813af7c75d7b91..6886a0bd129cbcb04ee40a06e215ebbbb11ed9e3 100644 (file)
@@ -3,7 +3,13 @@ package org.argeo.slc.core.execution;
 import org.springframework.core.io.Resource;
 
 public interface ExecutionResources {
+       /** Allocates a local file in the writable area and return it as a resource. */
        public Resource getWritableResource(String relativePath);
 
+       /**
+        * Returns the resource as a file path. If the resource is not writable it
+        * is copied as a file in the writable area and the path to this local file
+        * is returned.
+        */
        public String getAsOsPath(Resource resource, Boolean overwrite);
 }
index 0debe45fbd857da89c54fdf61c8f79b21935c4f4..0f3a8dc5841051cca98785f68c2967e8280ea66b 100644 (file)
@@ -80,17 +80,17 @@ public class FileExecutionResources implements ExecutionResources {
        }
 
        public String getAsOsPath(Resource resource, Boolean overwrite) {
-               File file = null;
-               try {
-                       file = resource.getFile();
-                       return file.getCanonicalPath();
-               } catch (IOException e) {
-                       if (log.isTraceEnabled())
-                               log
-                                               .trace("Resource "
-                                                               + resource
-                                                               + " is not available on the file system. Retrieving it...");
-               }
+               File file = fileFromResource(resource);
+               if (file != null)
+                       try {
+                               return file.getCanonicalPath();
+                       } catch (IOException e1) {
+                               // silent
+                       }
+
+               if (log.isTraceEnabled())
+                       log.trace("Resource " + resource
+                                       + " is not available on the file system. Retrieving it...");
 
                InputStream in = null;
                OutputStream out = null;
@@ -116,6 +116,20 @@ public class FileExecutionResources implements ExecutionResources {
                }
        }
 
+       /**
+        * Extract the underlying file from the resource.
+        * 
+        * @return the file or null if no files support this resource.
+        */
+       protected File fileFromResource(Resource resource) {
+               try {
+                       return resource.getFile();
+               } catch (IOException e) {
+                       return null;
+               }
+
+       }
+
        public File getFile(String relativePath) {
 
                if (withExecutionSubdirectory) {
index eb1d8fd41463128cb1fb4e22c7a4e845ab478057..95154ef0f6fcccdf312b1dc910b6052600ba97d5 100644 (file)
@@ -1,6 +1,7 @@
 package org.argeo.slc.core.execution.tasks;
 
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
@@ -27,6 +28,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.SlcException;
 import org.argeo.slc.UnsupportedException;
+import org.argeo.slc.core.execution.ExecutionResources;
 import org.argeo.slc.core.structure.tree.TreeSRelatedHelper;
 import org.argeo.slc.core.test.SimpleResultPart;
 import org.argeo.slc.test.TestResult;
@@ -50,6 +52,7 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
        private Resource stdOutFile = null;
        private Resource stdErrFile = null;
        private Resource stdInFile = null;
+       private Boolean redirectStdOut = false;
 
        private Map<String, List<Object>> osCommands = new HashMap<String, List<Object>>();
        private Map<String, String> osCmds = new HashMap<String, String>();
@@ -67,6 +70,8 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
 
        private TestResult testResult;
 
+       private ExecutionResources executionResources;
+
        /** Empty constructor */
        public SystemCall() {
 
@@ -102,23 +107,21 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
        /** Executes the system call. */
        public void run() {
                // Manage streams
-               final Writer stdOutWriter;
-               final Writer stdErrWriter;
-               final InputStream stdInStream;
-               if (stdOutFile != null) {
-                       stdOutWriter = createWriter(stdOutFile);
-               } else {
-                       stdOutWriter = null;
-               }
+               Writer stdOutWriter = null;
+               OutputStream stdOutputStream = null;
+               Writer stdErrWriter = null;
+               InputStream stdInStream = null;
+               if (stdOutFile != null)
+                       if (redirectStdOut)
+                               stdOutputStream = createOutputStream(stdOutFile);
+                       else
+                               stdOutWriter = createWriter(stdOutFile, true);
 
                if (stdErrFile != null) {
-                       stdErrWriter = createWriter(stdErrFile);
+                       stdErrWriter = createWriter(stdErrFile, true);
                } else {
-                       if (stdOutFile != null) {
-                               stdErrWriter = createWriter(stdOutFile);
-                       } else {
-                               stdErrWriter = null;
-                       }
+                       if (stdOutFile != null && !redirectStdOut)
+                               stdErrWriter = createWriter(stdOutFile, true);
                }
 
                if (stdInFile != null)
@@ -128,8 +131,6 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                                throw new SlcException("Cannot open a stream for " + stdInFile,
                                                e2);
                        }
-               else
-                       stdInStream = null;
 
                if (log.isTraceEnabled()) {
                        log.debug("os.name=" + System.getProperty("os.name"));
@@ -149,7 +150,7 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                if (redirectStreams) {
                        // Redirect standard streams
                        executor.setStreamHandler(createExecuteStreamHandler(stdOutWriter,
-                                       stdErrWriter, stdInStream));
+                                       stdOutputStream, stdErrWriter, stdInStream));
                } else {
                        // Dummy stream handler (otherwise pump is used)
                        executor.setStreamHandler(new DummyexecuteStreamHandler());
@@ -271,19 +272,20 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
         * logging mechanism.
         */
        protected ExecuteStreamHandler createExecuteStreamHandler(
-                       final Writer stdOutWriter, final Writer stdErrWriter,
-                       final InputStream stdInStream) {
+                       final Writer stdOutWriter, final OutputStream stdOutputStream,
+                       final Writer stdErrWriter, final InputStream stdInStream) {
 
                // Log writers
 
                PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(
-                               new LogOutputStream() {
-                                       protected void processLine(String line, int level) {
-                                               log(stdOutLogLevel, line);
-                                               if (stdOutWriter != null)
-                                                       appendLineToFile(stdOutWriter, line);
-                                       }
-                               }, new LogOutputStream() {
+                               stdOutputStream != null ? stdOutputStream
+                                               : new LogOutputStream() {
+                                                       protected void processLine(String line, int level) {
+                                                               log(stdOutLogLevel, line);
+                                                               if (stdOutWriter != null)
+                                                                       appendLineToFile(stdOutWriter, line);
+                                                       }
+                                               }, new LogOutputStream() {
                                        protected void processLine(String line, int level) {
                                                log(stdErrLogLevel, line);
                                                if (stdErrWriter != null)
@@ -377,19 +379,42 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                }
        }
 
-       /** Creates the writer for the log files. */
-       protected Writer createWriter(Resource target) {
+       /** Creates the writer for the output/err files. */
+       protected Writer createWriter(Resource target, Boolean append) {
                FileWriter writer = null;
                try {
-                       File file = target.getFile();
-                       writer = new FileWriter(file, true);
+
+                       final File file;
+                       if (executionResources != null)
+                               file = new File(executionResources.getAsOsPath(target, true));
+                       else
+                               file = target.getFile();
+                       writer = new FileWriter(file, append);
                } catch (IOException e) {
-                       log.error("Cannot create log file " + target, e);
+                       log.error("Cannot get file for " + target, e);
                        IOUtils.closeQuietly(writer);
                }
                return writer;
        }
 
+       /** Creates an outputstream for the output/err files. */
+       protected OutputStream createOutputStream(Resource target) {
+               FileOutputStream OutputStream = null;
+               try {
+
+                       final File file;
+                       if (executionResources != null)
+                               file = new File(executionResources.getAsOsPath(target, true));
+                       else
+                               file = target.getFile();
+                       OutputStream = new FileOutputStream(file, false);
+               } catch (IOException e) {
+                       log.error("Cannot get file for " + target, e);
+                       IOUtils.closeQuietly(OutputStream);
+               }
+               return OutputStream;
+       }
+
        /** Append the argument (for chaining) */
        public SystemCall arg(String arg) {
                command.add(arg);
@@ -484,6 +509,14 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                this.generateScript = generateScript;
        }
 
+       public void setExecutionResources(ExecutionResources executionResources) {
+               this.executionResources = executionResources;
+       }
+
+       public void setRedirectStdOut(Boolean redirectStdOut) {
+               this.redirectStdOut = redirectStdOut;
+       }
+
        private class DummyexecuteStreamHandler implements ExecuteStreamHandler {
 
                public void setProcessErrorStream(InputStream is) throws IOException {
diff --git a/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionResources.java b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionResources.java
new file mode 100644 (file)
index 0000000..7ef87fc
--- /dev/null
@@ -0,0 +1,76 @@
+package org.argeo.slc.osgi;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.FileExecutionResources;
+import org.osgi.framework.BundleContext;
+import org.springframework.core.io.Resource;
+import org.springframework.osgi.context.BundleContextAware;
+import org.springframework.osgi.io.OsgiBundleResource;
+
+public class OsgiExecutionResources extends FileExecutionResources implements
+               BundleContextAware {
+       private final static Log log = LogFactory
+                       .getLog(OsgiExecutionResources.class);
+
+       private BundleContext bundleContext;
+
+       @Override
+       protected File fileFromResource(Resource resource) {
+               File file = super.fileFromResource(resource);
+               if (file != null)
+                       return file;
+
+               if (!(resource instanceof OsgiBundleResource))
+                       return null;
+
+               OsgiBundleResource osgiBundleResource = (OsgiBundleResource) resource;
+               try {
+                       return osgiBundleResource.getFile();
+               } catch (IOException e) {
+                       if (log.isTraceEnabled())
+                               log.trace("Resource " + resource
+                                               + " is not available on the file system: " + e);
+               }
+
+               // TODO: ability to access resources in other bundles
+               String location = bundleContext.getBundle().getLocation();
+               String base = null;
+               if (location.startsWith("reference:file:"))
+                       base = location.substring("reference:file:".length());
+               else if (location.startsWith("initial@reference:file:")) {
+                       // TODO: Equinox specific?
+                       String relPath = location.substring("initial@reference:file:"
+                                       .length());
+                       if (relPath.startsWith("../"))// relative to the framework jar
+                               relPath = relPath.substring("../".length());
+                       String framework = System.getProperty("osgi.framework").substring(
+                                       "file:".length());
+                       int sepIndex = framework.lastIndexOf(File.separatorChar);
+                       framework = framework.substring(0, sepIndex);
+                       base = framework + '/' + relPath;
+               } else {
+                       return null;
+               }
+
+               String path = base + '/' + osgiBundleResource.getPathWithinContext();
+               try {
+                       file = new File(path).getCanonicalFile();
+               } catch (IOException e) {
+                       throw new SlcException("Cannot determine canonical path for "
+                                       + path, e);
+               }
+               if (log.isDebugEnabled())
+                       log.debug("OSGi local resource: " + file + " from " + resource);
+               return file;
+       }
+
+       public void setBundleContext(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+       }
+
+}
index f64b0abfb5d986504c7433c8c6e900bb26491317..67b02b37eb184ffcad6ea4a754d92a7c3df80d90 100644 (file)
@@ -8,7 +8,8 @@
 
        <osgi:service interface="org.argeo.slc.execution.ExecutionContext"
                ref="executionContext" />
-       <osgi:service interface="org.argeo.slc.execution.ExecutionFlowDescriptorConverter"
+       <osgi:service
+               interface="org.argeo.slc.execution.ExecutionFlowDescriptorConverter"
                ref="executionFlowDescriptorConverter" />
 
        <bean class="org.argeo.slc.osgi.MultipleServiceExporterPostProcessor">
@@ -19,4 +20,8 @@
                        </list>
                </property>
        </bean>
+
+       <bean id="osgiExecutionResources" class="org.argeo.slc.osgi.OsgiExecutionResources">
+               <property name="executionContext" ref="executionContext" />
+       </bean>
 </beans>
\ No newline at end of file