From 8279efc2b92ba454b24ad4d06e7878b00836c07d Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 22 Nov 2008 11:42:24 +0000 Subject: [PATCH] Move org.argeo.slc.detached git-svn-id: https://svn.argeo.org/slc/trunk@1849 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- runtime/org.argeo.slc.detached/.classpath | 8 + runtime/org.argeo.slc.detached/.project | 23 ++ .../.settings/org.eclipse.jdt.core.prefs | 12 + .../.settings/org.maven.ide.eclipse.prefs | 9 + runtime/org.argeo.slc.detached/pom.xml | 106 ++++++++ .../org/argeo/slc/detached/AppLauncher.java | 62 +++++ .../slc/detached/DetachedAdminCommand.java | 5 + .../argeo/slc/detached/DetachedAnswer.java | 85 ++++++ .../argeo/slc/detached/DetachedClient.java | 8 + .../slc/detached/DetachedCommunication.java | 7 + .../argeo/slc/detached/DetachedContext.java | 13 + .../slc/detached/DetachedContextImpl.java | 33 +++ .../argeo/slc/detached/DetachedDriver.java | 7 + .../argeo/slc/detached/DetachedException.java | 13 + .../slc/detached/DetachedExecutionServer.java | 5 + .../detached/DetachedExecutionServerImpl.java | 199 ++++++++++++++ .../argeo/slc/detached/DetachedRequest.java | 52 ++++ .../argeo/slc/detached/DetachedSession.java | 50 ++++ .../org/argeo/slc/detached/DetachedStep.java | 7 + .../slc/detached/DetachedXmlConverter.java | 11 + .../detached/DetachedXmlConverterCompat.java | 160 ++++++++++++ .../slc/detached/admin/CloseSession.java | 7 + .../slc/detached/admin/FelixShellCommand.java | 30 +++ .../argeo/slc/detached/admin/OpenSession.java | 57 ++++ .../slc/detached/drivers/AbstractDriver.java | 76 ++++++ .../slc/detached/drivers/FileDriver.java | 243 ++++++++++++++++++ .../org/argeo/slc/detached/ui/UiPart.java | 32 +++ .../org/argeo/slc/detached/ui/UiStep.java | 29 +++ .../src/main/resources/META-INF/MANIFEST.MF | 37 +++ .../META-INF/spring/slc-detached-osgi.xml | 16 ++ .../META-INF/spring/slc-detached.xml | 17 ++ .../org/argeo/slc/detached/slc-detached.xsd | 63 +++++ .../org/argeo/slc/detached/spring.xml | 20 ++ 33 files changed, 1502 insertions(+) create mode 100644 runtime/org.argeo.slc.detached/.classpath create mode 100644 runtime/org.argeo.slc.detached/.project create mode 100644 runtime/org.argeo.slc.detached/.settings/org.eclipse.jdt.core.prefs create mode 100644 runtime/org.argeo.slc.detached/.settings/org.maven.ide.eclipse.prefs create mode 100644 runtime/org.argeo.slc.detached/pom.xml create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/AppLauncher.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedAdminCommand.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedAnswer.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedClient.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedCommunication.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedContext.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedContextImpl.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedDriver.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedException.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServer.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedRequest.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedSession.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedStep.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedXmlConverter.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedXmlConverterCompat.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/CloseSession.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/FelixShellCommand.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/OpenSession.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/drivers/AbstractDriver.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/drivers/FileDriver.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/ui/UiPart.java create mode 100644 runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/ui/UiStep.java create mode 100644 runtime/org.argeo.slc.detached/src/main/resources/META-INF/MANIFEST.MF create mode 100644 runtime/org.argeo.slc.detached/src/main/resources/META-INF/spring/slc-detached-osgi.xml create mode 100644 runtime/org.argeo.slc.detached/src/main/resources/META-INF/spring/slc-detached.xml create mode 100644 runtime/org.argeo.slc.detached/src/main/resources/org/argeo/slc/detached/slc-detached.xsd create mode 100644 runtime/org.argeo.slc.detached/src/main/resources/org/argeo/slc/detached/spring.xml diff --git a/runtime/org.argeo.slc.detached/.classpath b/runtime/org.argeo.slc.detached/.classpath new file mode 100644 index 000000000..b606f1820 --- /dev/null +++ b/runtime/org.argeo.slc.detached/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/runtime/org.argeo.slc.detached/.project b/runtime/org.argeo.slc.detached/.project new file mode 100644 index 000000000..5757ba736 --- /dev/null +++ b/runtime/org.argeo.slc.detached/.project @@ -0,0 +1,23 @@ + + + org.argeo.slc.detached + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.maven.ide.eclipse.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.maven.ide.eclipse.maven2Nature + + diff --git a/runtime/org.argeo.slc.detached/.settings/org.eclipse.jdt.core.prefs b/runtime/org.argeo.slc.detached/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..134aca25f --- /dev/null +++ b/runtime/org.argeo.slc.detached/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Mon Nov 17 12:10:39 CET 2008 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.4 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning +org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning +org.eclipse.jdt.core.compiler.source=1.3 diff --git a/runtime/org.argeo.slc.detached/.settings/org.maven.ide.eclipse.prefs b/runtime/org.argeo.slc.detached/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..78b8c9f89 --- /dev/null +++ b/runtime/org.argeo.slc.detached/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Thu Sep 18 18:28:43 CEST 2008 +activeProfiles= +eclipse.preferences.version=1 +filterResources=false +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +useMavenFolders=false +version=1 diff --git a/runtime/org.argeo.slc.detached/pom.xml b/runtime/org.argeo.slc.detached/pom.xml new file mode 100644 index 000000000..1ecdbe0af --- /dev/null +++ b/runtime/org.argeo.slc.detached/pom.xml @@ -0,0 +1,106 @@ + + 4.0.0 + + org.argeo.slc + argeo-slc + 0.11.2-SNAPSHOT + ../org.argeo.slc + + org.argeo.slc.detached + Argeo SLC Detached + jar + + + + maven-jar-plugin + + + org.apache.felix + maven-bundle-plugin + + + + org.argeo.slc.detached.* + + + *, + org.springframework.beans.factory;version="2.0", + org.springframework.beans.factory.support;version="2.0", + org.springframework.beans.factory.xml;version="2.0", + org.springframework.context;version="2.0", + org.springframework.context.support;version="2.0", + org.springframework.core.io;version="2.0" + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.3 + 1.3 + + + + org.apache.maven.plugins + maven-source-plugin + + + + + + org.eclipse.osgi + org.eclipse.osgi + + + + org.springframework.osgi + org.springframework.osgi.extender + + + + + edu.emory.mathcs.backport + com.springsource.edu.emory.mathcs.backport + + + + + + + org.apache.xmlcommons + com.springsource.org.apache.xmlcommons + provided + + + + + org.apache.commons + + com.springsource.org.apache.commons.io + + + + org.junit + com.springsource.junit + test + + + org.apache.log4j + com.springsource.org.apache.log4j + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/AppLauncher.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/AppLauncher.java new file mode 100644 index 000000000..d2e1ff51e --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/AppLauncher.java @@ -0,0 +1,62 @@ +package org.argeo.slc.detached; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +public class AppLauncher { + private Properties systemProperties = new Properties(); + private String mainClass = null; + private List arguments = new ArrayList(); + + public void launch() { + + Properties base = System.getProperties(); + Properties fake = new Properties(base); + + try { + if (mainClass == null) + throw new DetachedException( + "A main class name has to be specified."); + + System.getProperties().putAll(systemProperties); + + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Class clss = cl.loadClass(mainClass); + + String[] args = new String[arguments.size()]; + for (int i = 0; i < arguments.size(); i++) { + args[i] = arguments.get(i).toString(); + } + + Class[] mainArgsClasses = new Class[] { args.getClass() }; + Object[] mainArgs = { args }; + Method mainMethod = clss.getMethod("main", mainArgsClasses); + + System.setProperties(fake); + + mainMethod.invoke(null, mainArgs); + + } catch (Exception e) { + throw new DetachedException("Unexpected exception while launching " + + mainClass, e); + } finally { + System.setProperties(base); + } + + } + + public void setSystemProperties(Properties systemProperties) { + this.systemProperties = systemProperties; + } + + public void setMainClass(String mainClass) { + this.mainClass = mainClass; + } + + public void setArguments(List arguments) { + this.arguments = arguments; + } + +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedAdminCommand.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedAdminCommand.java new file mode 100644 index 000000000..6407ee5f6 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedAdminCommand.java @@ -0,0 +1,5 @@ +package org.argeo.slc.detached; + +public interface DetachedAdminCommand { + +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedAnswer.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedAnswer.java new file mode 100644 index 000000000..55789a046 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedAnswer.java @@ -0,0 +1,85 @@ +package org.argeo.slc.detached; + +import java.util.Properties; + +public class DetachedAnswer implements DetachedCommunication { + static final long serialVersionUID = 1l; + + public final static int UNKOWN = -1; + public final static int PROCESSED = 0; + public final static int ERROR = 1; + public final static int SKIPPED = 2; + public final static int CLOSED_SESSION = 10; + + private Properties properties = new Properties(); + private int status = UNKOWN; + private String log; + private String uuid; + + public DetachedAnswer() { + + } + + public DetachedAnswer(DetachedRequest request) { + uuid = request.getUuid(); + } + + public DetachedAnswer(DetachedRequest request, String message) { + this(request); + log = message; + status = PROCESSED; + } + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties outputParameters) { + this.properties = outputParameters; + } + + public int getStatus() { + return status; + } + + public void setStatus(int outputStatus) { + this.status = outputStatus; + } + + public String getLog() { + return log; + } + + public void setLog(String log) { + this.log = log; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getStatusAsString() { + return convertStatus(getStatus()); + } + + public static String convertStatus(int status) { + switch (status) { + case UNKOWN: + return "UNKOWN"; + case PROCESSED: + return "PROCESSED"; + case SKIPPED: + return "SKIPPED"; + case ERROR: + return "ERROR"; + case CLOSED_SESSION: + return "CLOSED_SESSION"; + default: + throw new DetachedException("Unkown status " + status); + } + } +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedClient.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedClient.java new file mode 100644 index 000000000..3c7503253 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedClient.java @@ -0,0 +1,8 @@ +package org.argeo.slc.detached; + +public interface DetachedClient { + public void sendRequest(DetachedRequest request) throws Exception; + + /** Blocks until next answer. */ + public DetachedAnswer receiveAnswer() throws Exception; +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedCommunication.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedCommunication.java new file mode 100644 index 000000000..8bdba36e2 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedCommunication.java @@ -0,0 +1,7 @@ +package org.argeo.slc.detached; + +import java.io.Serializable; + +public interface DetachedCommunication extends Serializable { + public String getUuid(); +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedContext.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedContext.java new file mode 100644 index 000000000..1ac3690b0 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedContext.java @@ -0,0 +1,13 @@ +package org.argeo.slc.detached; + +import java.util.List; + +public interface DetachedContext { + public Object getDynamicRef(String ref); + + public void setDynamicRef(String ref, Object obj); + + public String getCurrentPath(); + + public List getExecutedPaths(); +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedContextImpl.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedContextImpl.java new file mode 100644 index 000000000..595b3379c --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedContextImpl.java @@ -0,0 +1,33 @@ +package org.argeo.slc.detached; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.Vector; + +public class DetachedContextImpl implements DetachedContext { + private List executedPaths = new Vector(); + private String currentPath; + private Map dynamicRefs = new TreeMap(); + + public String getCurrentPath() { + return currentPath; + } + + public void setDynamicRef(String ref, Object obj) { + dynamicRefs.put(ref, obj); + } + + public Object getDynamicRef(String ref) { + if (dynamicRefs.containsKey(ref)) + return dynamicRefs.get(ref); + else + return null; + } + + public List getExecutedPaths() { + return new ArrayList(executedPaths); + } + +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedDriver.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedDriver.java new file mode 100644 index 000000000..08791a8a2 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedDriver.java @@ -0,0 +1,7 @@ +package org.argeo.slc.detached; + +public interface DetachedDriver { + /** Blocks until it receives a request. */ + public DetachedRequest receiveRequest() throws Exception; + public void sendAnswer(DetachedAnswer answer) throws Exception; +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedException.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedException.java new file mode 100644 index 000000000..dc39ec8ab --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedException.java @@ -0,0 +1,13 @@ +package org.argeo.slc.detached; + +public class DetachedException extends RuntimeException { + static final long serialVersionUID = 1l; + + public DetachedException(String message) { + super(message); + } + + public DetachedException(String message, Exception cause) { + super(message, cause); + } +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServer.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServer.java new file mode 100644 index 000000000..ec5f3c506 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServer.java @@ -0,0 +1,5 @@ +package org.argeo.slc.detached; + +public interface DetachedExecutionServer { + public DetachedAnswer executeRequest(DetachedRequest request); +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java new file mode 100644 index 000000000..35b9d63d5 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java @@ -0,0 +1,199 @@ +package org.argeo.slc.detached; + +import java.util.List; +import java.util.Vector; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.detached.admin.CloseSession; +import org.argeo.slc.detached.admin.OpenSession; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.springframework.context.ApplicationContext; +import org.springframework.osgi.context.BundleContextAware; + +public class DetachedExecutionServerImpl implements DetachedExecutionServer, + BundleContextAware { + private final static Log log = LogFactory + .getLog(DetachedExecutionServerImpl.class); + + private final DetachedContextImpl detachedContext; + private final List sessions; + + private int skipCount = 1;// start skipCount at 1 since the first step is + // always an open session + + private BundleContext bundleContext; + + public DetachedExecutionServerImpl() { + detachedContext = new DetachedContextImpl(); + sessions = new Vector(); + } + + public synchronized DetachedAnswer executeRequest(DetachedRequest request) { + DetachedAnswer answer = null; + try { + // Find action + ServiceReference[] refs = bundleContext.getAllServiceReferences( + ApplicationContext.class.getName(), null); + Object obj = null; + for (int i = 0; i < refs.length; i++) { + ApplicationContext appContext = (ApplicationContext) bundleContext + .getService(refs[i]); + try { + obj = appContext.getBean(request.getRef()); + } catch (Exception e) { + // silent + if (log.isTraceEnabled()) + log.trace("Could not find ref " + request.getRef(), e); + } + if (obj != null) { + break; + } + } + + if (obj == null) + throw new DetachedException("Could not find action with ref " + + request.getRef()); + + // Execute actions + if (obj instanceof DetachedStep) { + answer = processStep((DetachedStep) obj, request); + + } else if (obj instanceof DetachedAdminCommand) { + answer = processAdminCommand((DetachedAdminCommand) obj, + request); + } + + if (answer == null) { + throw new DetachedException("Unknown action type " + + obj.getClass() + " for action with ref " + + request.getRef()); + } + } catch (Exception e) { + answer = new DetachedAnswer(request); + answer.setStatus(DetachedAnswer.ERROR); + answer.setLog(e.getMessage()); + } + getCurrentSession().getRequests().add(request); + getCurrentSession().getAnswers().add(answer); + if (log.isDebugEnabled()) + log.debug("Processed '" + request.getRef() + "' (status=" + + answer.getStatusAsString() + ", path=" + + request.getPath() + ")"); + return answer; + } + + protected DetachedAnswer processStep(DetachedStep obj, + DetachedRequest request) { + DetachedAnswer answer; + if (getCurrentSession() == null) + throw new DetachedException("No open session."); + + StringBuffer skippedLog = new StringBuffer(); + boolean execute = true; + if (getPreviousSession() != null && !getPreviousSession().isClosed()) { + if (getCurrentSession().getDoItAgainPolicy().equals( + DetachedSession.SKIP_UNTIL_ERROR)) { + // Skip execution of already successful steps + if (getPreviousSession().getAnswers().size() > skipCount) { + DetachedAnswer previousAnswer = (DetachedAnswer) getPreviousSession() + .getAnswers().get(skipCount); + DetachedRequest previousRequest = (DetachedRequest) getPreviousSession() + .getRequests().get(skipCount); + // Check paths + if (!previousRequest.getPath().equals(request.getPath())) { + String msg = "New request is not consistent with previous path. previousPath=" + + previousRequest.getPath() + + ", newPath=" + + request.getPath() + "\n"; + skippedLog.append(msg); + log.warn(msg); + } + + if (previousAnswer.getStatus() != DetachedAnswer.ERROR) { + execute = false; + String msg = "Skipped path " + request.getPath() + + " (skipCount=" + skipCount + ")"; + skippedLog.append(msg); + log.info(msg); + skipCount++; + } else { + log + .info("Path " + + request.getPath() + + " was previously in error, executing it again." + + " (skipCount=" + skipCount + + "). Reset skip count to 1"); + skipCount = 1; + } + } else { + // went further as skip count, doing nothing. + } + } + } + + if (execute) { + DetachedStep step = (DetachedStep) obj; + answer = step.execute(detachedContext, request); + } else { + answer = new DetachedAnswer(request); + answer.setStatus(DetachedAnswer.SKIPPED); + answer.setLog(skippedLog.toString()); + } + return answer; + } + + protected DetachedAnswer processAdminCommand(DetachedAdminCommand obj, + DetachedRequest request) { + DetachedAnswer answer; + if (obj instanceof OpenSession) { + if (getCurrentSession() != null) + throw new DetachedException( + "There is already an open session #" + + getCurrentSession().getUuid()); + sessions.add(((OpenSession) obj).execute(request, bundleContext)); + answer = new DetachedAnswer(request, "Session #" + + getCurrentSession().getUuid() + " open."); + } else if (obj instanceof CloseSession) { + if (getCurrentSession() == null) + throw new DetachedException("There is no open session to close"); + answer = new DetachedAnswer(request, "Session #" + + getCurrentSession().getUuid() + " closed."); + answer.setStatus(DetachedAnswer.CLOSED_SESSION); + } else { + answer = null; + } + return answer; + } + + protected final DetachedSession getCurrentSession() { + if (sessions.size() == 0) { + return null; + } else { + DetachedSession session = (DetachedSession) sessions.get(sessions + .size() - 1); + List answers = session.getAnswers(); + if (answers.size() > 0) { + DetachedAnswer lastAnswer = (DetachedAnswer) answers + .get(answers.size() - 1); + if (lastAnswer.getStatus() == DetachedAnswer.ERROR + || lastAnswer.getStatus() == DetachedAnswer.CLOSED_SESSION) + return null; + } + return session; + } + } + + protected final DetachedSession getPreviousSession() { + if (sessions.size() < 2) + return null; + else + return (DetachedSession) sessions.get(sessions.size() - 2); + } + + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedRequest.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedRequest.java new file mode 100644 index 000000000..99427bf1d --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedRequest.java @@ -0,0 +1,52 @@ +package org.argeo.slc.detached; + +import java.util.Properties; + +public class DetachedRequest implements DetachedCommunication { + static final long serialVersionUID = 1l; + + private String uuid; + private Properties properties = new Properties(); + private String ref; + private String path = ""; + + public DetachedRequest() { + + } + + public DetachedRequest(String uuid) { + this.uuid = uuid; + } + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties inputParameters) { + this.properties = inputParameters; + } + + public String getRef() { + return ref; + } + + public void setRef(String stepRef) { + this.ref = stepRef; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedSession.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedSession.java new file mode 100644 index 000000000..76e894b16 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedSession.java @@ -0,0 +1,50 @@ +package org.argeo.slc.detached; + +import java.util.List; +import java.util.Vector; + +public class DetachedSession { + public final static String PROP_DO_IT_AGAIN_POLICY = "slc.detached.doItAgainPolicy"; + public final static String SKIP_UNTIL_ERROR = "skipUntilError"; + public final static String REPLAY = "replay"; + + private String uuid = null; + private List requests = new Vector(); + private List answers = new Vector(); + private String doItAgainPolicy = SKIP_UNTIL_ERROR; + + public boolean isClosed() { + if (answers.size() > 0) { + DetachedAnswer answer = (DetachedAnswer) answers + .get(answers.size() - 1); + return answer.getStatus() == DetachedAnswer.CLOSED_SESSION; + } else { + return false; + } + } + + public String getDoItAgainPolicy() { + return doItAgainPolicy; + } + + public void setDoItAgainPolicy(String doItAgainPolicy) { + this.doItAgainPolicy = doItAgainPolicy; + } + + public List getRequests() { + return requests; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public List getAnswers() { + return answers; + } + +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedStep.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedStep.java new file mode 100644 index 000000000..67dba674c --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedStep.java @@ -0,0 +1,7 @@ +package org.argeo.slc.detached; + + +public interface DetachedStep { + public DetachedAnswer execute(DetachedContext detachedContext, + DetachedRequest detachedStepRequest); +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedXmlConverter.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedXmlConverter.java new file mode 100644 index 000000000..0843a8885 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedXmlConverter.java @@ -0,0 +1,11 @@ +package org.argeo.slc.detached; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; + +public interface DetachedXmlConverter { + public void marshallCommunication(DetachedCommunication detCom, + Result result); + + public DetachedCommunication unmarshallCommunication(Source source); +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedXmlConverterCompat.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedXmlConverterCompat.java new file mode 100644 index 000000000..7ad49fada --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedXmlConverterCompat.java @@ -0,0 +1,160 @@ +package org.argeo.slc.detached; + +import java.io.StringReader; +import java.util.Enumeration; +import java.util.Properties; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.commons.io.IOUtils; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** For compatibility with old JDKs (pre 1.5). Use Spring base one when possible. */ +public class DetachedXmlConverterCompat implements DetachedXmlConverter { + public final static String SLC_DETACHED_NAMESPACE_URI = "http://argeo.org/projects/slc/schemas/detached"; + // private final static Log log = LogFactory + // .getLog(DetachedXmlConverterCompat.class); + + private final Transformer copy; + + public DetachedXmlConverterCompat() { + try { + copy = TransformerFactory.newInstance().newTransformer(); + } catch (Exception e) { + throw new DetachedException("Could not create transformer.", e); + } + } + + public void marshallCommunication(DetachedCommunication detCom, + Result result) { + if (detCom instanceof DetachedRequest) { + marshallRequest((DetachedRequest) detCom, result); + } else if (detCom instanceof DetachedAnswer) { + marshallAnswer((DetachedAnswer) detCom, result); + } else { + throw new DetachedException("Unkown communication type " + + detCom.getClass()); + } + } + + public DetachedCommunication unmarshallCommunication(Source source) { + // Parse + DOMResult result = new DOMResult(); + try { + copy.transform(source, result); + } catch (TransformerException e) { + throw new DetachedException("Could not copy xml source", e); + } + Element root = (Element) ((Document) result.getNode()) + .getDocumentElement(); + + // Create objects + String requestType = root.getLocalName(); + if (requestType.equals("detached-request")) { + DetachedRequest request = new DetachedRequest(); + request.setUuid(root.getElementsByTagNameNS( + SLC_DETACHED_NAMESPACE_URI, "uuid").item(0) + .getTextContent()); + request + .setRef(root.getElementsByTagNameNS( + SLC_DETACHED_NAMESPACE_URI, "ref").item(0) + .getTextContent()); + request.setPath(root.getElementsByTagNameNS( + SLC_DETACHED_NAMESPACE_URI, "path").item(0) + .getTextContent()); + Element propertiesElement = (Element) root.getElementsByTagNameNS( + SLC_DETACHED_NAMESPACE_URI, "properties").item(0); + NodeList propElements = propertiesElement.getElementsByTagNameNS( + SLC_DETACHED_NAMESPACE_URI, "prop"); + Properties properties = new Properties(); + for (int i = 0; i < propElements.getLength(); i++) { + Element propElement = (Element) propElements.item(i); + String key = propElement.getAttribute("key"); + String value = propElement.getTextContent(); + properties.setProperty(key, value); + } + request.setProperties(properties); + return request; + } else { + throw new DetachedException(requestType + " not implemented."); + } + } + + public void marshallAnswer(DetachedAnswer answer, Result result) { + StringBuffer buf = new StringBuffer(""); + buf.append(""); + if (answer.getUuid() != null) + buf.append("").append(answer.getUuid()).append( + ""); + buf.append("").append(answer.getStatus()).append( + ""); + if (answer.getLog() != null) + buf.append("").append(answer.getLog()).append( + ""); + if (answer.getProperties().size() != 0) { + buf.append(""); + Enumeration keys = answer.getProperties().keys(); + while (keys.hasMoreElements()) { + String key = (String) keys.nextElement(); + buf.append(""); + buf.append(answer.getProperties().getProperty(key)); + buf.append(""); + } + buf.append(""); + } + buf.append(""); + StringReader reader = new StringReader(buf.toString()); + Source source = new StreamSource(reader); + try { + copy.transform(source, result); + } catch (TransformerException e) { + throw new DetachedException("Could not copy xml to result", e); + } finally { + IOUtils.closeQuietly(reader); + } + } + + public void marshallRequest(DetachedRequest request, Result result) { + throw new DetachedException(" Not implemented."); + } + + public DetachedRequest unmarshallRequest(Source source) { + DOMResult result = new DOMResult(); + try { + copy.transform(source, result); + } catch (TransformerException e) { + throw new DetachedException("Could not copy xml source", e); + } + Element node = (Element) ((Document) result.getNode()) + .getDocumentElement(); + DetachedRequest request = new DetachedRequest(); + request.setUuid(node.getElementsByTagNameNS(SLC_DETACHED_NAMESPACE_URI, + "uuid").item(0).getTextContent()); + request.setRef(node.getElementsByTagNameNS(SLC_DETACHED_NAMESPACE_URI, + "ref").item(0).getTextContent()); + request.setPath(node.getElementsByTagNameNS(SLC_DETACHED_NAMESPACE_URI, + "path").item(0).getTextContent()); + Element propertiesElement = (Element) node.getElementsByTagNameNS( + SLC_DETACHED_NAMESPACE_URI, "properties").item(0); + NodeList propElements = propertiesElement.getElementsByTagNameNS( + SLC_DETACHED_NAMESPACE_URI, "prop"); + Properties properties = new Properties(); + for (int i = 0; i < propElements.getLength(); i++) { + Element propElement = (Element) propElements.item(i); + String key = propElement.getAttribute("key"); + String value = propElement.getTextContent(); + properties.setProperty(key, value); + } + request.setProperties(properties); + return request; + } +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/CloseSession.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/CloseSession.java new file mode 100644 index 000000000..c27a03538 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/CloseSession.java @@ -0,0 +1,7 @@ +package org.argeo.slc.detached.admin; + +import org.argeo.slc.detached.DetachedAdminCommand; + +public class CloseSession implements DetachedAdminCommand { + +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/FelixShellCommand.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/FelixShellCommand.java new file mode 100644 index 000000000..1b6ab0bae --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/FelixShellCommand.java @@ -0,0 +1,30 @@ +package org.argeo.slc.detached.admin; + +import org.argeo.slc.detached.DetachedAdminCommand; +import org.argeo.slc.detached.DetachedAnswer; +import org.argeo.slc.detached.DetachedException; +import org.argeo.slc.detached.DetachedRequest; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; + +public class FelixShellCommand implements DetachedAdminCommand { + public final static String PROP_FELIX_CMDLINE = "slc.detached.felix.cmdline"; + + public DetachedAnswer execute(DetachedRequest request, + BundleContext bundleContext) { + ServiceReference ref = bundleContext + .getServiceReference("org.apache.felix.shell.ShellService"); + if (ref == null) + throw new DetachedException("Felix shell service not found."); + + String cmdLine = request.getProperties() + .getProperty(PROP_FELIX_CMDLINE); + if (cmdLine == null) + throw new DetachedException("Property " + PROP_FELIX_CMDLINE + + " must be defined."); + + // TODO: check were to put Felix dependency + // see http://felix.apache.org/site/apache-felix-shell-service.html + throw new DetachedException("Not yet implemented."); + } +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/OpenSession.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/OpenSession.java new file mode 100644 index 000000000..11966a975 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/OpenSession.java @@ -0,0 +1,57 @@ +package org.argeo.slc.detached.admin; + +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.detached.DetachedAdminCommand; +import org.argeo.slc.detached.DetachedException; +import org.argeo.slc.detached.DetachedRequest; +import org.argeo.slc.detached.DetachedSession; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; + +public class OpenSession implements DetachedAdminCommand { + private final static Log log = LogFactory.getLog(OpenSession.class); + + public DetachedSession execute(DetachedRequest request, + BundleContext bundleContext) { + DetachedSession session = new DetachedSession(); + session.setUuid(Long.toString(System.currentTimeMillis())); + + Properties props = request.getProperties(); + if (props.containsKey(DetachedSession.PROP_DO_IT_AGAIN_POLICY)) + session.setDoItAgainPolicy(props + .getProperty(DetachedSession.PROP_DO_IT_AGAIN_POLICY)); + + String refreshedBundles = props + .getProperty("slc.detached.refreshedBundles"); + if (refreshedBundles != null) { + Bundle[] bundles = bundleContext.getBundles(); + Bundle bundle = null; + for (int i = 0; i < bundles.length; i++) { + if (bundles[i].getSymbolicName().equals(refreshedBundles)) { + bundle = bundles[i]; + } + } + + if (bundle != null) { + try { + bundle.stop(); + bundle.update(); + bundle.start(); + log.info("Refreshed bundle " + bundle.getSymbolicName()); + } catch (BundleException e) { + throw new DetachedException("Could not refresh bundle " + + bundle.getSymbolicName(), e); + } + } else { + log.warn("Did not find bundle to refresh " + refreshedBundles); + } + + } + + return session; + } +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/drivers/AbstractDriver.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/drivers/AbstractDriver.java new file mode 100644 index 000000000..6d8e5ac8f --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/drivers/AbstractDriver.java @@ -0,0 +1,76 @@ +package org.argeo.slc.detached.drivers; + +import org.argeo.slc.detached.DetachedAnswer; +import org.argeo.slc.detached.DetachedDriver; +import org.argeo.slc.detached.DetachedExecutionServer; +import org.argeo.slc.detached.DetachedRequest; +import org.argeo.slc.detached.DetachedXmlConverter; + +public abstract class AbstractDriver implements DetachedDriver { + private boolean active = true; + private DetachedExecutionServer executionServer = null; + private long receiveAnswerTimeout = 10000l; + + private DetachedXmlConverter xmlConverter = null; + + public synchronized void start() { + + Thread driverThread = new Thread(new Runnable() { + + public void run() { + while (active) { + try { + DetachedRequest request = receiveRequest(); + if (!active) + break; + DetachedAnswer answer = executionServer + .executeRequest(request); + sendAnswer(answer); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException) e; + else + e.printStackTrace(); + } + } + + } + }, "driverThread ("+getClass()+")"); + driverThread.start(); + + } + + public void setExecutionServer(DetachedExecutionServer executionServer) { + this.executionServer = executionServer; + } + + public synchronized void stop() { + active = false; + notifyAll(); + } + + public synchronized boolean isActive() { + return active; + } + + public synchronized void setActive(boolean active) { + this.active = active; + } + + public DetachedXmlConverter getXmlConverter() { + return xmlConverter; + } + + public void setXmlConverter(DetachedXmlConverter xmlConverter) { + this.xmlConverter = xmlConverter; + } + + public long getReceiveAnswerTimeout() { + return receiveAnswerTimeout; + } + + public void setReceiveAnswerTimeout(long reveiveTimeout) { + this.receiveAnswerTimeout = reveiveTimeout; + } + +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/drivers/FileDriver.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/drivers/FileDriver.java new file mode 100644 index 000000000..ce88f5b12 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/drivers/FileDriver.java @@ -0,0 +1,243 @@ +package org.argeo.slc.detached.drivers; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.filefilter.NotFileFilter; +import org.apache.commons.io.filefilter.SuffixFileFilter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.detached.DetachedAnswer; +import org.argeo.slc.detached.DetachedClient; +import org.argeo.slc.detached.DetachedCommunication; +import org.argeo.slc.detached.DetachedException; +import org.argeo.slc.detached.DetachedRequest; +import org.springframework.beans.factory.InitializingBean; + +public class FileDriver extends AbstractDriver implements DetachedClient, + InitializingBean { + private final static Log log = LogFactory.getLog(FileDriver.class); + private final static SimpleDateFormat sdf = new SimpleDateFormat( + "yyMMdd_HHmmss_SSS"); + + private File baseDir; + private File requestsDir; + private File answersDir; + private File processedRequestsDir; + private File processedAnswersDir; + private File cleanedRequestsDir; + private File cleanedAnswersDir; + + private String lockFileExt = "lck"; + private FileFilter notLockFileFilter = new NotFileFilter( + new SuffixFileFilter("." + lockFileExt)); + + public synchronized DetachedRequest receiveRequest() throws Exception { + DetachedRequest request = (DetachedRequest) receiveFile(requestsDir, + processedRequestsDir, 0); + if (request != null) + if (log.isTraceEnabled()) + log.trace("Received detached request #" + request.getUuid() + + " for ref '" + request.getRef() + "', path=" + + request.getPath()); + return request; + } + + public void sendAnswer(DetachedAnswer answer) throws Exception { + sendFile(answersDir, answer); + if (log.isTraceEnabled()) + log.trace("Sent detached answer #" + answer.getUuid()); + } + + public DetachedAnswer receiveAnswer() throws Exception { + DetachedAnswer answer = (DetachedAnswer) receiveFile(answersDir, + processedAnswersDir, getReceiveAnswerTimeout()); + if (answer != null) + if (log.isTraceEnabled()) + log.trace("Received detached answer #" + answer.getUuid()); + return answer; + } + + public void sendRequest(DetachedRequest request) throws Exception { + sendFile(requestsDir, request); + if (log.isTraceEnabled()) + log.trace("Sent detached request #" + request.getUuid() + + " for ref '" + request.getRef() + "', path=" + + request.getPath()); + } + + protected void sendFile(File dir, DetachedCommunication detCom) + throws Exception { + final File file; + if (getXmlConverter() != null) + file = new File(dir.getPath() + File.separator + + sdf.format(new Date()) + '-' + detCom.getUuid() + ".xml"); + else + file = new File(dir.getPath() + File.separator + detCom.getUuid()); + + File lockFile = createLockFile(file); + if (getXmlConverter() != null) { + FileOutputStream outFile = new FileOutputStream(file); + try { + StreamResult result = new StreamResult(outFile); + getXmlConverter().marshallCommunication(detCom, result); + } finally { + IOUtils.closeQuietly(outFile); + } + } else { + ObjectOutputStream out = new ObjectOutputStream( + new FileOutputStream(file)); + try { + out.writeObject(detCom); + } finally { + IOUtils.closeQuietly(out); + } + } + lockFile.delete(); + } + + /** + * @param timeout + * in ms, 0 is no timeout + */ + protected synchronized DetachedCommunication receiveFile(File dir, + File processedDir, long timeout) throws Exception { + long begin = System.currentTimeMillis(); + File file = null; + while (file == null && isActive()) { + if (!dir.exists()) + throw new DetachedException("Dir " + dir + " does not exist."); + + File[] files = dir.listFiles(notLockFileFilter); + if (files.length > 0) + file = files[0]; + else { + try { + wait(100); + } catch (InterruptedException e) { + // silent + } + } + + long duration = System.currentTimeMillis() - begin; + if (timeout != 0 && duration > timeout) { + throw new DetachedException("Receive file timed out after " + + duration + "ms."); + } + } + + if (!isActive()) + return null; + + File lockFile = nameLockFile(file); + while (lockFile.exists()) + // FIXME: implements time out + Thread.sleep(100); + + // Read the file + final DetachedCommunication detCom; + if (FilenameUtils.getExtension(file.getName()).equals("xml")) { + if (getXmlConverter() == null) + throw new DetachedException("No XML converter defined."); + FileInputStream in = new FileInputStream(file); + try { + StreamSource source = new StreamSource(in); + detCom = getXmlConverter().unmarshallCommunication(source); + } finally { + IOUtils.closeQuietly(in); + } + } else { + ObjectInputStream in = new ObjectInputStream(new FileInputStream( + file)); + try { + detCom = (DetachedCommunication) in.readObject(); + } finally { + IOUtils.closeQuietly(in); + } + } + // Move to processed dir + FileUtils.moveFileToDirectory(file, processedDir, false); + return detCom; + } + + protected File createLockFile(File file) { + File lockFile = nameLockFile(file); + try { + lockFile.createNewFile(); + } catch (IOException e) { + throw new DetachedException("Cannot create lock file " + lockFile); + } + return lockFile; + } + + protected File nameLockFile(File file) { + return new File(file.getAbsolutePath() + "." + lockFileExt); + } + + public void setBaseDir(File baseDir) { + this.baseDir = baseDir; + } + + private void createIfNotExist(File dir) { + if (!dir.exists()) { + log.warn("Dir " + dir.getAbsolutePath() + + " does not exist. Creating it..."); + dir.mkdirs(); + } + } + + public void afterPropertiesSet() throws Exception { + this.requestsDir = new File(baseDir.getAbsolutePath() + File.separator + + "requests"); + this.answersDir = new File(baseDir.getAbsolutePath() + File.separator + + "answers"); + this.processedRequestsDir = new File(baseDir.getAbsolutePath() + + File.separator + "processed" + File.separator + "requests"); + this.processedAnswersDir = new File(baseDir.getAbsolutePath() + + File.separator + "processed" + File.separator + "answers"); + this.cleanedRequestsDir = new File(baseDir.getAbsolutePath() + + File.separator + "cleaned" + File.separator + "requests"); + this.cleanedAnswersDir = new File(baseDir.getAbsolutePath() + + File.separator + "cleaned" + File.separator + "answers"); + + createIfNotExist(requestsDir); + createIfNotExist(answersDir); + createIfNotExist(processedRequestsDir); + createIfNotExist(processedAnswersDir); + createIfNotExist(cleanedRequestsDir); + createIfNotExist(cleanedAnswersDir); + log.info("Detached File Driver initialized on " + baseDir); + } + + public void cleanPreviousRuns() throws Exception { + + // Clean requests and answers from previous builds + File[] remainingRequests = requestsDir.listFiles(); + for (int i = 0; i < remainingRequests.length; i++) { + FileUtils.moveFileToDirectory(remainingRequests[i], + cleanedRequestsDir, false); + } + + File[] remainingAnswers = answersDir.listFiles(); + for (int i = 0; i < remainingAnswers.length; i++) { + FileUtils.moveFileToDirectory(remainingAnswers[i], + cleanedAnswersDir, false); + } + log.info("Clean previous runs of File Driver on " + baseDir); + + } + +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/ui/UiPart.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/ui/UiPart.java new file mode 100644 index 000000000..7f3f2a91f --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/ui/UiPart.java @@ -0,0 +1,32 @@ +package org.argeo.slc.detached.ui; + +import org.argeo.slc.detached.DetachedContext; +import org.argeo.slc.detached.DetachedRequest; + +public abstract class UiPart { + private boolean initialized = false; + + public synchronized final void init(DetachedContext context, + DetachedRequest request) { + initUi(context, request); + initialized = true; + } + + public synchronized final void reset(DetachedContext context, + DetachedRequest request) { + resetUi(context, request); + initialized = false; + } + + protected abstract void initUi(DetachedContext context, + DetachedRequest request); + + protected void resetUi(DetachedContext context, DetachedRequest request) { + + } + + public synchronized boolean isInitialized() { + return initialized; + } + +} diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/ui/UiStep.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/ui/UiStep.java new file mode 100644 index 000000000..757d2c17d --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/ui/UiStep.java @@ -0,0 +1,29 @@ +package org.argeo.slc.detached.ui; + +import org.argeo.slc.detached.DetachedAnswer; +import org.argeo.slc.detached.DetachedContext; +import org.argeo.slc.detached.DetachedRequest; +import org.argeo.slc.detached.DetachedStep; +import org.springframework.beans.factory.BeanNameAware; + +public abstract class UiStep implements DetachedStep, BeanNameAware { + private String beanName; + + public final DetachedAnswer execute(DetachedContext detachedContext, + DetachedRequest detachedStepRequest) { + // uiPart.init(detachedContext, detachedStepRequest); + return executeUiStep(detachedContext, detachedStepRequest); + } + + protected abstract DetachedAnswer executeUiStep(DetachedContext context, + DetachedRequest request); + + public void setBeanName(String name) { + this.beanName = name; + } + + public String getBeanName() { + return beanName; + } + +} diff --git a/runtime/org.argeo.slc.detached/src/main/resources/META-INF/MANIFEST.MF b/runtime/org.argeo.slc.detached/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 000000000..b379bcba6 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,37 @@ +Manifest-Version: 1.0 +Export-Package: org.argeo.slc.detached.admin;uses:="org.apache.commons + .logging,org.osgi.framework,org.argeo.slc.detached";version="0.11.2.S + NAPSHOT",org.argeo.slc.detached.ui;uses:="org.argeo.slc.detached,org. + springframework.beans.factory";version="0.11.2.SNAPSHOT",org.argeo.sl + c.detached;uses:="org.springframework.osgi.context,org.apache.commons + .logging,org.springframework.context,javax.xml.transform.dom,org.w3c. + dom,org.argeo.slc.detached.admin,javax.xml.transform,javax.xml.transf + orm.stream,org.osgi.framework,org.apache.commons.io";version="0.11.2. + SNAPSHOT",org.argeo.slc.detached.drivers;uses:="org.apache.commons.lo + gging,org.apache.commons.io.filefilter,javax.xml.transform,javax.xml. + transform.stream,org.apache.commons.io,org.argeo.slc.detached,org.spr + ingframework.beans.factory";version="0.11.2.SNAPSHOT" +Tool: Bnd-0.0.255 +Bundle-Name: Argeo SLC Detached +Created-By: 1.6.0 (Sun Microsystems Inc.) +Bundle-Vendor: Argeo +Bundle-Version: 0.11.2.SNAPSHOT +Bundle-ManifestVersion: 2 +Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt +Bundle-Description: SLC Distribution +Import-Package: javax.xml.transform,javax.xml.transform.dom,javax.xml. + transform.stream,org.apache.commons.io;version="1.4",org.apache.commo + ns.io.filefilter;version="1.4",org.apache.commons.logging;version="1. + 1",org.argeo.slc.detached;version="0.11.2.SNAPSHOT",org.argeo.slc.det + ached.admin;version="0.11.2.SNAPSHOT",org.argeo.slc.detached.drivers; + version="0.11.2.SNAPSHOT",org.argeo.slc.detached.ui;version="0.11.2.S + NAPSHOT",org.osgi.framework;version="1.4",org.springframework.beans.f + actory;version="2.0",org.springframework.beans.factory.support;versio + n="2.0",org.springframework.beans.factory.xml;version="2.0",org.sprin + gframework.context;version="2.0",org.springframework.context.support; + version="2.0",org.springframework.core.io;version="2.0",org.springfra + mework.osgi.context;version="1.1.2.B",org.w3c.dom +Bundle-SymbolicName: org.argeo.slc.detached +Bundle-DocURL: http://www.argeo.org +Originally-Created-By: 1.6.0 (Sun Microsystems Inc.) + diff --git a/runtime/org.argeo.slc.detached/src/main/resources/META-INF/spring/slc-detached-osgi.xml b/runtime/org.argeo.slc.detached/src/main/resources/META-INF/spring/slc-detached-osgi.xml new file mode 100644 index 000000000..009726d27 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/resources/META-INF/spring/slc-detached-osgi.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.detached/src/main/resources/META-INF/spring/slc-detached.xml b/runtime/org.argeo.slc.detached/src/main/resources/META-INF/spring/slc-detached.xml new file mode 100644 index 000000000..13f485c88 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/resources/META-INF/spring/slc-detached.xml @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/runtime/org.argeo.slc.detached/src/main/resources/org/argeo/slc/detached/slc-detached.xsd b/runtime/org.argeo.slc.detached/src/main/resources/org/argeo/slc/detached/slc-detached.xsd new file mode 100644 index 000000000..c4fab177b --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/resources/org/argeo/slc/detached/slc-detached.xsd @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.detached/src/main/resources/org/argeo/slc/detached/spring.xml b/runtime/org.argeo.slc.detached/src/main/resources/org/argeo/slc/detached/spring.xml new file mode 100644 index 000000000..9aa9aec30 --- /dev/null +++ b/runtime/org.argeo.slc.detached/src/main/resources/org/argeo/slc/detached/spring.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + \ No newline at end of file -- 2.39.2