From: Mathieu Baudier Date: Tue, 16 Feb 2010 20:14:56 +0000 (+0000) Subject: Introduce local osgi resource edition X-Git-Tag: argeo-slc-2.1.7~1418 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=afe680eba2d193e550e4d0a897c1329e9bd533ca;p=gpl%2Fargeo-slc.git Introduce local osgi resource edition git-svn-id: https://svn.argeo.org/slc/trunk@3364 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/ExecutionResources.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/ExecutionResources.java index 53f5af79a..6886a0bd1 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/ExecutionResources.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/ExecutionResources.java @@ -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); } diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/FileExecutionResources.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/FileExecutionResources.java index 0debe45fb..0f3a8dc58 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/FileExecutionResources.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/FileExecutionResources.java @@ -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) { diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java index eb1d8fd41..95154ef0f 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java @@ -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> osCommands = new HashMap>(); private Map osCmds = new HashMap(); @@ -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 index 000000000..7ef87fcde --- /dev/null +++ b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionResources.java @@ -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; + } + +} diff --git a/runtime/org.argeo.slc.support.osgi/src/main/resources/org/argeo/slc/osgi/execution.xml b/runtime/org.argeo.slc.support.osgi/src/main/resources/org/argeo/slc/osgi/execution.xml index f64b0abfb..67b02b37e 100644 --- a/runtime/org.argeo.slc.support.osgi/src/main/resources/org/argeo/slc/osgi/execution.xml +++ b/runtime/org.argeo.slc.support.osgi/src/main/resources/org/argeo/slc/osgi/execution.xml @@ -8,7 +8,8 @@ - @@ -19,4 +20,8 @@ + + + + \ No newline at end of file