Rename SLC Core into SLC Spring.
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 15 Feb 2020 08:45:53 +0000 (09:45 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 15 Feb 2020 08:45:53 +0000 (09:45 +0100)
376 files changed:
dep/org.argeo.slc.dep.e4.rap/pom.xml
dep/org.argeo.slc.dep.minimal/pom.xml
dep/org.argeo.slc.dep.spring/pom.xml
org.argeo.slc.core/.classpath [deleted file]
org.argeo.slc.core/.gitignore [deleted file]
org.argeo.slc.core/.project [deleted file]
org.argeo.slc.core/META-INF/.gitignore [deleted file]
org.argeo.slc.core/META-INF/spring.handlers [deleted file]
org.argeo.slc.core/META-INF/spring.schemas [deleted file]
org.argeo.slc.core/bnd.bnd [deleted file]
org.argeo.slc.core/build.properties [deleted file]
org.argeo.slc.core/ext/test/log4j.properties [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/DefaultResourceSetTest.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/data/file1.txt [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/data/subdir/file2.txt [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/relativeResourceSet.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/AbstractExecutionFlowTestCase.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/BasicExecutionFlowTest.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/DefaultAgentCliTest.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/ExceptionIfInitCalledTwice.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesSpringTest.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesTest.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/ParameterRefTest.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/applicationContext.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-001.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-002.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-003.error.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-004.error.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/executionResources.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/imports.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/listSetMap.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/listSetMapMultipleFlow.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/minimal.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/multipleFlow.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/parameterRef.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.exec.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/specOverriding.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/tasks/SystemCallTest.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/tasks/systemCall.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/test.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/FlowNamespaceTest.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/advanced.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-001.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-002.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/canonic-ns.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/containers.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/tests.xml [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/test/context/AbstractInternalSpringTestCase.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/test/context/ContextTest.java [deleted file]
org.argeo.slc.core/ext/test/org/argeo/slc/core/test/context/applicationContext.xml [deleted file]
org.argeo.slc.core/pom.xml [deleted file]
org.argeo.slc.core/src/org/argeo/slc/ant/AntFlowGenerator.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/ant/AntRun.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/attachment/Attachment.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/attachment/AttachmentUploader.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/attachment/AttachmentsEnabled.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/attachment/AttachmentsStorage.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/attachment/FileAttachmentsStorage.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/attachment/SimpleAttachment.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/build/ResourceDistribution.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/build/VersionDistributionId.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/build/VersionedResourceDistribution.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/build/package.html [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/deploy/DefaultResourceSet.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/deploy/DigestCheck.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/deploy/LocalFilesDeployment.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/deploy/MultiResourceSet.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/deploy/ResourceSet.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/deploy/SimpleExecutables.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/deploy/VersionedDirSync.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/deploy/package.html [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractExecutionFlowGenerator.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractExecutionValue.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractSpecAttribute.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractSpringExecutionModule.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultAgent.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultAgentCli.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionFlow.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionSpec.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionStack.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultProcess.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionAspect.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionParameterPostProcessor.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionResources.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionResourcesFactoryBean.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionScope.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionThread.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/FileExecutionResources.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/FlowConfigurationException.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/InstantiationManager.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/MapExecutionContext.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/OsFileFactoryBean.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/ParameterRef.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveAccessor.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveSpecAttribute.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveUtils.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveValue.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/ProcessThread.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/ProcessThreadGroup.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/RefSpecAttribute.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/RefValue.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/RefValueChoice.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/SedFilteredResource.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/defaults.xml [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/doc/ConsoleContextDescriber.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/doc/ContextDescriber.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/CompositeRunnableFactory.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/DefaultRunnableDataNode.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/ExecutionFlowGenerator.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/ExecutionFlowGeneratorSource.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableCall.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableCallFlow.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableCallFlowDescriptor.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableDataNode.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableFactory.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/runtime.xml [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/simple.xml [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/specs.xml [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/spring.xml [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/CloseTestResult.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/Echo.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/If.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/JvmProcess.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/MergedLists.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/MethodCall.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/OverrideContextAware.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/SystemCall.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/SystemCallOutputListener.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/UploadAttachments.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/core.xml [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/templates.xml [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/utils.xml [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/AsFlowDecorator.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/ExecutionScopeDecorator.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/FlowBeanDefinitionParser.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/FlowNamespaceHandler.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/NamespaceUtils.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/ParamDecorator.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/SpecBeanDefinitionParser.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/slc-flow-0.12.xsd [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/BasicTestData.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/BasicTestDefinition.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/SimpleResultPart.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/SimpleTestResult.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/SimpleTestRun.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/SlcTestUtils.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/TestDataUtils.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/context/ContextUtils.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/context/DefaultContextTestData.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/context/SimpleContextAware.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/context/SimpleParentContextAware.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/context/package.html [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/package.html [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/test/spring.xml [deleted file]
org.argeo.slc.core/src/org/argeo/slc/jcr/JcrMetadataWriter.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/jcr/JcrTestResult.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrConstants.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrResultUtils.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrUtils.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrAgent.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrAttachmentUploader.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrExecutionProcess.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrProcessThread.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrRealizedFlow.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/BundleRegister.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/BundlesManager.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/FileSystemBundleRegister.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiBundle.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionModule.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionModulesManager.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionResources.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiRuntime.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/AbstractOsgiModularDistribution.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/BundleModularDistribution.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSite.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSiteCategory.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSiteFeature.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/OsgiRuntimeModularDistribution.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/deploy/OsgiResourceSet.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/osgi/execution.xml [deleted file]
org.argeo.slc.core/src/org/argeo/slc/spring/AbstractSystemExecution.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/spring/AuthenticatedApplicationContextInitialization.java [deleted file]
org.argeo.slc.spring/.classpath [new file with mode: 0644]
org.argeo.slc.spring/.gitignore [new file with mode: 0644]
org.argeo.slc.spring/.project [new file with mode: 0644]
org.argeo.slc.spring/META-INF/.gitignore [new file with mode: 0644]
org.argeo.slc.spring/META-INF/spring.handlers [new file with mode: 0644]
org.argeo.slc.spring/META-INF/spring.schemas [new file with mode: 0644]
org.argeo.slc.spring/bnd.bnd [new file with mode: 0644]
org.argeo.slc.spring/build.properties [new file with mode: 0644]
org.argeo.slc.spring/ext/test/log4j.properties [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/DefaultResourceSetTest.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/data/file1.txt [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/data/subdir/file2.txt [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/relativeResourceSet.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/AbstractExecutionFlowTestCase.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/BasicExecutionFlowTest.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/DefaultAgentCliTest.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/ExceptionIfInitCalledTwice.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesSpringTest.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesTest.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/ParameterRefTest.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/applicationContext.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-001.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-002.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-003.error.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-004.error.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/executionResources.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/imports.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/listSetMap.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/listSetMapMultipleFlow.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/minimal.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/multipleFlow.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/parameterRef.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.exec.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/specOverriding.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/tasks/SystemCallTest.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/tasks/systemCall.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/test.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/FlowNamespaceTest.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/advanced.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-001.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-002.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/canonic-ns.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/containers.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/tests.xml [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/test/context/AbstractInternalSpringTestCase.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/test/context/ContextTest.java [new file with mode: 0644]
org.argeo.slc.spring/ext/test/org/argeo/slc/core/test/context/applicationContext.xml [new file with mode: 0644]
org.argeo.slc.spring/pom.xml [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/ant/AntFlowGenerator.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/ant/AntRun.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/attachment/Attachment.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/attachment/AttachmentUploader.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/attachment/AttachmentsEnabled.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/attachment/AttachmentsStorage.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/attachment/FileAttachmentsStorage.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/attachment/SimpleAttachment.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/build/ResourceDistribution.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/build/VersionDistributionId.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/build/VersionedResourceDistribution.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/build/package.html [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/deploy/DefaultResourceSet.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/deploy/DigestCheck.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/deploy/LocalFilesDeployment.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/deploy/MultiResourceSet.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/deploy/ResourceSet.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/deploy/SimpleExecutables.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/deploy/VersionedDirSync.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/deploy/package.html [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractExecutionFlowGenerator.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractExecutionValue.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractSpecAttribute.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractSpringExecutionModule.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultAgent.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultAgentCli.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionFlow.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionSpec.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionStack.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultProcess.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionAspect.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionParameterPostProcessor.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionResources.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionResourcesFactoryBean.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionScope.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionThread.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/FileExecutionResources.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/FlowConfigurationException.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/InstantiationManager.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/MapExecutionContext.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/OsFileFactoryBean.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/ParameterRef.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveAccessor.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveSpecAttribute.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveUtils.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveValue.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/ProcessThread.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/ProcessThreadGroup.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/RefSpecAttribute.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/RefValue.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/RefValueChoice.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/SedFilteredResource.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/defaults.xml [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/doc/ConsoleContextDescriber.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/doc/ContextDescriber.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/CompositeRunnableFactory.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/DefaultRunnableDataNode.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/ExecutionFlowGenerator.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/ExecutionFlowGeneratorSource.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableCall.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableCallFlow.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableCallFlowDescriptor.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableDataNode.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableFactory.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/runtime.xml [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/simple.xml [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/specs.xml [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/spring.xml [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/CloseTestResult.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/Echo.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/If.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/JvmProcess.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/MergedLists.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/MethodCall.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/OverrideContextAware.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/SystemCall.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/SystemCallOutputListener.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/UploadAttachments.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/core.xml [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/templates.xml [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/utils.xml [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/AsFlowDecorator.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/ExecutionScopeDecorator.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/FlowBeanDefinitionParser.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/FlowNamespaceHandler.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/NamespaceUtils.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/ParamDecorator.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/SpecBeanDefinitionParser.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/slc-flow-0.12.xsd [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/BasicTestData.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/BasicTestDefinition.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/SimpleResultPart.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/SimpleTestResult.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/SimpleTestRun.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/SlcTestUtils.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/TestDataUtils.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/context/ContextUtils.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/context/DefaultContextTestData.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/context/SimpleContextAware.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/context/SimpleParentContextAware.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/context/package.html [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/package.html [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/core/test/spring.xml [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/jcr/JcrMetadataWriter.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/jcr/JcrTestResult.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/jcr/SlcJcrConstants.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/jcr/SlcJcrResultUtils.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/jcr/SlcJcrUtils.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrAgent.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrAttachmentUploader.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrExecutionProcess.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrProcessThread.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrRealizedFlow.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/BundleRegister.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/BundlesManager.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/FileSystemBundleRegister.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiBundle.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiExecutionModule.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiExecutionModulesManager.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiExecutionResources.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiRuntime.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/build/AbstractOsgiModularDistribution.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/build/BundleModularDistribution.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/build/EclipseUpdateSite.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/build/EclipseUpdateSiteCategory.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/build/EclipseUpdateSiteFeature.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/build/OsgiRuntimeModularDistribution.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/deploy/OsgiResourceSet.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/osgi/execution.xml [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/spring/AbstractSystemExecution.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/spring/AuthenticatedApplicationContextInitialization.java [new file with mode: 0644]
pom.xml

index f1a96897591358c99d0750e2938e25995426e13b..30bd59c9ee8bee32fdd482e4c6861249ff2a8c61 100644 (file)
                <!-- Parent dependencies -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.dep.cms.e4.rap</artifactId>
+                       <artifactId>org.argeo.dep.cms.sdk</artifactId>
                        <version>${version.argeo-commons}</version>
                        <type>pom</type>
                </dependency>
                <dependency>
                        <groupId>org.argeo.slc</groupId>
-                       <artifactId>org.argeo.slc.dep.spring</artifactId>
+                       <artifactId>org.argeo.slc.dep.minimal</artifactId>
                        <version>2.1.17-SNAPSHOT</version>
                        <type>pom</type>
                </dependency>
                                                        </execution>
                                                </executions>
                                        </plugin>
-                                       <!-- <plugin> -->
-                                       <!-- <groupId>org.apache.maven.plugins</groupId> -->
-                                       <!-- <artifactId>maven-dependency-plugin</artifactId> -->
-                                       <!-- <executions> -->
-                                       <!-- <execution> -->
-                                       <!-- <id>copy-argeo</id> -->
-                                       <!-- <phase>package</phase> -->
-                                       <!-- <goals> -->
-                                       <!-- <goal>copy-dependencies</goal> -->
-                                       <!-- </goals> -->
-                                       <!-- <configuration> -->
-                                       <!-- <includeTypes>jar</includeTypes> -->
-                                       <!-- <outputDirectory>${project.build.directory}/lib-argeo</outputDirectory> -->
-                                       <!-- <includeGroupIds>org.argeo.slc</includeGroupIds> -->
-                                       <!-- <excludeTransitive>true</excludeTransitive> -->
-                                       <!-- <excludeArtifactIds>org.argeo.slc.dep.minimal</excludeArtifactIds> -->
-                                       <!-- <includeTypes>jar</includeTypes> -->
-                                       <!-- <includeScope>runtime</includeScope> -->
-                                       <!-- <useRepositoryLayout>true</useRepositoryLayout> -->
-                                       <!-- </configuration> -->
-                                       <!-- </execution> -->
-                                       <!-- </executions> -->
-                                       <!-- </plugin> -->
                                        <plugin>
                                                <groupId>org.codehaus.mojo</groupId>
                                                <artifactId>rpm-maven-plugin</artifactId>
                                                                                                </source>
                                                                                        </sources>
                                                                                </mapping>
-                                                                               <!-- <mapping> -->
-                                                                               <!-- <directory>/usr/share/osgi/org/argeo/slc/${project.artifactId}/${project.version}</directory> -->
-                                                                               <!-- <username>root</username> -->
-                                                                               <!-- <groupname>root</groupname> -->
-                                                                               <!-- <directoryIncluded>false</directoryIncluded> -->
-                                                                               <!-- <artifact /> -->
-                                                                               <!-- </mapping> -->
                                                                        </mappings>
                                                                        <requires>
                                                                                <require>argeo-cms-e4-rap</require>
                                                                                <require>argeo-cms-sdk-tp</require>
-                                                                               <require>slc-spring</require>
+                                                                               <require>slc-agent</require>
                                                                        </requires>
                                                                </configuration>
                                                        </execution>
index c1ab9d88e3e08979389868e4a9b6db0dc135ca61..e32a59a8229cb5a0e3b2a8e207fa0a123d20ced1 100644 (file)
                        <artifactId>org.argeo.slc.api</artifactId>
                        <version>2.1.17-SNAPSHOT</version>
                </dependency>
-               <dependency>
-                       <groupId>org.argeo.slc</groupId>
-                       <artifactId>org.argeo.slc.core</artifactId>
-                       <version>2.1.17-SNAPSHOT</version>
-               </dependency>
                <dependency>
                        <groupId>org.argeo.slc</groupId>
                        <artifactId>org.argeo.slc.support</artifactId>
index bec19f6d69aa160171a810178d4cc3947d524601..faada3bb65b9dad2034a68b611351d6f0a33a20f 100644 (file)
                </dependency>
 
                <!-- Spring-based Agent -->
+               <dependency>
+                       <groupId>org.argeo.slc</groupId>
+                       <artifactId>org.argeo.slc.core</artifactId>
+                       <version>2.1.17-SNAPSHOT</version>
+               </dependency>
                <dependency>
                        <groupId>org.argeo.slc</groupId>
                        <artifactId>org.argeo.slc.agent</artifactId>
diff --git a/org.argeo.slc.core/.classpath b/org.argeo.slc.core/.classpath
deleted file mode 100644 (file)
index 70b08e8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-       <classpathentry kind="src" output="target/classes" path="src"/>
-       <classpathentry kind="src" path="ext/test"/>
-       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
-       <classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/org.argeo.slc.core/.gitignore b/org.argeo.slc.core/.gitignore
deleted file mode 100644 (file)
index 09e3bc9..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/bin/
-/target/
diff --git a/org.argeo.slc.core/.project b/org.argeo.slc.core/.project
deleted file mode 100644 (file)
index a304482..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>org.argeo.slc.core</name>
-       <comment></comment>
-       <projects>
-       </projects>
-       <buildSpec>
-               <buildCommand>
-                       <name>org.eclipse.jdt.core.javabuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.pde.ManifestBuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.pde.SchemaBuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-       </buildSpec>
-       <natures>
-               <nature>org.eclipse.jdt.core.javanature</nature>
-               <nature>org.eclipse.pde.PluginNature</nature>
-       </natures>
-</projectDescription>
diff --git a/org.argeo.slc.core/META-INF/.gitignore b/org.argeo.slc.core/META-INF/.gitignore
deleted file mode 100644 (file)
index 4854a41..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/MANIFEST.MF
diff --git a/org.argeo.slc.core/META-INF/spring.handlers b/org.argeo.slc.core/META-INF/spring.handlers
deleted file mode 100644 (file)
index 417a952..0000000
+++ /dev/null
@@ -1 +0,0 @@
-http\://www.argeo.org/schema/slc-flow=org.argeo.slc.core.execution.xml.FlowNamespaceHandler
\ No newline at end of file
diff --git a/org.argeo.slc.core/META-INF/spring.schemas b/org.argeo.slc.core/META-INF/spring.schemas
deleted file mode 100644 (file)
index 229d4c5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-http\://www.argeo.org/schema/slc-flow.xsd=org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd
-http\://www.argeo.org/schema/slc-flow-1.2.xsd=org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd
-http\://www.argeo.org/schema/slc-flow-0.12.xsd=org/argeo/slc/core/execution/xml/slc-flow-0.12.xsd
diff --git a/org.argeo.slc.core/bnd.bnd b/org.argeo.slc.core/bnd.bnd
deleted file mode 100644 (file)
index fb76254..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-Import-Package: javax.jcr.nodetype,\
-javax.jcr.security,\
-org.apache.tools.ant.*;resolution:="optional",\
-junit.framework;resolution:="optional",\
-org.osgi.*;version=0.0.0,\
-*
diff --git a/org.argeo.slc.core/build.properties b/org.argeo.slc.core/build.properties
deleted file mode 100644 (file)
index 7abe079..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-additional.bundles = org.springframework.context
-bin.includes = META-INF/,.
-source.. = src/
diff --git a/org.argeo.slc.core/ext/test/log4j.properties b/org.argeo.slc.core/ext/test/log4j.properties
deleted file mode 100644 (file)
index 0133bab..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# Set root logger level to DEBUG and its only appender to A1.\r
-log4j.rootLogger=WARN, console\r
-\r
-## Levels\r
-# Slc\r
-log4j.logger.org.argeo=DEBUG\r
-\r
-# Castor\r
-log4j.logger.org.exolab.castor=WARN\r
-\r
-# Spring\r
-log4j.logger.org.springframework=WARN\r
-\r
-\r
-## Appenders\r
-# A1 is set to be a ConsoleAppender.\r
-log4j.appender.console=org.apache.log4j.ConsoleAppender\r
-\r
-# A1 uses PatternLayout.\r
-log4j.appender.console.layout=org.apache.log4j.PatternLayout\r
-log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n\r
-\r
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/DefaultResourceSetTest.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/DefaultResourceSetTest.java
deleted file mode 100644 (file)
index 15fb429..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.core.test.context.AbstractInternalSpringTestCase;
-import org.springframework.core.io.Resource;
-
-public class DefaultResourceSetTest extends AbstractInternalSpringTestCase {
-       private final static Log log = LogFactory
-                       .getLog(DefaultResourceSetTest.class);
-
-       public void testListResources() {
-               DefaultResourceSet rrs = getBean("relativeResourceSet");
-               Map<String, Resource> res = rrs.listResources();
-               for (String relativePath : res.keySet())
-                       log.debug(relativePath + "=" + res.get(relativePath));
-               assertEquals(2, res.size());
-       }
-
-       @Override
-       protected String getApplicationContextLocation() {
-               return inPackage("relativeResourceSet.xml");
-       }
-
-}
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/data/file1.txt b/org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/data/file1.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/data/subdir/file2.txt b/org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/data/subdir/file2.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/relativeResourceSet.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/deploy/relativeResourceSet.xml
deleted file mode 100644 (file)
index 074c205..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
-\r
-       <bean id="relativeResourceSet" class="org.argeo.slc.core.deploy.DefaultResourceSet">\r
-               <property name="base" value="classpath:/org/argeo/slc/core/deploy/data" />\r
-       </bean>\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/AbstractExecutionFlowTestCase.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/AbstractExecutionFlowTestCase.java
deleted file mode 100644 (file)
index 004605c..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution;\r
-\r
-import junit.framework.TestCase;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.core.test.SimpleTestResult;\r
-import org.argeo.slc.execution.ExecutionContext;\r
-import org.argeo.slc.execution.ExecutionFlow;\r
-import org.argeo.slc.test.TestResultPart;\r
-import org.argeo.slc.test.TestStatus;\r
-import org.springframework.context.ConfigurableApplicationContext;\r
-import org.springframework.context.support.ClassPathXmlApplicationContext;\r
-\r
-public abstract class AbstractExecutionFlowTestCase extends TestCase {\r
-\r
-       protected final Log log = LogFactory.getLog(getClass());\r
-\r
-       protected void logException(Throwable ex) {\r
-               log.info("Got Exception of class " + ex.getClass().toString()\r
-                               + " with message '" + ex.getMessage() + "'.");\r
-       }\r
-\r
-       protected void validateTestResult(SimpleTestResult testResult) {\r
-               validateTestResult(testResult, TestStatus.PASSED);\r
-       }\r
-\r
-       protected void validateTestResult(SimpleTestResult testResult,\r
-                       int expectedStatus) {\r
-               for (TestResultPart part : testResult.getParts()) {\r
-                       if (part.getStatus() != expectedStatus) {\r
-                               fail("Error found in TestResult: " + part.getMessage());\r
-                       }\r
-               }\r
-       }\r
-\r
-       protected ConfigurableApplicationContext createApplicationContext(\r
-                       String applicationContextSuffix) {\r
-               ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext(\r
-                               inPackage(applicationContextSuffix));\r
-               // applicationContext.start();\r
-               return applicationContext;\r
-       }\r
-\r
-       protected void configureAndExecuteSlcFlow(String applicationContextSuffix,\r
-                       String beanName) {\r
-               ConfigurableApplicationContext applicationContext = createApplicationContext(applicationContextSuffix);\r
-               ExecutionContext executionContext = (ExecutionContext) applicationContext\r
-                               .getBean("executionContext");\r
-               ExecutionFlow executionFlow = (ExecutionFlow) applicationContext\r
-                               .getBean(beanName);\r
-               if (executionFlow instanceof DefaultExecutionFlow)\r
-                       ((DefaultExecutionFlow) executionFlow)\r
-                                       .setExecutionContext(executionContext);\r
-               try {\r
-                       executionContext.beforeFlow(executionFlow);\r
-                       executionFlow.run();\r
-               } finally {\r
-                       executionContext.afterFlow(executionFlow);\r
-               }\r
-               applicationContext.close();\r
-       }\r
-\r
-       protected String inPackage(String suffix) {\r
-               String prefix = getClass().getPackage().getName().replace('.', '/');\r
-               return prefix + '/' + suffix;\r
-       }\r
-}\r
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/BasicExecutionFlowTest.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/BasicExecutionFlowTest.java
deleted file mode 100644 (file)
index 91be3bd..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution;\r
-\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-import org.argeo.slc.core.test.SimpleTestResult;\r
-import org.argeo.slc.execution.ExecutionContext;\r
-import org.argeo.slc.execution.ExecutionFlow;\r
-import org.argeo.slc.test.TestStatus;\r
-import org.springframework.beans.factory.BeanCreationException;\r
-import org.springframework.context.ConfigurableApplicationContext;\r
-\r
-public class BasicExecutionFlowTest extends AbstractExecutionFlowTestCase {\r
-       // TO TEST\r
-       // - post-processing for @{} replacement in beans with complex properties\r
-       // - bean of scope other than execution are not resolved at execution\r
-\r
-       // public void testMyTest() throws Exception {\r
-       // ConfigurableApplicationContext applicationContext =\r
-       // createApplicationContext("test.xml");\r
-       // log.info("Start Execution");\r
-       // ((ExecutionFlow) applicationContext.getBean("flow1")).execute();\r
-       // applicationContext.close();\r
-       // }\r
-\r
-       public void testSpecOverriding() throws Exception {\r
-               ConfigurableApplicationContext applicationContext = createApplicationContext("specOverriding.xml");\r
-               ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
-               SimpleTestResult res = (SimpleTestResult) applicationContext\r
-                               .getBean("myTestResult");\r
-               validateTestResult(res);\r
-       }\r
-\r
-       public void testMultipleFlows() throws Exception {\r
-               ConfigurableApplicationContext applicationContext = createApplicationContext("multipleFlow.xml");\r
-               ((ExecutionFlow) applicationContext.getBean("flow1")).run();\r
-               SimpleTestResult res = (SimpleTestResult) applicationContext\r
-                               .getBean("myTestResult");\r
-               validateTestResult(res);\r
-               res.getParts().clear();\r
-               ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
-               validateTestResult(res, TestStatus.FAILED);\r
-               applicationContext.close();\r
-       }\r
-\r
-       /**\r
-        * Test placeholder resolution in a context without scope execution or proxy\r
-        * and with cascading flows (the flow A contains the flow B)\r
-        * \r
-        * @throws Exception\r
-        */\r
-       public void testPlaceHolders() throws Exception {\r
-               ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.xml");\r
-               ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
-               validateTestResult((SimpleTestResult) applicationContext\r
-                               .getBean("myTestResult"));\r
-               applicationContext.close();\r
-       }\r
-\r
-       /**\r
-        * Test placeholder resolution in a context without scope execution or proxy\r
-        * and with cascading flows (the flow A contains the flow B) setting\r
-        * execution values (should have no effect)\r
-        * \r
-        * @throws Exception\r
-        */\r
-       public void testPlaceHoldersWithExecutionValues() throws Exception {\r
-               ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.xml");\r
-\r
-               ExecutionContext executionContext = (ExecutionContext) applicationContext\r
-                               .getBean("executionContext");\r
-               Map<String, String> executionParameters = new HashMap<String, String>();\r
-               executionParameters.put("p1", "e1");\r
-               executionParameters.put("p2", "e2");\r
-               executionParameters.put("p3", "e3");\r
-               executionParameters.put("p4", "e4");\r
-               executionParameters.put("p5", "e5");\r
-               executionParameters.put("p6", "e6");\r
-               executionParameters.put("p7", "e7");\r
-               executionParameters.put("p8", "e8");\r
-               addVariables(executionContext, executionParameters);\r
-\r
-               ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
-               validateTestResult((SimpleTestResult) applicationContext\r
-                               .getBean("myTestResult"));\r
-               applicationContext.close();\r
-       }\r
-\r
-       public void testPlaceHoldersExec() throws Exception {\r
-               ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.exec.xml");\r
-\r
-               ExecutionContext executionContext = (ExecutionContext) applicationContext\r
-                               .getBean("executionContext");\r
-               Map<String, String> executionParameters = new HashMap<String, String>();\r
-               executionParameters.put("p1", "e1");\r
-               executionParameters.put("p2", "e2");\r
-               executionParameters.put("p3", "e3");\r
-               executionParameters.put("p4", "e4");\r
-               executionParameters.put("p5", "e5");\r
-               executionParameters.put("p6", "e6");\r
-               addVariables(executionContext, executionParameters);\r
-\r
-               ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
-               validateTestResult((SimpleTestResult) applicationContext\r
-                               .getBean("myTestResult"));\r
-               applicationContext.close();\r
-       }\r
-\r
-       public void testCanonicFlowParameters() throws Exception {\r
-               configureAndExecuteSlcFlow("canonic-001.xml", "canonic.001");\r
-       }\r
-\r
-       public void testCanonicDefaultValues() throws Exception {\r
-               configureAndExecuteSlcFlow("canonic-002.xml", "canonic.002");\r
-       }\r
-\r
-       public void testCanonicMissingValues() throws Exception {\r
-               try {\r
-                       configureAndExecuteSlcFlow("canonic-003.error.xml", "canonic.003");\r
-                       fail("Parameter not set - should be rejected.");\r
-               } catch (BeanCreationException e) {\r
-                       // exception expected\r
-                       logException(e);\r
-               }\r
-       }\r
-\r
-       public void testCanonicUnknownParameter() throws Exception {\r
-               try {\r
-                       configureAndExecuteSlcFlow("canonic-004.error.xml", "canonic.004");\r
-                       fail("Unknown parameter set - should be rejected.");\r
-               } catch (BeanCreationException e) {\r
-                       // exception expected\r
-                       logException(e);\r
-               }\r
-       }\r
-\r
-       public void testListSetMap() throws Exception {\r
-               ConfigurableApplicationContext applicationContext = createApplicationContext("listSetMap.xml");\r
-               ExecutionFlow executionFlow = (ExecutionFlow) applicationContext\r
-                               .getBean("myFlow");\r
-               executionFlow.run();\r
-\r
-               validateTestResult((SimpleTestResult) applicationContext\r
-                               .getBean("myTestResult"));\r
-\r
-               // BasicTestData res = (BasicTestData)\r
-               // applicationContext.getBean("cascadingComplex.testData");\r
-               // log.info("res=" + res.getReached().toString());\r
-\r
-               applicationContext.close();\r
-       }\r
-\r
-       public void testListSetMapMultipleFlows() throws Exception {\r
-               ConfigurableApplicationContext applicationContext = createApplicationContext("listSetMapMultipleFlow.xml");\r
-               ((ExecutionFlow) applicationContext.getBean("flow1")).run();\r
-               SimpleTestResult res = (SimpleTestResult) applicationContext\r
-                               .getBean("myTestResult");\r
-               validateTestResult(res);\r
-               res.getParts().clear();\r
-               ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
-               validateTestResult(res, TestStatus.FAILED);\r
-               applicationContext.close();\r
-       }\r
-\r
-       protected void addVariables(ExecutionContext executionContext,\r
-                       Map<String, String> vars) {\r
-               for (String key : vars.keySet())\r
-                       executionContext.setVariable(key, vars.get(key));\r
-       }\r
-}\r
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/DefaultAgentCliTest.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/DefaultAgentCliTest.java
deleted file mode 100644 (file)
index a7d9b8b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.argeo.slc.core.execution;
-
-import java.net.URI;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-public class DefaultAgentCliTest extends TestCase {
-       public void testArgsToUris() {
-               String[] args = { "org.argeo.slc.demo.minimal", "HelloWorld/WithVar",
-                               "--testKey", "555" };
-               List<URI> uris = DefaultAgentCli.asURIs(args);
-               assertEquals(1, uris.size());
-               assertEquals(
-                               "flow:/org.argeo.slc.demo.minimal/HelloWorld/WithVar?testKey=555",
-                               uris.get(0).toString());
-       }
-}
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/ExceptionIfInitCalledTwice.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/ExceptionIfInitCalledTwice.java
deleted file mode 100644 (file)
index 55afdc0..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.InitializingBean;
-
-public class ExceptionIfInitCalledTwice implements Runnable, InitializingBean {
-       private final static Log log = LogFactory
-                       .getLog(ExceptionIfInitCalledTwice.class);
-
-       private Boolean calledOnce = false;
-
-       public void run() {
-               log.info(getClass().getSimpleName() + " ran properly");
-       }
-
-       public void afterPropertiesSet() throws Exception {
-               log.info(getClass().getSimpleName() + " init method called");
-
-               if (calledOnce)
-                       throw new SlcException(getClass().getSimpleName()
-                                       + "init method called twice.");
-               else
-                       calledOnce = true;
-       }
-}
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesSpringTest.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesSpringTest.java
deleted file mode 100644 (file)
index 8b3d2ec..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-
-public class FileExecutionResourcesSpringTest extends
-               AbstractExecutionFlowTestCase {
-       private String basePath = FileExecutionResources.DEFAULT_EXECUTION_RESOURCES_TMP_PATH;
-
-       public void testSimple() throws Exception {
-               File file = getFile("subdir/writeTo");
-               try {
-                       assertFalse(file.exists());
-                       configureAndExecuteSlcFlow("executionResources.xml",
-                                       "executionResources.simple");
-                       assertTrue(file.exists());
-               } finally {
-                       file.deleteOnExit();
-               }
-       }
-
-       public void testPlaceholderPass() throws Exception {
-               File file = getFile("subdir/60");
-               try {
-                       assertFalse(file.exists());
-                       configureAndExecuteSlcFlow("executionResources.xml",
-                                       "executionResources.placeholderPass");
-                       assertTrue(file.exists());
-               } finally {
-                       file.deleteOnExit();
-               }
-       }
-
-       /**
-        * Test that it generate the wrong file because of issue when using
-        * execution placeholder in contructor-arg
-        */
-       public void testPlaceholderFail() throws Exception {
-               File file = getFile("subdir/@{var}");
-               try {
-                       assertFalse(file.exists());
-                       configureAndExecuteSlcFlow("executionResources.xml",
-                                       "executionResources.placeholderFail");
-                       assertTrue(file.exists());
-               } finally {
-                       file.deleteOnExit();
-               }
-       }
-
-       protected File getFile(String relativePath) {
-               return new File(basePath + File.separator
-                               + relativePath.replace('/', File.separatorChar));
-       }
-}
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesTest.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesTest.java
deleted file mode 100644 (file)
index e2dae65..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-
-import junit.framework.TestCase;
-
-import org.apache.commons.io.FileUtils;
-import org.argeo.slc.execution.ExecutionContext;
-import org.springframework.core.io.Resource;
-
-public class FileExecutionResourcesTest extends TestCase {
-       public void testGetWritableFile() throws Exception {
-               FileExecutionResources executionResources = new FileExecutionResources();
-               ExecutionContext executionContext = new MapExecutionContext();
-               executionResources.setExecutionContext(executionContext);
-
-               String expected = "TEST";
-               String reached = "";
-               try {
-                       // Resource
-                       Resource resource = executionResources
-                                       .getWritableResource("subdir1/textRes.txt");
-                       assertTrue(resource.getFile().getParentFile().exists());
-                       assertFalse(resource.getFile().exists());
-                       FileUtils.writeStringToFile(resource.getFile(), expected);
-                       reached = FileUtils.readFileToString(resource.getFile());
-                       assertEquals(expected, reached);
-
-                       // File
-                       File file = executionResources.getFile("subdir2/textFile.txt");
-                       assertFalse(file.getParentFile().exists());
-                       assertFalse(file.exists());
-                       FileUtils.writeStringToFile(file, expected);
-                       reached = FileUtils.readFileToString(file);
-                       assertEquals(expected, reached);
-               } finally {
-                       if (executionResources.getBaseDir() != null
-                                       && executionResources.getBaseDir().exists())
-                               FileUtils.deleteDirectory(executionResources.getBaseDir());
-               }
-
-       }
-}
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/ParameterRefTest.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/ParameterRefTest.java
deleted file mode 100644 (file)
index 35df7eb..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.argeo.slc.core.test.SimpleTestResult;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.test.TestStatus;
-import org.springframework.context.ConfigurableApplicationContext;
-
-public class ParameterRefTest extends AbstractExecutionFlowTestCase {
-       public void test001() throws Exception {
-               ConfigurableApplicationContext applicationContext = createApplicationContext("parameterRef.xml");
-               ((ExecutionFlow) applicationContext.getBean("parameterRef.001")).run();
-
-               SimpleTestResult res = (SimpleTestResult) applicationContext
-                               .getBean("parameterRef.testResult");
-               assertEquals(res.getParts().get(0).getStatus(), TestStatus.PASSED);
-               assertEquals(res.getParts().get(1).getStatus(), TestStatus.FAILED);
-
-               applicationContext.close();
-       }
-
-}
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/applicationContext.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/applicationContext.xml
deleted file mode 100644 (file)
index d83c2c1..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" /> \r
-\r
-       <bean id="executionModule_1" class="org.argeo.slc.core.execution.SimpleSpringExecutionModule" >\r
-               <property name="executionContext">\r
-                       <ref bean="executionContext" />\r
-               </property>     \r
-               <property name="name" value="dummyname" />\r
-               <property name="version" value="dummyversion" />\r
-       </bean>\r
\r
-       <bean id="main" parent="slcTemplate.simpleFlow">\r
-               <constructor-arg>\r
-                       <bean parent="slcTemplate.simpleSpec">\r
-                               <property name="attributes">\r
-                                       <map>\r
-                                               <entry key="testKey">\r
-                                                       <bean parent="specAttr.primitive" p:value="660" />\r
-                                               </entry>\r
-                                       </map>\r
-                               </property>\r
-                       </bean>\r
-               </constructor-arg>\r
-               <property name="executables">\r
-                       <list>\r
-                               <ref local="echo1" />\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="echo1" parent="task.echo" scope="execution">\r
-               <property name="message"\r
-                       value="From main! @{testKey}" />\r
-               <aop:scoped-proxy />\r
-       </bean>\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-001.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-001.xml
deleted file mode 100644 (file)
index a1c59c9..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="canonic.xml" />\r
-\r
-       <bean id="canonic.001" parent="canonic.flowTemplate">\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="parameterAtInstantiation" value="1" />\r
-                       </map>\r
-               </constructor-arg>\r
-       </bean>\r
-</beans>\r
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-002.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-002.xml
deleted file mode 100644 (file)
index 57f0c8a..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="canonic.xml" />\r
-\r
-       <bean id="canonic.002" parent="canonic.flowTemplate">\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="parameterAtInstantiation" value="2" />\r
-                               <entry key="displayWithoutControl" value="102" />\r
-                               <entry key="displayWithControl" value="202" />\r
-                               <entry key="hide" value="202" />\r
-                               <entry key="notParameterAtInstantiation" value="202" />\r
-                       </map>\r
-               </constructor-arg>\r
-       </bean>\r
-</beans>\r
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-003.error.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-003.error.xml
deleted file mode 100644 (file)
index 6de8810..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="canonic.xml" />\r
-\r
-       <bean id="canonic.003" parent="canonic.flowTemplate">\r
-               <constructor-arg>\r
-                       <map>\r
-                               <!-- missing parameter -->\r
-                               <entry key="displayWithoutControl" value="102" />\r
-                               <entry key="displayWithControl" value="202" />\r
-                               <entry key="hide" value="202" />\r
-                       </map>\r
-               </constructor-arg>\r
-       </bean>\r
-</beans>\r
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-004.error.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic-004.error.xml
deleted file mode 100644 (file)
index 2638ed6..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="canonic.xml" />\r
-\r
-       <bean id="canonic.004" parent="canonic.flowTemplate">\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="parameterAtInstantiation" value="2" />\r
-                               <entry key="displayWithoutControl" value="102" />\r
-                               <entry key="displayWithControl" value="202" />\r
-                               <entry key="hide" value="202" />\r
-                               <entry key="unknownParameter" value="1" />\r
-                       </map>\r
-               </constructor-arg>\r
-       </bean>\r
-</beans>\r
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/canonic.xml
deleted file mode 100644 (file)
index 8d6af0e..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" />\r
-\r
-       <bean id="canonic.spec" parent="slcTemplate.simpleSpec">\r
-               <property name="attributes">\r
-                       <map>\r
-                               <entry key="parameterAtInstantiation">\r
-                                       <bean parent="specAttr.primitive" p:isParameter="true" p:type="integer" />\r
-                               </entry>\r
-                               <entry key="displayWithoutControl">\r
-                                       <bean parent="specAttr.primitive" p:value="100" p:isParameter="true"\r
-                                               p:isFrozen="true" p:type="integer" />\r
-                               </entry>\r
-                               <entry key="displayWithControl">\r
-                                       <bean parent="specAttr.primitive" p:value="200" p:isParameter="true"\r
-                                               p:isFrozen="false" p:type="integer" />\r
-                               </entry>\r
-                               <entry key="hide">\r
-                                       <bean parent="specAttr.primitive" p:value="300" p:isParameter="true"\r
-                                               p:isFrozen="false" p:isHidden="true" p:type="integer" />\r
-                               </entry>                        \r
-                               <entry key="notParameterAtInstantiation">\r
-                                       <bean parent="specAttr.primitive" p:value="400" p:isParameter="false"\r
-                                               p:isFrozen="false" p:isHidden="false" p:type="integer" />\r
-                               </entry>                                                        \r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="canonic.flowTemplate" parent="slcTemplate.simpleFlow"\r
-               abstract="true">\r
-               <constructor-arg ref="canonic.spec" />\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.echo"\r
-                                       p:message="Canonical: displayWithControl=@{displayWithControl}, displayWithoutControl=@{displayWithoutControl}, hide=@{hide}">\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/executionResources.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/executionResources.xml
deleted file mode 100644 (file)
index 654f8b4..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" />\r
-\r
-       <bean id="executionResources.spec" parent="slcTemplate.simpleSpec">\r
-               <property name="attributes">\r
-                       <map>\r
-                               <entry key="var">\r
-                                       <bean parent="specAttr.primitive" p:isParameter="false"\r
-                                               p:type="integer" p:value="60" />\r
-                               </entry>\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="executionResources.placeholderPass" parent="slcTemplate.simpleFlow">\r
-               <constructor-arg ref="executionResources.spec" />\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.echo">\r
-                                       <property name="message" value="DATA" />\r
-                                       <property name="writeTo">\r
-                                               <bean parent="slcTemplate.resourcesFactoryBean" scope="execution">\r
-                                                       <property name="executionResources" ref="executionResources" />\r
-                                                       <property name="relativePath" value="subdir/@{var}" />\r
-                                                       <aop:scoped-proxy />\r
-                                               </bean>\r
-                                       </property>\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="executionResources.placeholderFail" parent="slcTemplate.simpleFlow">\r
-               <constructor-arg ref="executionResources.spec" />\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.echo">\r
-                                       <property name="message" value="DATA" />\r
-                                       <property name="writeTo">\r
-                                               <bean factory-bean="executionResources" factory-method="getWritableResource"\r
-                                                       scope="execution">\r
-                                                       <constructor-arg value="subdir/@{var}" />\r
-                                                       <aop:scoped-proxy />\r
-                                               </bean>\r
-                                       </property>\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="executionResources.simple" parent="slcTemplate.simpleFlow">\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.echo">\r
-                                       <property name="message" value="DATA" />\r
-                                       <property name="writeTo">\r
-                                               <bean factory-bean="executionResources" factory-method="getWritableResource"\r
-                                                       scope="execution">\r
-                                                       <constructor-arg value="subdir/writeTo" />\r
-                                                       <aop:scoped-proxy />\r
-                                               </bean>\r
-                                       </property>\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="executionResources" parent="slcTemplate.fileResources">\r
-               <property name="executionContext" ref="executionContext" />\r
-               <property name="withExecutionSubdirectory" value="false" />\r
-       </bean>\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/imports.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/imports.xml
deleted file mode 100644 (file)
index 7ddb4ea..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (C) 2007-2012 Argeo GmbH
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-            http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-<!-- Copyright (C) 2007-2012 Mathieu Baudier Licensed under the Apache License, 
-       Version 2.0 (the "License"); you may not use this file except in compliance 
-       with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
-       Unless required by applicable law or agreed to in writing, software distributed 
-       under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
-       OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
-       the specific language governing permissions and limitations under the License. -->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
-       <import resource="classpath:org/argeo/slc/core/execution/spring.xml" />
-       <import resource="classpath:/org/argeo/slc/core/test/spring.xml" />
-
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/listSetMap.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/listSetMap.xml
deleted file mode 100644 (file)
index 8cf72e3..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" /> \r
-\r
-       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
-               <property name="testDefinition" ref="basic.testDef" />\r
-               <property name="testResult" ref="myTestResult"/>\r
-       </bean>         \r
-\r
-       <bean id="myFlow" parent="slcTemplate.simpleFlow">\r
-               <constructor-arg>\r
-                       <bean parent="slcTemplate.simpleSpec">\r
-                               <property name="attributes">\r
-                                       <map>\r
-                                               <entry key="testKey">\r
-                                                       <bean parent="specAttr.primitive" p:value="myValue" />\r
-                                               </entry>\r
-                                       </map>\r
-                               </property>\r
-                       </bean>\r
-               </constructor-arg>\r
-               <property name="executables">\r
-                       <list>\r
-                               <ref local="echo1" />\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="simpleMap.testData" />\r
-                               </bean>                         \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingMap.testData" />\r
-                               </bean>                         \r
-                                               \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="simpleList.testData" />\r
-                               </bean>                         \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingList.testData" />\r
-                               </bean>                         \r
-                                                       \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="simpleSet.testData" />\r
-                               </bean>                         \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingSet.testData" />\r
-                               </bean> \r
-                                                       \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingListMap.testData" />\r
-                               </bean>                         \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingSetMap.testData" />\r
-                               </bean> \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingComplex.testData" />\r
-                               </bean>                                 \r
-       \r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-\r
-       <bean id="simpleMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <map>\r
-                               <entry key="key1" value="myValue_myValue" />\r
-                       </map>\r
-               </property>\r
-               <property name="reached">\r
-                       <map>\r
-                               <entry key="key1" value="@{testKey}_@{testKey}" />\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-       \r
-       <bean id="cascadingMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <map>\r
-                               <entry key="key3">\r
-                                       <map>\r
-                                               <entry key="key2">\r
-                                                       <map>\r
-                                                               <entry key="key1" value="myValue" />\r
-                                                       </map>\r
-                                               </entry>\r
-                                               <entry key="key2bis" value="myValue" />\r
-                                       </map>\r
-                               </entry>\r
-                       </map>\r
-               </property>\r
-               <property name="reached">\r
-                       <map>\r
-                               <entry key="key3">\r
-                                       <map>\r
-                                               <entry key="key2">\r
-                                                       <map>\r
-                                                               <entry key="key1" value="@{testKey}" />\r
-                                                       </map>\r
-                                               </entry>\r
-                                               <entry key="key2bis" value="@{testKey}" />\r
-                                       </map>\r
-                               </entry>\r
-                       </map>\r
-               </property>\r
-       </bean> \r
-       \r
-       <bean id="simpleList.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <list>\r
-                               <value>myValue</value>\r
-                               <value>_myValue_</value>\r
-                       </list>\r
-               </property>\r
-               <property name="reached">\r
-                       <list>\r
-                               <value>@{testKey}</value>\r
-                               <value>_@{testKey}_</value>                             \r
-                       </list>\r
-               </property>\r
-       </bean>         \r
-       \r
-       <bean id="cascadingList.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <list>\r
-                               <list>\r
-                                       <value>myValue</value>\r
-                                       <value>_myValue_</value>\r
-                               </list>\r
-                               <value>myValue</value>\r
-                       </list>\r
-               </property>\r
-               <property name="reached">\r
-                       <list>\r
-                               <list>\r
-                                       <value>@{testKey}</value>\r
-                                       <value>_@{testKey}_</value>\r
-                               </list>\r
-                               <value>@{testKey}</value>\r
-                       </list>\r
-               </property>\r
-       </bean>         \r
-       \r
-       <bean id="simpleSet.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <set>\r
-                               <value>myValue</value>\r
-                               <value>_myValue_</value>\r
-                       </set>\r
-               </property>\r
-               <property name="reached">\r
-                       <set>\r
-                               <value>@{testKey}</value>\r
-                               <value>_@{testKey}_</value>                             \r
-                       </set>\r
-               </property>\r
-       </bean>         \r
-       \r
-       <bean id="cascadingSet.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <set>\r
-                               <set>\r
-                                       <value>myValue</value>\r
-                                       <value>_myValue_</value>\r
-                               </set>\r
-                               <value>myValue</value>\r
-                       </set>\r
-               </property>\r
-               <property name="reached">\r
-                       <set>\r
-                               <set>\r
-                                       <value>@{testKey}</value>\r
-                                       <value>_@{testKey}_</value>\r
-                               </set>\r
-                               <value>@{testKey}</value>\r
-                       </set>\r
-               </property>\r
-       </bean>         \r
-       \r
-       <bean id="cascadingListMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <list>\r
-                               <map>\r
-                                       <entry key="key1" value="myValue" />\r
-                               </map>                                          \r
-                       </list>\r
-               </property>\r
-               <property name="reached">\r
-                       <list>\r
-                               <map>\r
-                                       <entry key="key1" value="@{testKey}" />\r
-                               </map>                                  \r
-                       </list>\r
-               </property>\r
-       </bean> \r
-       \r
-       <bean id="cascadingSetMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <set>\r
-                               <map>\r
-                                       <entry key="key1" value="myValue" />\r
-                               </map>                                          \r
-                       </set>\r
-               </property>\r
-               <property name="reached">\r
-                       <set>\r
-                               <map>\r
-                                       <entry key="key1" value="@{testKey}" />\r
-                               </map>                                  \r
-                       </set>\r
-               </property>\r
-       </bean>         \r
-       \r
-       <bean id="cascadingComplex.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <set>\r
-                               <map>\r
-                                       <entry key="key1" value="myValue" />\r
-                               </map>  \r
-                               <list>\r
-                                       <map>\r
-                                               <entry key="key1" value="myValue" />\r
-                                       </map>          \r
-                                       <set>\r
-                                               <set>\r
-                                                       <value>myValue</value>\r
-                                                       <value>_myValue_</value>\r
-                                                       <list>\r
-                                                               <list>\r
-                                                                       <value>myValue</value>\r
-                                                                       <value>_myValue_</value>\r
-                                                               </list>\r
-                                                               <value>myValue</value>\r
-                                                       </list>                                                 \r
-                                               </set>\r
-                                               <value>myValue</value>\r
-                                       </set>                                                                  \r
-                               </list> \r
-                               <set>\r
-                                       <map>\r
-                                               <entry key="key1" value="myValue" />\r
-                                       </map>  \r
-                               </set>                                                                                          \r
-                       </set>\r
-               </property>\r
-               <property name="reached">\r
-                       <set>\r
-                               <map>\r
-                                       <entry key="key1" value="@{testKey}" />\r
-                               </map>  \r
-                               <list>\r
-                                       <map>\r
-                                               <entry key="key1" value="@{testKey}" />\r
-                                       </map>          \r
-                                       <set>\r
-                                               <set>\r
-                                                       <value>@{testKey}</value>\r
-                                                       <value>_@{testKey}_</value>\r
-                                                       <list>\r
-                                                               <list>\r
-                                                                       <value>@{testKey}</value>\r
-                                                                       <value>_@{testKey}_</value>\r
-                                                               </list>\r
-                                                               <value>@{testKey}</value>\r
-                                                       </list>                                                 \r
-                                               </set>\r
-                                               <value>@{testKey}</value>\r
-                                       </set>                                                                  \r
-                               </list> \r
-                               <set>\r
-                                       <map>\r
-                                               <entry key="key1" value="@{testKey}" />\r
-                                       </map>  \r
-                               </set>                                                                                          \r
-                       </set>\r
-               </property>\r
-       </bean>                 \r
-       \r
-       <bean id="basic.testDef" class="org.argeo.slc.core.test.BasicTestDefinition">\r
-       </bean> \r
-\r
-\r
-       <bean id="echo1" parent="task.echo" scope="prototype">\r
-               <property name="message"\r
-                       value="testKey=@{testKey}" />\r
-       </bean>\r
-       \r
-       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/listSetMapMultipleFlow.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/listSetMapMultipleFlow.xml
deleted file mode 100644 (file)
index b8626f8..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" /> \r
-\r
-       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
-               <property name="testDefinition" ref="basic.testDef" />\r
-               <property name="testResult" ref="myTestResult"/>\r
-       </bean>         \r
-\r
-       <bean id="abstractFlow" parent="slcTemplate.simpleFlow" abstract="true">\r
-               <property name="executables">\r
-                       <list>\r
-                               <ref local="echo1" />\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="simpleMap.testData" />\r
-                               </bean>                         \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingMap.testData" />\r
-                               </bean>                         \r
-                                               \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="simpleList.testData" />\r
-                               </bean>                         \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingList.testData" />\r
-                               </bean>                         \r
-                                                       \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="simpleSet.testData" />\r
-                               </bean>                         \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingSet.testData" />\r
-                               </bean> \r
-                                                       \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingListMap.testData" />\r
-                               </bean>                         \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingSetMap.testData" />\r
-                               </bean> \r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData" ref="cascadingComplex.testData" />\r
-                               </bean>                                 \r
-       \r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="flow1" parent="abstractFlow" scope="prototype">\r
-               <constructor-arg>\r
-                       <bean parent="slcTemplate.simpleSpec">\r
-                               <property name="attributes">\r
-                                       <map>\r
-                                               <entry key="testKey">\r
-                                                       <bean parent="specAttr.primitive" p:value="myValue" />\r
-                                               </entry>\r
-                                       </map>\r
-                               </property>\r
-                       </bean>\r
-               </constructor-arg>\r
-       </bean> \r
-\r
-       <bean id="flow2" parent="abstractFlow" scope="prototype">\r
-               <constructor-arg>\r
-                       <bean parent="slcTemplate.simpleSpec">\r
-                               <property name="attributes">\r
-                                       <map>\r
-                                               <entry key="testKey">\r
-                                                       <bean parent="specAttr.primitive" p:value="myValue2" />\r
-                                               </entry>\r
-                                       </map>\r
-                               </property>\r
-                       </bean>\r
-               </constructor-arg>\r
-       </bean> \r
-\r
-\r
-       <bean id="simpleMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <map>\r
-                               <entry key="key1" value="myValue_myValue" />\r
-                       </map>\r
-               </property>\r
-               <property name="reached">\r
-                       <map>\r
-                               <entry key="key1" value="@{testKey}_@{testKey}" />\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-       \r
-       <bean id="cascadingMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <map>\r
-                               <entry key="key3">\r
-                                       <map>\r
-                                               <entry key="key2">\r
-                                                       <map>\r
-                                                               <entry key="key1" value="myValue" />\r
-                                                       </map>\r
-                                               </entry>\r
-                                               <entry key="key2bis" value="myValue" />\r
-                                       </map>\r
-                               </entry>\r
-                       </map>\r
-               </property>\r
-               <property name="reached">\r
-                       <map>\r
-                               <entry key="key3">\r
-                                       <map>\r
-                                               <entry key="key2">\r
-                                                       <map>\r
-                                                               <entry key="key1" value="@{testKey}" />\r
-                                                       </map>\r
-                                               </entry>\r
-                                               <entry key="key2bis" value="@{testKey}" />\r
-                                       </map>\r
-                               </entry>\r
-                       </map>\r
-               </property>\r
-       </bean> \r
-       \r
-       <bean id="simpleList.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <list>\r
-                               <value>myValue</value>\r
-                               <value>_myValue_</value>\r
-                       </list>\r
-               </property>\r
-               <property name="reached">\r
-                       <list>\r
-                               <value>@{testKey}</value>\r
-                               <value>_@{testKey}_</value>                             \r
-                       </list>\r
-               </property>\r
-       </bean>         \r
-       \r
-       <bean id="cascadingList.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <list>\r
-                               <list>\r
-                                       <value>myValue</value>\r
-                                       <value>_myValue_</value>\r
-                               </list>\r
-                               <value>myValue</value>\r
-                       </list>\r
-               </property>\r
-               <property name="reached">\r
-                       <list>\r
-                               <list>\r
-                                       <value>@{testKey}</value>\r
-                                       <value>_@{testKey}_</value>\r
-                               </list>\r
-                               <value>@{testKey}</value>\r
-                       </list>\r
-               </property>\r
-       </bean>         \r
-       \r
-       <bean id="simpleSet.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <set>\r
-                               <value>myValue</value>\r
-                               <value>_myValue_</value>\r
-                       </set>\r
-               </property>\r
-               <property name="reached">\r
-                       <set>\r
-                               <value>@{testKey}</value>\r
-                               <value>_@{testKey}_</value>                             \r
-                       </set>\r
-               </property>\r
-       </bean>         \r
-       \r
-       <bean id="cascadingSet.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <set>\r
-                               <set>\r
-                                       <value>myValue</value>\r
-                                       <value>_myValue_</value>\r
-                               </set>\r
-                               <value>myValue</value>\r
-                       </set>\r
-               </property>\r
-               <property name="reached">\r
-                       <set>\r
-                               <set>\r
-                                       <value>@{testKey}</value>\r
-                                       <value>_@{testKey}_</value>\r
-                               </set>\r
-                               <value>@{testKey}</value>\r
-                       </set>\r
-               </property>\r
-       </bean>         \r
-       \r
-       <bean id="cascadingListMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <list>\r
-                               <map>\r
-                                       <entry key="key1" value="myValue" />\r
-                               </map>                                          \r
-                       </list>\r
-               </property>\r
-               <property name="reached">\r
-                       <list>\r
-                               <map>\r
-                                       <entry key="key1" value="@{testKey}" />\r
-                               </map>                                  \r
-                       </list>\r
-               </property>\r
-       </bean> \r
-       \r
-       <bean id="cascadingSetMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <set>\r
-                               <map>\r
-                                       <entry key="key1" value="myValue" />\r
-                               </map>                                          \r
-                       </set>\r
-               </property>\r
-               <property name="reached">\r
-                       <set>\r
-                               <map>\r
-                                       <entry key="key1" value="@{testKey}" />\r
-                               </map>                                  \r
-                       </set>\r
-               </property>\r
-       </bean>         \r
-       \r
-       <bean id="cascadingComplex.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
-               <property name="expected">\r
-                       <set>\r
-                               <map>\r
-                                       <entry key="key1" value="myValue" />\r
-                               </map>  \r
-                               <list>\r
-                                       <map>\r
-                                               <entry key="key1" value="myValue" />\r
-                                       </map>          \r
-                                       <set>\r
-                                               <set>\r
-                                                       <value>myValue</value>\r
-                                                       <value>_myValue_</value>\r
-                                                       <list>\r
-                                                               <list>\r
-                                                                       <value>myValue</value>\r
-                                                                       <value>_myValue_</value>\r
-                                                               </list>\r
-                                                               <value>myValue</value>\r
-                                                       </list>                                                 \r
-                                               </set>\r
-                                               <value>myValue</value>\r
-                                       </set>                                                                  \r
-                               </list> \r
-                               <set>\r
-                                       <map>\r
-                                               <entry key="key1" value="myValue" />\r
-                                       </map>  \r
-                               </set>                                                                                          \r
-                       </set>\r
-               </property>\r
-               <property name="reached">\r
-                       <set>\r
-                               <map>\r
-                                       <entry key="key1" value="@{testKey}" />\r
-                               </map>  \r
-                               <list>\r
-                                       <map>\r
-                                               <entry key="key1" value="@{testKey}" />\r
-                                       </map>          \r
-                                       <set>\r
-                                               <set>\r
-                                                       <value>@{testKey}</value>\r
-                                                       <value>_@{testKey}_</value>\r
-                                                       <list>\r
-                                                               <list>\r
-                                                                       <value>@{testKey}</value>\r
-                                                                       <value>_@{testKey}_</value>\r
-                                                               </list>\r
-                                                               <value>@{testKey}</value>\r
-                                                       </list>                                                 \r
-                                               </set>\r
-                                               <value>@{testKey}</value>\r
-                                       </set>                                                                  \r
-                               </list> \r
-                               <set>\r
-                                       <map>\r
-                                               <entry key="key1" value="@{testKey}" />\r
-                                       </map>  \r
-                               </set>                                                                                          \r
-                       </set>\r
-               </property>\r
-       </bean>                 \r
-               \r
-       <bean id="basic.testDef" class="org.argeo.slc.core.test.BasicTestDefinition">\r
-       </bean> \r
-\r
-\r
-       <bean id="echo1" parent="task.echo" scope="prototype">\r
-               <property name="message"\r
-                       value="testKey=@{testKey}" />\r
-       </bean>\r
-       \r
-       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/minimal.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/minimal.xml
deleted file mode 100644 (file)
index 5b16697..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" /> \r
-\r
-       <bean id="minimal" parent="slcTemplate.simpleFlow">\r
-               <property name="executionSpec">\r
-                       <bean parent="slcTemplate.simpleSpec">\r
-<!--                           <property name="attributes">\r
-                                       <map>\r
-                                               <entry key="testKey">\r
-                                                       <bean parent="specAttr.primitive" p:value="660" />\r
-                                               </entry>\r
-                                       </map>\r
-                               </property> -->\r
-                       </bean>\r
-               </property>\r
-               <property name="executables">\r
-                       <list>\r
-                               <ref local="echo1" />\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="echo1" parent="task.echo" scope="execution">\r
-               <property name="message"\r
-                       value="From minimal" />\r
-               <aop:scoped-proxy />\r
-       </bean>\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/multipleFlow.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/multipleFlow.xml
deleted file mode 100644 (file)
index 58a43e4..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" /> \r
-\r
-       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
-\r
-       <bean id="myTestDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
-\r
-       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
-               <property name="testDefinition" ref="myTestDef" />\r
-               <property name="testResult" ref="myTestResult"/>\r
-       </bean>         \r
-\r
-       <bean id="fileDiff.spec" parent="slcTemplate.simpleSpec">\r
-               <property name="attributes">\r
-                       <map>\r
-                               <entry key="fileName">\r
-                                       <bean parent="specAttr.primitive" p:isParameter="true" p:type="string"\r
-                                               p:isFrozen="true" />\r
-                               </entry>\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-\r
-       <bean id="fileDiff.flowTemplate" parent="slcTemplate.simpleFlow"\r
-               abstract="true">\r
-               <property name="path" value="/fileDiff/testcases" />\r
-               <constructor-arg ref="fileDiff.spec" />\r
-               <property name="executables">\r
-                       <list>                  \r
-                               <bean parent="task.echo">\r
-                                       <property name="message" value="fileName=@{fileName}" />\r
-                               </bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="file1" />\r
-                                                       <property name="reached" value="@{fileName}" />\r
-                                               </bean>\r
-                                       </property>     \r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-       \r
-       <bean id="echo" parent="task.echo" scope="prototype">\r
-               <property name="message" value="fileName=@{fileName}" />\r
-       </bean>                 \r
-       \r
-       <bean id="flow1" parent="fileDiff.flowTemplate">\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="fileName" value="file1" />\r
-                       </map>\r
-               </constructor-arg>\r
-       </bean> \r
-\r
-       <bean id="flow2" parent="fileDiff.flowTemplate">\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="fileName" value="file2" />\r
-                       </map>\r
-               </constructor-arg>\r
-       </bean> \r
\r
\r
- <!-- \r
-       <bean id="flow1" parent="slcTemplate.simpleFlow">\r
-               <property name="path" value="/fileDiff/testcases" />\r
-               <constructor-arg ref="fileDiff.spec" />\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="fileName" value="file1" />\r
-                       </map>\r
-               </constructor-arg>              \r
-               <property name="executables">\r
-                       <list>                  \r
-                               <bean parent="task.echo" scope="execution">\r
-                                       <property name="message" value="fileName=@{fileName}" />\r
-                                       <aop:scoped-proxy />\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="flow2" parent="slcTemplate.simpleFlow">\r
-               <property name="path" value="/fileDiff/testcases" />\r
-               <constructor-arg ref="fileDiff.spec" />\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="fileName" value="file2" />\r
-                       </map>\r
-               </constructor-arg>              \r
-               <property name="executables">\r
-                       <list>                  \r
-                               <bean parent="task.echo" scope="execution">\r
-                                       <property name="message" value="fileName=@{fileName}" />\r
-                                       <aop:scoped-proxy />\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
- -->\r
-<!-- \r
-       <bean id="main" parent="slcTemplate.simpleFlow">\r
-               <property name="executables">\r
-                       <list>          \r
-                               <ref bean="flow1"/>     \r
-                               <ref bean="flow2"/>     \r
-                       </list>\r
-               </property>\r
-       </bean>\r
- -->\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/parameterRef.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/parameterRef.xml
deleted file mode 100644 (file)
index 98cc14d..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" />\r
-\r
-       <!-- DEFINITIONS -->\r
-       <bean id="parameterRef.spec" parent="slcTemplate.simpleSpec">\r
-               <property name="attributes">\r
-                       <map>\r
-                               <entry key="exceptionIfInitCalledTwice">\r
-                                       <bean parent="specAttr.ref"\r
-                                               p:targetClass="org.argeo.slc.core.execution.ExceptionIfInitCalledTwice"\r
-                                               p:isParameter="true" p:isFrozen="true" />\r
-                               </entry>\r
-                               <entry key="testData1">\r
-                                       <bean parent="specAttr.ref" p:targetClass="org.argeo.slc.core.test.BasicTestData"\r
-                                               p:isParameter="true" p:isFrozen="true" />\r
-                               </entry>\r
-                               <entry key="testData2">\r
-                                       <bean parent="specAttr.ref" p:targetClass="org.argeo.slc.core.test.BasicTestData"\r
-                                               p:isParameter="true" p:isFrozen="true" />\r
-                               </entry>\r
-                               <entry key="testedComponentId">\r
-                                       <bean parent="specAttr.primitive" p:value="100" p:isParameter="true"\r
-                                               p:type="integer" />\r
-                               </entry>\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="parameterRef.flowTemplate" parent="slcTemplate.simpleFlow"\r
-               abstract="true">\r
-               <constructor-arg ref="parameterRef.spec" />\r
-               <property name="executables">\r
-                       <list>\r
-                               <!-- Primitive -->\r
-                               <bean parent="task.echo" scope="execution">\r
-                                       <property name="message" value="testedComponentId=@{testedComponentId}" />\r
-                               </bean>\r
-\r
-                               <!-- Exception if init called twice -->\r
-                               <bean parent="parameterRef">\r
-                                       <constructor-arg value="exceptionIfInitCalledTwice" />\r
-                               </bean>\r
-                               <bean parent="parameterRef">\r
-                                       <property name="name" value="exceptionIfInitCalledTwice" />\r
-                               </bean>\r
-\r
-                               <!-- Basic tests -->\r
-                               <bean parent="parameterRef.testRun">\r
-                                       <property name="testData">\r
-                                               <bean parent="parameterRef">\r
-                                                       <constructor-arg value="testData1" />\r
-                                               </bean>\r
-                                       </property>\r
-                               </bean>\r
-                               <bean parent="parameterRef.testRun">\r
-                                       <property name="testData" ref="ref1" />\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <!-- TEST CASES -->\r
-       <bean id="parameterRef.001" parent="parameterRef.flowTemplate">\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="exceptionIfInitCalledTwice">\r
-                                       <bean class="org.argeo.slc.core.execution.ExceptionIfInitCalledTwice" />\r
-                               </entry>\r
-                               <entry key="testData1">\r
-                                       <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                               <property name="expected" value="toto" />\r
-                                               <property name="reached" value="toto" />\r
-                                       </bean>\r
-                               </entry>\r
-                               <entry key="testData2">\r
-                                       <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                               <property name="expected" value="tata" />\r
-                                               <property name="reached" value="toto" />\r
-                                       </bean>\r
-                               </entry>\r
-                       </map>\r
-               </constructor-arg>\r
-       </bean>\r
-\r
-       <!-- UTILITIES -->\r
-\r
-       <bean id="ref1" parent="parameterRef">\r
-               <constructor-arg value="testData2" />\r
-       </bean>\r
-\r
-       <bean id="parameterRef.testResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
-\r
-       <bean id="parameterRef.testRun" class="org.argeo.slc.core.test.SimpleTestRun"\r
-               abstract="true">\r
-               <property name="testResult" ref="parameterRef.testResult" />\r
-               <property name="testDefinition">\r
-                       <bean class="org.argeo.slc.core.test.BasicTestDefinition" />\r
-               </property>\r
-       </bean>\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.exec.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.exec.xml
deleted file mode 100644 (file)
index a36b4a1..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" /> \r
-\r
-       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
-\r
-       <bean id="myTestDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
-\r
-       <bean id="echo1" parent="task.echo">\r
-               <property name="message" value="From minimal" />\r
-       </bean>\r
-\r
-       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
-               <property name="testDefinition" ref="myTestDef" />\r
-               <property name="testResult" ref="myTestResult"/>\r
-       </bean>         \r
-\r
-       <!-- \r
-               The Flow A contains the flow B as executable.\r
-       \r
-               Parameters\r
-               p1: flow A: default - flow B: - \r
-               p2: flow A: set     - flow B: - \r
-               p3: flow A: default - flow B: default \r
-               p4: flow A: set     - flow B: default\r
-               p5: flow A: default - flow B: set \r
-               p6: flow A: set     - flow B: set\r
-               p7: flow A: -       - flow B: default\r
-               p8: flow A: -       - flow B: set\r
-                \r
-               \r
-        -->\r
-\r
-       <bean id="flowA" parent="slcTemplate.simpleFlow">\r
-               <constructor-arg>\r
-                       <bean parent="slcTemplate.simpleSpec">\r
-                               <property name="attributes">\r
-                                       <map>\r
-                                               <entry key="p1"><bean parent="specAttr.primitive" p:value="da1" /></entry>\r
-                                               <entry key="p2"><bean parent="specAttr.primitive" p:value="da2" /></entry>                                              \r
-                                               <entry key="p3"><bean parent="specAttr.primitive" p:value="da3" /></entry>                                              \r
-                                               <entry key="p4"><bean parent="specAttr.primitive" p:value="da4" /></entry>                                              \r
-                                               <entry key="p5"><bean parent="specAttr.primitive" p:value="da5" /></entry>                                              \r
-                                               <entry key="p6"><bean parent="specAttr.primitive" p:value="da6" /></entry>                                              \r
-                                       </map>\r
-                               </property>\r
-                       </bean>\r
-               </constructor-arg>\r
-               <constructor-arg>               \r
-                       <map>\r
-                               <entry key="p2" value="va2"/>\r
-                               <entry key="p4" value="va4"/>\r
-                               <entry key="p6" value="va6"/>\r
-                       </map>\r
-               </constructor-arg>\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.echo"><property name="message" value="p1=@{p1}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da1" />\r
-                                                       <property name="reached" value="@{p1}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>\r
-                               <bean parent="task.echo"><property name="message" value="p2=@{p2}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va2" />\r
-                                                       <property name="reached" value="@{p2}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p3=@{p3}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da3" />\r
-                                                       <property name="reached" value="@{p3}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p4=@{p4}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va4" />\r
-                                                       <property name="reached" value="@{p4}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                                 \r
-                               <bean parent="task.echo"><property name="message" value="p5=@{p5}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da5" />\r
-                                                       <property name="reached" value="@{p5}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p6=@{p6}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va6" />\r
-                                                       <property name="reached" value="@{p6}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                                 \r
-                               <ref bean="flowB"/>                             \r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="flowB" parent="slcTemplate.simpleFlow" scope="prototype">\r
-               <constructor-arg>\r
-                       <bean parent="slcTemplate.simpleSpec">\r
-                               <property name="attributes">\r
-                                       <map>\r
-                                               <entry key="p3"><bean parent="specAttr.primitive" p:value="db3" /></entry>                                              \r
-                                               <entry key="p4"><bean parent="specAttr.primitive" p:value="db4" /></entry>\r
-                                               <entry key="p5"><bean parent="specAttr.primitive" p:value="db5" /></entry>                                              \r
-                                               <entry key="p6"><bean parent="specAttr.primitive" p:value="db6" /></entry>\r
-                                               <entry key="p7"><bean parent="specAttr.primitive" p:value="db7" /></entry>                                              \r
-                                               <entry key="p8"><bean parent="specAttr.primitive" p:value="db8" /></entry>\r
-                                       </map>\r
-                               </property>\r
-                       </bean>\r
-               </constructor-arg>\r
-               <constructor-arg>               \r
-                       <map>\r
-                               <entry key="p3" value="vb3"/>\r
-                               <entry key="p4" value="vb4"/>\r
-                               <entry key="p7" value="vb7"/>\r
-                       </map>\r
-               </constructor-arg>              \r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.echo"><property name="message" value="p1=@{p1}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da1" />\r
-                                                       <property name="reached" value="@{p1}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>\r
-                               <bean parent="task.echo"><property name="message" value="p2=@{p2}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va2" />\r
-                                                       <property name="reached" value="@{p2}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p3=@{p3}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da3" />\r
-                                                       <property name="reached" value="@{p3}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p4=@{p4}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va4" />\r
-                                                       <property name="reached" value="@{p4}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                                 \r
-                               <bean parent="task.echo"><property name="message" value="p5=@{p5}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da5" />\r
-                                                       <property name="reached" value="@{p5}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p6=@{p6}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va6" />\r
-                                                       <property name="reached" value="@{p6}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p7=@{p7}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="vb7" />\r
-                                                       <property name="reached" value="@{p7}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                                                         \r
-                               <bean parent="task.echo"><property name="message" value="p8=@{p8}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="db8" />\r
-                                                       <property name="reached" value="@{p8}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean> \r
-                               \r
-                               <!-- test in scope execution -->\r
-                               <bean parent="task.echo" scope="execution"><property name="message" value="p1=@{p1}" /><aop:scoped-proxy /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
-                                                       <property name="expected" value="e1" />\r
-                                                       <property name="reached" value="@{p1}" />\r
-                                                       <aop:scoped-proxy />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>\r
-                               <bean parent="task.echo" scope="execution"><property name="message" value="p2=@{p2}" /><aop:scoped-proxy /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
-                                                       <property name="expected" value="e2" />\r
-                                                       <property name="reached" value="@{p2}" />\r
-                                                       <aop:scoped-proxy />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo" scope="execution"><property name="message" value="p3=@{p3}" /><aop:scoped-proxy /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
-                                                       <property name="expected" value="e3" />\r
-                                                       <property name="reached" value="@{p3}" />\r
-                                                       <aop:scoped-proxy />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo" scope="execution"><property name="message" value="p4=@{p4}" /><aop:scoped-proxy /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
-                                                       <property name="expected" value="e4" />\r
-                                                       <property name="reached" value="@{p4}" />\r
-                                                       <aop:scoped-proxy />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                                 \r
-                               <bean parent="task.echo" scope="execution"><property name="message" value="p5=@{p5}" /><aop:scoped-proxy /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
-                                                       <property name="expected" value="e5" />\r
-                                                       <property name="reached" value="@{p5}" />\r
-                                                       <aop:scoped-proxy />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo" scope="execution"><property name="message" value="p6=@{p6}" /><aop:scoped-proxy /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
-                                                       <property name="expected" value="e6" />\r
-                                                       <property name="reached" value="@{p6}" />\r
-                                                       <aop:scoped-proxy />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>\r
-                                                               \r
-                               <!-- \r
-                                       p7 and p8 are not in the spec of FlowA and therefore can not be overridden\r
-                                       at the execution\r
-                                -->\r
-                               <bean parent="task.echo" scope="execution"><property name="message" value="p7=@{p7}" /><aop:scoped-proxy /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
-                                                       <property name="expected" value="vb7" />\r
-                                                       <property name="reached" value="@{p7}" />\r
-                                                       <aop:scoped-proxy />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                                                         \r
-                               <bean parent="task.echo" scope="execution"><property name="message" value="p8=@{p8}" /><aop:scoped-proxy /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
-                                                       <property name="expected" value="db8" />\r
-                                                       <property name="reached" value="@{p8}" />\r
-                                                       <aop:scoped-proxy />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>         \r
-                                                                                       \r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.xml
deleted file mode 100644 (file)
index 893768b..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" /> \r
-\r
-       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
-\r
-       <bean id="myTestDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
-\r
-       <bean id="echo1" parent="task.echo">\r
-               <property name="message" value="From minimal" />\r
-       </bean>\r
-\r
-       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
-               <property name="testDefinition" ref="myTestDef" />\r
-               <property name="testResult" ref="myTestResult"/>\r
-       </bean>         \r
-\r
-       <!-- \r
-               The Flow A contains the flow B as executable.\r
-       \r
-               Parameters\r
-               p1: flow A: default - flow B: - \r
-               p2: flow A: set     - flow B: - \r
-               p3: flow A: default - flow B: default \r
-               p4: flow A: set     - flow B: default\r
-               p5: flow A: default - flow B: set \r
-               p6: flow A: set     - flow B: set\r
-               p7: flow A: -       - flow B: default\r
-               p8: flow A: -       - flow B: set\r
-                \r
-               \r
-        -->\r
-\r
-       <bean id="flowA" parent="slcTemplate.simpleFlow">\r
-               <constructor-arg>\r
-                       <bean parent="slcTemplate.simpleSpec">\r
-                               <property name="attributes">\r
-                                       <map>\r
-                                               <entry key="p1"><bean parent="specAttr.primitive" p:value="da1" /></entry>\r
-                                               <entry key="p2"><bean parent="specAttr.primitive" p:value="da2" /></entry>                                              \r
-                                               <entry key="p3"><bean parent="specAttr.primitive" p:value="da3" /></entry>                                              \r
-                                               <entry key="p4"><bean parent="specAttr.primitive" p:value="da4" /></entry>                                              \r
-                                               <entry key="p5"><bean parent="specAttr.primitive" p:value="da5" /></entry>                                              \r
-                                               <entry key="p6"><bean parent="specAttr.primitive" p:value="da6" /></entry>                                              \r
-                                       </map>\r
-                               </property>\r
-                       </bean>\r
-               </constructor-arg>\r
-               <constructor-arg>               \r
-                       <map>\r
-                               <entry key="p2" value="va2"/>\r
-                               <entry key="p4" value="va4"/>\r
-                               <entry key="p6" value="va6"/>\r
-                       </map>\r
-               </constructor-arg>\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.echo"><property name="message" value="p1=@{p1}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da1" />\r
-                                                       <property name="reached" value="@{p1}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>\r
-                               <bean parent="task.echo"><property name="message" value="p2=@{p2}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va2" />\r
-                                                       <property name="reached" value="@{p2}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p3=@{p3}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da3" />\r
-                                                       <property name="reached" value="@{p3}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p4=@{p4}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va4" />\r
-                                                       <property name="reached" value="@{p4}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                                 \r
-                               <bean parent="task.echo"><property name="message" value="p5=@{p5}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da5" />\r
-                                                       <property name="reached" value="@{p5}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p6=@{p6}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va6" />\r
-                                                       <property name="reached" value="@{p6}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                                 \r
-                               <ref bean="flowB"/>                             \r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="flowB" parent="slcTemplate.simpleFlow" scope="prototype">\r
-               <constructor-arg>\r
-                       <bean parent="slcTemplate.simpleSpec">\r
-                               <property name="attributes">\r
-                                       <map>\r
-                                               <entry key="p3"><bean parent="specAttr.primitive" p:value="db3" /></entry>                                              \r
-                                               <entry key="p4"><bean parent="specAttr.primitive" p:value="db4" /></entry>\r
-                                               <entry key="p5"><bean parent="specAttr.primitive" p:value="db5" /></entry>                                              \r
-                                               <entry key="p6"><bean parent="specAttr.primitive" p:value="db6" /></entry>\r
-                                               <entry key="p7"><bean parent="specAttr.primitive" p:value="db7" /></entry>                                              \r
-                                               <entry key="p8"><bean parent="specAttr.primitive" p:value="db8" /></entry>\r
-                                       </map>\r
-                               </property>\r
-                       </bean>\r
-               </constructor-arg>\r
-               <constructor-arg>               \r
-                       <map>\r
-                               <entry key="p3" value="vb3"/>\r
-                               <entry key="p4" value="vb4"/>\r
-                               <entry key="p7" value="vb7"/>\r
-                       </map>\r
-               </constructor-arg>              \r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.echo"><property name="message" value="p1=@{p1}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da1" />\r
-                                                       <property name="reached" value="@{p1}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>\r
-                               <bean parent="task.echo"><property name="message" value="p2=@{p2}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va2" />\r
-                                                       <property name="reached" value="@{p2}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p3=@{p3}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da3" />\r
-                                                       <property name="reached" value="@{p3}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p4=@{p4}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va4" />\r
-                                                       <property name="reached" value="@{p4}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                                 \r
-                               <bean parent="task.echo"><property name="message" value="p5=@{p5}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="da5" />\r
-                                                       <property name="reached" value="@{p5}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p6=@{p6}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="va6" />\r
-                                                       <property name="reached" value="@{p6}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                         \r
-                               <bean parent="task.echo"><property name="message" value="p7=@{p7}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="vb7" />\r
-                                                       <property name="reached" value="@{p7}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean>                                                         \r
-                               <bean parent="task.echo"><property name="message" value="p8=@{p8}" /></bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                                       <property name="expected" value="db8" />\r
-                                                       <property name="reached" value="@{p8}" />\r
-                                               </bean>\r
-                                       </property>                                     \r
-                               </bean> \r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/specOverriding.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/specOverriding.xml
deleted file mode 100644 (file)
index de1dc85..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" /> \r
\r
-       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
-\r
-       <bean id="myTestDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
-\r
-       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
-               <property name="testDefinition" ref="myTestDef" />\r
-               <property name="testResult" ref="myTestResult"/>\r
-       </bean>         \r
\r
-       <bean id="spec1" parent="slcTemplate.simpleSpec">\r
-               <property name="attributes">\r
-                       <map>\r
-                               <entry key="testedComponentId">\r
-                                       <bean parent="specAttr.primitive" p:isParameter="true"\r
-                                               p:type="integer" />\r
-                               </entry>\r
-                               <entry key="testData1">\r
-                                       <bean parent="specAttr.ref" p:targetClass="org.argeo.slc.core.test.BasicTestData"\r
-                                               p:isParameter="true" p:isFrozen="true" />\r
-                               </entry>\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="flowTemplate1" parent="slcTemplate.simpleFlow"\r
-               abstract="true">\r
-               <constructor-arg ref="spec1" />\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.echo" scope="execution">\r
-                                       <property name="message" value="From basic @{testedComponentId}" />\r
-                                       <aop:scoped-proxy />\r
-                               </bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean parent="parameterRef">\r
-                                                       <constructor-arg value="testData1" />\r
-                                               </bean>\r
-                                       </property>\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="flow1" parent="flowTemplate1" scope="prototype">\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="testedComponentId" value="200" />\r
-                               <entry key="testData1">\r
-                                       <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
-                                               <aop:scoped-proxy/>\r
-                                               <property name="expected" value="tata101" />\r
-                                               <property name="reached" value="tata@{testedComponentId}" />\r
-                                       </bean>\r
-                               </entry>\r
-                       </map>                  \r
-               </constructor-arg>\r
-       </bean>\r
-\r
-       <bean id="spec2" parent="slcTemplate.simpleSpec">\r
-               <property name="attributes">\r
-                       <map>\r
-                               <entry key="testData1">\r
-                                       <bean parent="specAttr.ref" p:targetClass="org.argeo.slc.core.test.BasicTestData"\r
-                                               p:isParameter="true" p:isFrozen="true" />\r
-                               </entry>\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="flowTemplate2" parent="slcTemplate.simpleFlow" abstract="true">\r
-               <constructor-arg ref="spec2" />\r
-               <property name="executables">\r
-                       <list>\r
-                               <ref bean="flow1"/>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-       \r
-       <bean id="flow2" parent="flowTemplate2">\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="testData1">\r
-                                       <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                               <property name="expected" value="tata100" />\r
-                                               <property name="reached" value="tata100" />\r
-                                       </bean>\r
-                               </entry>\r
-                       </map>                  \r
-               </constructor-arg>\r
-       </bean> \r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/tasks/SystemCallTest.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/tasks/SystemCallTest.java
deleted file mode 100644 (file)
index 8301b85..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.core.execution.AbstractExecutionFlowTestCase;
-
-public class SystemCallTest extends AbstractExecutionFlowTestCase {
-       private final static Log log = LogFactory.getLog(SystemCallTest.class);
-
-       private final String defFile = "systemCall.xml";
-
-       public void testSystemCallSimple() throws Exception {
-               if (isOsSupported())
-                       configureAndExecuteSlcFlow(defFile, "systemCallSimple");
-       }
-
-       public void testSystemCallList() throws Exception {
-               if (isOsSupported())
-                       configureAndExecuteSlcFlow(defFile, "systemCallList");
-       }
-
-       public void testSystemCallOsSpecific() throws Exception {
-               if (isOsSupported())
-                       configureAndExecuteSlcFlow(defFile, "systemCallOsSpecific");
-       }
-
-       public void testSystemCallWithVar() throws Exception {
-               if (isOsSupported())
-                       configureAndExecuteSlcFlow(defFile, "systemCallWithVar");
-       }
-
-       protected boolean isOsSupported() {
-               String osName = System.getProperty("os.name");
-               final Boolean ret;
-               if (osName.contains("Windows"))
-                       ret = false;
-               else
-                       ret = true;
-
-               if (ret == false)
-                       log.warn("Skip test because OS '" + osName + "' is not supported.");
-               return ret;
-       }
-}
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/tasks/systemCall.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/tasks/systemCall.xml
deleted file mode 100644 (file)
index 8d35650..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="../imports.xml" />\r
-\r
-       <bean id="systemCallSimple" parent="slcTemplate.simpleFlow">\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.echo">\r
-                                       <property name="message" value="os.name=${os.name}" />\r
-                               </bean>\r
-                               <bean parent="task.systemCall">\r
-                                       <property name="cmd" value="echo Hello World" />\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="systemCallList" parent="slcTemplate.simpleFlow">\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.systemCall">\r
-                                       <property name="command">\r
-                                               <list>\r
-                                                       <value>echo</value>\r
-                                                       <value>Hello</value>\r
-                                                       <value>World</value>\r
-                                               </list>\r
-                                       </property>\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="systemCallOsSpecific" parent="slcTemplate.simpleFlow">\r
-               <!-- Direct call to dir under Windows isnot working -->\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.systemCall">\r
-                                       <property name="cmd" value="dir" />\r
-                                       <property name="execDir" value="../.." />\r
-                                       <property name="osCmds">\r
-                                               <map>\r
-                                                       <entry key="Linux" value="ls" />\r
-                                                       <entry key="Mac OS X" value="ls" />\r
-                                               </map>\r
-                                       </property>\r
-                               </bean>\r
-                               <bean parent="task.systemCall">\r
-                                       <property name="command">\r
-                                               <list>\r
-                                                       <value>dir</value>\r
-                                               </list>\r
-                                       </property>\r
-                                       <property name="osCommands">\r
-                                               <map>\r
-                                                       <entry key="Linux">\r
-                                                               <list>\r
-                                                                       <value>ls</value>\r
-                                                               </list>\r
-                                                       </entry>\r
-                                                       <entry key="Mac OS X">\r
-                                                               <list>\r
-                                                                       <value>ls</value>\r
-                                                               </list>\r
-                                                       </entry>\r
-                                               </map>\r
-                                       </property>\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="systemCallWithVar" parent="slcTemplate.simpleFlow">\r
-               <constructor-arg>\r
-                       <bean parent="slcTemplate.simpleSpec">\r
-                               <property name="attributes">\r
-                                       <map>\r
-                                               <entry key="var">\r
-                                                       <bean parent="specAttr.primitive" p:value="660" />\r
-                                               </entry>\r
-                                       </map>\r
-                               </property>\r
-                       </bean>\r
-               </constructor-arg>\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.systemCall" scope="execution">\r
-                                       <property name="cmd" value="echo var=@{var}" />\r
-                                       <aop:scoped-proxy />\r
-                               </bean>\r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/test.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/test.xml
deleted file mode 100644 (file)
index d8bec3d..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
-       xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
-       <import resource="imports.xml" /> \r
-\r
-       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
-\r
-       <bean id="myTestDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
-\r
-       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
-               <property name="testDefinition" ref="myTestDef" />\r
-               <property name="testResult" ref="myTestResult"/>\r
-       </bean>         \r
\r
-       <bean id="spec1" parent="slcTemplate.simpleSpec">\r
-               <property name="attributes">\r
-                       <map>\r
-                               <entry key="testedComponentId">\r
-                                       <bean parent="specAttr.primitive" p:isParameter="true"\r
-                                               p:type="integer" />\r
-                               </entry>\r
-                               <entry key="testData1">\r
-                                       <bean parent="specAttr.ref" p:targetClass="org.argeo.slc.core.test.BasicTestData"\r
-                                               p:isParameter="true" p:isFrozen="true" />\r
-                               </entry>\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="flowTemplate1" parent="slcTemplate.simpleFlow"\r
-               abstract="true">\r
-               <constructor-arg ref="spec1" />\r
-               <property name="executables">\r
-                       <list>\r
-                               <bean parent="task.echo">\r
-                                       <property name="message" value="From basic @{testedComponentId}" />\r
-                               </bean>\r
-                               <bean parent="myTestRunTemplate">\r
-                                       <property name="testData">\r
-                                               <bean parent="parameterRef">\r
-                                                       <constructor-arg value="testData1" />\r
-                                               </bean>\r
-                                       </property>\r
-                               </bean>\r
-                               <bean parent="task.echo">\r
-                                       <property name="message"><value>From basic @{testedComponentId}</value></property>\r
-                               </bean>         \r
-                               <bean parent="task.echo">\r
-                                       <property name="message"><value>testData1='@{testData1}'</value></property>\r
-                               </bean>                                                 \r
-                       </list>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="flow1" parent="flowTemplate1" scope="prototype">\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="testedComponentId" value="200" />\r
-                               <entry key="testData1">\r
-                                       <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
-                                               <aop:scoped-proxy/>\r
-                                               <property name="expected" value="tata101" />\r
-                                               <property name="reached" value="tata@{testedComponentId}" />\r
-                                       </bean>\r
-                               </entry>\r
-                       </map>                  \r
-               </constructor-arg>\r
-       </bean>\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/FlowNamespaceTest.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/FlowNamespaceTest.java
deleted file mode 100644 (file)
index f673020..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import org.argeo.slc.core.execution.AbstractExecutionFlowTestCase;
-import org.argeo.slc.core.test.SimpleTestResult;
-import org.argeo.slc.execution.ExecutionContext;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.springframework.context.ConfigurableApplicationContext;
-
-public class FlowNamespaceTest extends AbstractExecutionFlowTestCase {
-       public void testCanonical() throws Exception {
-               ConfigurableApplicationContext applicationContext = createApplicationContext("canonic-ns.xml");
-               ((ExecutionFlow) applicationContext.getBean("canonic-ns.001")).run();
-               ((ExecutionFlow) applicationContext.getBean("canonic-ns.002")).run();
-       }
-
-       public void testAdvanced() throws Exception {
-               ConfigurableApplicationContext applicationContext = createApplicationContext("advanced.xml");
-               ((ExecutionFlow) applicationContext.getBean("flow1")).run();
-               ((ExecutionFlow) applicationContext.getBean("flow2")).run();
-               ((ExecutionFlow) applicationContext.getBean("flow3")).run();
-
-               validateTestResult((SimpleTestResult) applicationContext
-                               .getBean("testResult"));
-       }
-
-       public void testAdvancedExecution() throws Exception {
-               ConfigurableApplicationContext applicationContext = createApplicationContext("advanced.xml");
-
-               ExecutionContext executionContext = (ExecutionContext) applicationContext
-                               .getBean("executionContext");
-               executionContext.setVariable("param2", 4);
-
-               ((ExecutionFlow) applicationContext.getBean("flow4")).run();
-
-               validateTestResult((SimpleTestResult) applicationContext
-                               .getBean("testResult"));
-       }
-
-       // These tests causes pb when using Spring 3
-       
-       // public void testContainers() throws Exception {
-       // ConfigurableApplicationContext applicationContext =
-       // createApplicationContext("containers.xml");
-       // ((ExecutionFlow) applicationContext.getBean("test.list.flow1")).run();
-       // ((ExecutionFlow) applicationContext.getBean("test.list.flow2")).run();
-       //
-       // validateTestResult((SimpleTestResult) applicationContext
-       // .getBean("testResult"));
-       // }
-}
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/advanced.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/advanced.xml
deleted file mode 100644 (file)
index 49b6f7e..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
-       xmlns:flow="http://www.argeo.org/schema/slc-flow"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
-       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
-\r
-       <import resource="classpath:org/argeo/slc/core/execution/spring.xml" />\r
-       <import resource="classpath:/org/argeo/slc/core/test/spring.xml" />\r
-\r
-       <bean id="testResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
-\r
-       <bean id="testDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
-\r
-       <bean id="testRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
-               <property name="testDefinition" ref="testDef" />\r
-               <property name="testResult" ref="testResult"/>\r
-       </bean> \r
-\r
-       <flow:spec id="advanced.spec">\r
-               <description>spec description</description>\r
-               <flow:primitive name="param1" isParameter="true"\r
-                       type="integer" />\r
-               <flow:primitive name="param2" isParameter="true"\r
-                       type="integer" />                       \r
-       </flow:spec>\r
-\r
-\r
-       <flow:flow id="advanced.flowTemplate" abstract="true" spec="advanced.spec"\r
-               path="/path">\r
-               <description>flow description</description>\r
-               <bean parent="task.echo">\r
-                       <property name="message" value="Advanced: param1=@{param1}, param2=@{param2}" />\r
-                       <flow:variable/>\r
-               </bean> \r
-               <flow:flow>\r
-                       <bean parent="task.echo" p:message="Flow in Flow - param1=@{param1}, param2=@{param2} [Not variable]" />\r
-               </flow:flow>\r
\r
-               <bean parent="testRunTemplate">\r
-                       <property name="testData">\r
-                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                       <flow:variable/>\r
-                                       <property name="expected" value="@{param1}" />\r
-                                       <property name="reached" value="@{param2}" />\r
-                               </bean>\r
-                       </property>                                     \r
-               </bean>\r
\r
-       </flow:flow>\r
-\r
-       <flow:flow id="advanced.flowTemplate2" abstract="true" spec="advanced.spec"\r
-               path="/path">\r
-               <bean parent="task.echo" p:message="Advanced2: param1=@{param1}, param2=@{param2}">\r
-                       <flow:variable/>\r
-               </bean>\r
-               <flow:flow parent="advanced.flowTemplate">\r
-                       <flow:arg name="param1" value="@{param1}"/>\r
-                       <flow:arg name="param2">\r
-                               <!-- flow:param in flow:arg -->\r
-                               <flow:param name="param2" />\r
-                       </flow:arg>\r
-               </flow:flow>\r
-       </flow:flow>\r
-\r
-       \r
-       <flow:flow id="flow1" parent="advanced.flowTemplate">\r
-               <flow:arg name="param1" value="1" />\r
-               <flow:arg name="param2" value="1" />\r
-       </flow:flow>\r
-       \r
-       <flow:flow id="flow2">\r
-               <flow:flow parent="advanced.flowTemplate">\r
-                       <flow:arg name="param1" value="2" />\r
-                       <flow:arg name="param2" value="2" />\r
-               </flow:flow>\r
-       </flow:flow>\r
-\r
-       <flow:flow id="flow3" parent="advanced.flowTemplate2">\r
-               <flow:arg name="param1" value="3" />\r
-               <flow:arg name="param2" value="3" />\r
-       </flow:flow>\r
-       \r
-       <flow:flow id="flow4" parent="advanced.flowTemplate">\r
-               <description>Would fail if param 2 is not changed at execution</description>\r
-               <flow:arg name="param1" value="4" />\r
-               <flow:arg name="param2" value="3" />\r
-       </flow:flow>    \r
-\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-001.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-001.xml
deleted file mode 100644 (file)
index aeef3a3..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
-       xmlns:flow="http://www.argeo.org/schema/slc-flow"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
-\r
-       <bean id="canonic-ns.001" parent="canonic-ns.flowTemplate">\r
-               <description>Canonic 001</description>\r
-               <constructor-arg>\r
-                       <map>\r
-                               <entry key="parameterAtInstantiation" value="1" />\r
-                       </map>\r
-               </constructor-arg>\r
-       </bean>\r
-</beans>\r
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-002.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-002.xml
deleted file mode 100644 (file)
index ac5f085..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans:beans xmlns="http://www.argeo.org/schema/slc-flow"\r
-       xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:p="http://www.springframework.org/schema/p"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
-\r
-       <flow id="canonic-ns.002" parent="canonic-ns.flowTemplate">\r
-               <arg name="parameterAtInstantiation" value="2" />\r
-               <arg name="displayWithoutControl" value="102" />\r
-               <arg name="displayWithControl" value="202" />\r
-               <arg name="hide" value="202" />\r
-               <arg name="refWithoutValue">\r
-                       <beans:bean id="testDataOk" p:expected="tata" p:reached="tata"\r
-                               class="org.argeo.slc.core.test.BasicTestData" />\r
-               </arg>\r
-       </flow>\r
-</beans:beans>\r
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/canonic-ns.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/canonic-ns.xml
deleted file mode 100644 (file)
index facb277..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans:beans xmlns="http://www.argeo.org/schema/slc-flow"\r
-       xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd\r
-       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
-\r
-       <beans:import resource="classpath:org/argeo/slc/core/execution/spring.xml" />\r
-       <beans:import resource="classpath:/org/argeo/slc/core/test/spring.xml" />\r
-\r
-       <beans:import resource="canonic-ns-001.xml" />\r
-       <beans:import resource="canonic-ns-002.xml" />\r
-       <beans:import resource="tests.xml" />\r
-\r
-       <!--\r
-               Specifications definition is greatly simplified by the flow namespace\r
-       -->\r
-       <spec id="canonic-ns.spec">\r
-               <primitive name="parameterAtInstantiation" isParameter="true"\r
-                       type="integer" />\r
-               <primitive name="displayWithoutControl" value="100"\r
-                       isParameter="true" type="integer" isFrozen="true" />\r
-               <primitive name="displayWithControl" value="200"\r
-                       isParameter="true" type="integer" />\r
-               <primitive name="hide" value="300" isParameter="true" type="integer"\r
-                       isHidden="true" />\r
-               <ref name="refWithValue" targetClass="org.argeo.slc.core.test.BasicTestData"\r
-                       isParameter="true" ref="testDataNok" />\r
-               <ref name="refWithoutValue" targetClass="org.argeo.slc.core.test.BasicTestData" />\r
-               <ref name="refWithoutValueFrozen" targetClass="org.argeo.slc.core.test.BasicTestData"\r
-                       isParameter="true" isFrozen="true">\r
-                       <value>\r
-                               <beans:bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                       <aop:scoped-proxy />\r
-                                       <beans:property name="expected" value="tata" />\r
-                                       <beans:property name="reached" value="tata" />\r
-                               </beans:bean>\r
-                       </value>\r
-               </ref>\r
-       </spec>\r
-\r
-       <flow id="canonic-ns.flowTemplate" abstract="true" spec="canonic-ns.spec"\r
-               path="/path">\r
-               <beans:bean parent="task.echo"\r
-                       p:message="Canonical: displayWithControl=@{displayWithControl}, displayWithoutControl=@{displayWithoutControl}, hide=@{hide}"\r
-                       scope="execution">\r
-                       <aop:scoped-proxy />\r
-               </beans:bean>\r
-               <beans:ref bean="testRun" />\r
-       </flow>\r
-\r
-       <beans:bean id="testDataOk" class="org.argeo.slc.core.test.BasicTestData">\r
-               <aop:scoped-proxy />\r
-               <beans:property name="expected" value="tata" />\r
-               <beans:property name="reached" value="tata" />\r
-       </beans:bean>\r
-\r
-       <beans:bean id="testDataNok" class="org.argeo.slc.core.test.BasicTestData">\r
-               <aop:scoped-proxy />\r
-               <beans:property name="expected" value="tata" />\r
-               <beans:property name="reached" value="toto" />\r
-       </beans:bean>\r
-</beans:beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/containers.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/containers.xml
deleted file mode 100644 (file)
index 61bfa07..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
-       xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd\r
-       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
-\r
-       <import resource="classpath:org/argeo/slc/core/execution/spring.xml" />\r
-       <import resource="classpath:/org/argeo/slc/core/test/spring.xml" />\r
-\r
-       <bean id="testResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
-\r
-       <bean id="testDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
-\r
-       <bean id="testRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
-               <property name="testDefinition" ref="testDef" />\r
-               <property name="testResult" ref="testResult"/>\r
-       </bean> \r
-\r
-       <flow:spec id="test.list.spec">\r
-               <flow:ref name="list1" targetClass="java.util.List">\r
-                       <flow:value>\r
-                               <!-- a list element can be used directly as default value-->\r
-                               <list>\r
-                                       <value>val1</value>\r
-                               </list>\r
-                       </flow:value>\r
-               </flow:ref>\r
-               <flow:ref name="list2" targetClass="java.util.List" />\r
-               <!-- following parameters are not used in flow -->\r
-               <flow:ref name="dummyMap" targetClass="java.util.Map">\r
-                       <flow:value>\r
-                               <map></map>\r
-                       </flow:value>\r
-               </flow:ref>\r
-               <flow:ref name="dummySet" targetClass="java.util.Set">\r
-                       <flow:value>\r
-                               <set></set>\r
-                       </flow:value>\r
-               </flow:ref>\r
-               <flow:ref name="dummyProperties" targetClass="java.util.Properties">\r
-                       <flow:value>\r
-                               <props></props>\r
-                       </flow:value>\r
-               </flow:ref>\r
-               \r
-       </flow:spec>\r
-\r
-\r
-       <flow:flow id="test.list.flowTemplate" abstract="true" spec="test.list.spec"\r
-               path="/path">\r
-               <bean parent="task.echo">\r
-                       <property name="message" value="list1=@{list1}, list2=@{list2}" />\r
-                       <flow:variable/>\r
-               </bean> \r
-\r
-               <bean parent="testRunTemplate">\r
-                       <property name="testData">\r
-                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
-                                       <property name="expected">\r
-                                               <flow:param name="list1"/>\r
-                                       </property>\r
-                                       <property name="reached">\r
-                                               <flow:param name="list2"/>\r
-                                       </property>\r
-                               </bean>\r
-                       </property>                                     \r
-               </bean>\r
\r
-       </flow:flow>\r
-\r
-       <flow:flow id="test.list.flow1" parent="test.list.flowTemplate">\r
-               <flow:arg name="list1">\r
-                       <list>\r
-                               <value>val1</value>\r
-                               <value>val2</value>                     \r
-                       </list>\r
-               </flow:arg>\r
-               <flow:arg name="list2">\r
-                       <list>\r
-                               <value>val1</value>\r
-                               <value>val2</value>                     \r
-                       </list>\r
-               </flow:arg>\r
-               \r
-               <!-- not used in flow (just to test that the syntax is accepted): -->\r
-               <flow:arg name="dummyMap">\r
-                       <map></map>\r
-               </flow:arg>\r
-               <flow:arg name="dummySet">\r
-                       <set></set>\r
-               </flow:arg>\r
-               <flow:arg name="dummyProperties">\r
-                       <props></props>\r
-               </flow:arg>             \r
-               \r
-       </flow:flow>\r
-       \r
-       <flow:flow id="test.list.flow2" parent="test.list.flowTemplate">\r
-               <description>use default value for parameter "list1"</description>\r
-               <flow:arg name="list2">\r
-                       <list>\r
-                               <value>val1</value>\r
-                       </list>\r
-               </flow:arg>\r
-       </flow:flow>\r
-\r
-\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/tests.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/xml/tests.xml
deleted file mode 100644 (file)
index ee58a18..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:flow="http://www.argeo.org/schema/slc-flow"\r
-       xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"\r
-       xsi:schemaLocation="\r
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd\r
-       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
-\r
-       <bean id="testRun" class="org.argeo.slc.core.test.SimpleTestRun">\r
-               <property name="testDefinition">\r
-                       <bean class="org.argeo.slc.core.test.BasicTestDefinition" />\r
-               </property>\r
-               <property name="testData">\r
-                       <flow:param name="refWithValue" />\r
-               </property>\r
-               <!--            <property name="testData">-->\r
-               <!--                    <bean parent="parameterRef">-->\r
-               <!--                            <constructor-arg value="refWithValue" />-->\r
-               <!--                    </bean>-->\r
-               <!--            </property>-->\r
-               <property name="testResult">\r
-                       <bean parent="slcDefault.test.basicSimpleTestResult" scope="execution">\r
-                               <property name="attributes">\r
-                                       <map>\r
-                                               <entry key="displayWithControl" value="@{displayWithControl}" />\r
-                                       </map>\r
-                               </property>\r
-                               <aop:scoped-proxy />\r
-                       </bean>\r
-               </property>\r
-       </bean>\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/test/context/AbstractInternalSpringTestCase.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/test/context/AbstractInternalSpringTestCase.java
deleted file mode 100644 (file)
index 61eb3b2..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import java.util.Map;\r
-\r
-import junit.framework.TestCase;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.springframework.beans.factory.BeanFactoryUtils;\r
-import org.springframework.beans.factory.ListableBeanFactory;\r
-import org.springframework.context.ConfigurableApplicationContext;\r
-import org.springframework.context.support.ClassPathXmlApplicationContext;\r
-\r
-/** Helper for tests using a Spring application context. */\r
-public abstract class AbstractInternalSpringTestCase extends TestCase {\r
-       protected final Log log = LogFactory.getLog(getClass());\r
-       private ConfigurableApplicationContext context;\r
-\r
-       /**\r
-        * Gets (and create if necessary) the application context to use. Default\r
-        * implementation uses a class path xml application context and calls\r
-        * {@link #getApplicationContextLocation()}.\r
-        */\r
-       protected ConfigurableApplicationContext getContext() {\r
-               if (context == null) {\r
-                       context = new ClassPathXmlApplicationContext(\r
-                                       getApplicationContextLocation());\r
-               }\r
-               return context;\r
-       }\r
-\r
-       /** Returns a bean from the underlying context */\r
-       @SuppressWarnings(value = { "unchecked" })\r
-       protected <T> T getBean(String beanId) {\r
-               return (T) getContext().getBean(beanId);\r
-       }\r
-\r
-       protected <T> T getBean(Class<? extends T> clss) {\r
-               T bean = loadSingleFromContext(getContext(), clss);\r
-               if (bean == null) {\r
-                       throw new SlcException("Cannot retrieve a unique bean of type "\r
-                                       + clss);\r
-               } else {\r
-                       return bean;\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Th location of the application to load. The default implementation\r
-        * returns <i>applicationContext.xml</i> found in the same package as the\r
-        * test.\r
-        */\r
-       protected String getApplicationContextLocation() {\r
-               return inPackage("applicationContext.xml");\r
-       }\r
-\r
-       /**\r
-        * Prefixes the package of the class after converting the '.' to '/' in\r
-        * order to have a resource path.\r
-        */\r
-       protected String inPackage(String suffix) {\r
-               String prefix = getClass().getPackage().getName().replace('.', '/');\r
-               return prefix + '/' + suffix;\r
-       }\r
-\r
-       @SuppressWarnings(value = { "unchecked" })\r
-       protected <T> T loadSingleFromContext(ListableBeanFactory context,\r
-                       Class<T> clss) {\r
-               Map<String, T> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(\r
-                               context, clss, false, false);\r
-               if (beans.size() == 1) {\r
-                       return beans.values().iterator().next();\r
-               } else if (beans.size() > 1) {\r
-                       if (log.isDebugEnabled()) {\r
-                               log\r
-                                               .debug(("Found more that on bean for type " + clss\r
-                                                               + ": " + beans.keySet()));\r
-                       }\r
-                       return null;\r
-               } else {\r
-                       return null;\r
-               }\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/test/context/ContextTest.java b/org.argeo.slc.core/ext/test/org/argeo/slc/core/test/context/ContextTest.java
deleted file mode 100644 (file)
index 694851c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import java.util.List;\r
-\r
-import org.argeo.slc.core.test.SimpleTestResult;\r
-import org.argeo.slc.test.TestResultPart;\r
-import org.argeo.slc.test.TestStatus;\r
-import org.argeo.slc.test.context.ContextAware;\r
-\r
-public class ContextTest extends AbstractInternalSpringTestCase {\r
-\r
-       public void testComplexContext() {\r
-               SimpleTestResult testResult = new SimpleTestResult();\r
-               ContextUtils.compareReachedExpected(\r
-                               (ContextAware) getBean("context.c1"), testResult);\r
-               ContextUtils.compareReachedExpected(\r
-                               (ContextAware) getBean("context.c2"), testResult);\r
-               ContextUtils.compareReachedExpected(\r
-                               (ContextAware) getBean("context.c3"), testResult);\r
-\r
-               List<TestResultPart> parts = testResult.getParts();\r
-               assertEquals(6, parts.size());\r
-               assertEquals(TestStatus.PASSED, parts.get(0).getStatus());\r
-               assertEquals(TestStatus.PASSED, parts.get(1).getStatus());\r
-               assertEquals(TestStatus.PASSED, parts.get(2).getStatus());\r
-               assertEquals(TestStatus.FAILED, parts.get(3).getStatus());\r
-               assertEquals(TestStatus.PASSED, parts.get(4).getStatus());\r
-               assertEquals(TestStatus.PASSED, parts.get(5).getStatus());\r
-       }\r
-}\r
diff --git a/org.argeo.slc.core/ext/test/org/argeo/slc/core/test/context/applicationContext.xml b/org.argeo.slc.core/ext/test/org/argeo/slc/core/test/context/applicationContext.xml
deleted file mode 100644 (file)
index 4949c4e..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
-    Copyright (C) 2007-2012 Argeo GmbH\r
-\r
-    Licensed under the Apache License, Version 2.0 (the "License");\r
-    you may not use this file except in compliance with the License.\r
-    You may obtain a copy of the License at\r
-\r
-            http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-    Unless required by applicable law or agreed to in writing, software\r
-    distributed under the License is distributed on an "AS IS" BASIS,\r
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-    See the License for the specific language governing permissions and\r
-    limitations under the License.\r
-\r
--->\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
-\r
-       <bean id="parentContext.pc1" parent="parentContext.template">\r
-               <property name="values">\r
-                       <map>\r
-                               <entry key="rootvar" value="text" />\r
-                       </map>\r
-               </property>\r
-               <property name="expectedValues">\r
-                       <map>\r
-                               <entry key="reference" value="20" />\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="context.c1" parent="context.template">\r
-               <property name="parentContext" ref="parentContext.pc1" />\r
-               <property name="values">\r
-                       <map>\r
-                               <entry key="reference" value="20" />\r
-                               <entry key="any" value="999" />\r
-                               <entry key="skipped" value="999" />\r
-                       </map>\r
-               </property>\r
-               <property name="expectedValues">\r
-                       <map>\r
-                               <entry key="reference" value="21" />\r
-                               <entry key="any" value="*" />\r
-                               <entry key="skipped" value="!" />\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="context.c2" parent="context.template">\r
-               <property name="parentContext" ref="parentContext.pc1" />\r
-               <property name="values">\r
-                       <map>\r
-                               <entry key="var" value="37" />\r
-                               <entry key="bad" value="56" />\r
-                       </map>\r
-               </property>\r
-               <property name="expectedValues">\r
-                       <map>\r
-                               <entry key="var" value="37" />\r
-                               <entry key="bad" value="57" />\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="parentContext.pc2" parent="parentContext.template">\r
-               <property name="parentContext" ref="parentContext.pc1" />\r
-               <property name="expectedValues">\r
-                       <map>\r
-                               <entry key="reference" value="40" />\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-       <bean id="context.c3" parent="context.template">\r
-               <property name="parentContext" ref="parentContext.pc2" />\r
-               <property name="values">\r
-                       <map>\r
-                               <entry key="reference" value="41" />\r
-                               <entry key="rootvar" value="textX" />\r
-                       </map>\r
-               </property>\r
-               <property name="expectedValues">\r
-                       <map>\r
-                               <entry key="reference" value="40" />\r
-                               <entry key="rootvar" value="text" />\r
-                       </map>\r
-               </property>\r
-       </bean>\r
-\r
-\r
-       <bean id="parentContext.template"\r
-               class="org.argeo.slc.core.test.context.SimpleParentContextAware"\r
-               abstract="true">\r
-       </bean>\r
-\r
-       <bean id="context.template"\r
-               class="org.argeo.slc.core.test.context.SimpleContextAware"\r
-               abstract="true">\r
-       </bean>\r
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/pom.xml b/org.argeo.slc.core/pom.xml
deleted file mode 100644 (file)
index 982f0e6..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-       <modelVersion>4.0.0</modelVersion>
-       <parent>
-               <groupId>org.argeo.slc</groupId>
-               <artifactId>argeo-slc</artifactId>
-               <version>2.1.17-SNAPSHOT</version>
-               <relativePath>..</relativePath>
-       </parent>
-       <artifactId>org.argeo.slc.core</artifactId>
-       <name>SLC Runtime</name>
-       <build>
-               <plugins>
-                       <plugin>
-                               <groupId>org.apache.maven.plugins</groupId>
-                               <artifactId>maven-surefire-plugin</artifactId>
-                               <configuration>
-                                       <skipTests>true</skipTests>
-                               </configuration>
-                       </plugin>
-               </plugins>
-       </build>
-       <dependencies>
-               <!-- Commons -->
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.enterprise</artifactId>
-                       <version>${version.argeo-commons}</version>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.node.api</artifactId>
-                       <version>${version.argeo-commons}</version>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.cms</artifactId>
-                       <version>${version.argeo-commons}</version>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.jcr</artifactId>
-                       <version>${version.argeo-commons}</version>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.util</artifactId>
-                       <version>${version.argeo-commons}</version>
-               </dependency>
-
-               <!-- SLC -->
-               <dependency>
-                       <groupId>org.argeo.slc</groupId>
-                       <artifactId>org.argeo.slc.api</artifactId>
-                       <version>2.1.17-SNAPSHOT</version>
-               </dependency>
-
-               <!-- Spring -->
-               <dependency>
-                       <groupId>org.argeo.tp.spring</groupId>
-                       <artifactId>org.springframework.beans</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp.spring</groupId>
-                       <artifactId>org.springframework.core</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp.spring</groupId>
-                       <artifactId>org.springframework.context</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp.spring</groupId>
-                       <artifactId>org.springframework.aop</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp.gemini</groupId>
-                       <artifactId>org.eclipse.gemini.blueprint.core</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp.gemini</groupId>
-                       <artifactId>org.eclipse.gemini.blueprint.io</artifactId>
-               </dependency>
-
-               <!-- Ant -->
-               <dependency>
-                       <groupId>org.argeo.tp.apache.ant</groupId>
-                       <artifactId>org.apache.ant</artifactId>
-               </dependency>
-
-       </dependencies>
-</project>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/ant/AntFlowGenerator.java b/org.argeo.slc.core/src/org/argeo/slc/ant/AntFlowGenerator.java
deleted file mode 100644 (file)
index 9dea43e..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.ant;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.argeo.slc.core.execution.AbstractExecutionFlowGenerator;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.core.io.Resource;
-
-public class AntFlowGenerator extends AbstractExecutionFlowGenerator {
-       private List<Resource> antFiles = new ArrayList<Resource>();
-
-       protected Map<String, BeanDefinition> createExecutionFlowDefinitions(
-                       ConfigurableListableBeanFactory beanFactory) {
-               Map<String, BeanDefinition> definitions = new HashMap<String, BeanDefinition>();
-
-               for (Resource antFile : antFiles) {
-                       AntRun antRun = new AntRun();
-                       antRun.setBuildFile(antFile);
-
-                       List<Runnable> executables = new ArrayList<Runnable>();
-                       executables.add(antRun);
-                       definitions.put("ant." + antFile.getFilename(),
-                                       createDefaultFlowDefinition(executables));
-               }
-               return definitions;
-       }
-
-       public void setAntFiles(List<Resource> antFiles) {
-               this.antFiles = antFiles;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/ant/AntRun.java b/org.argeo.slc.core/src/org/argeo/slc/ant/AntRun.java
deleted file mode 100644 (file)
index 1e2dcb9..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.ant;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.tools.ant.BuildEvent;
-import org.apache.tools.ant.BuildListener;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.ProjectHelper;
-import org.apache.tools.ant.helper.ProjectHelper2;
-import org.argeo.slc.SlcException;
-import org.springframework.core.io.Resource;
-
-public class AntRun implements Runnable {
-       private final static Log log = LogFactory.getLog(AntRun.class);
-
-       private Resource buildFile;
-       private File baseDir;
-
-       private List<String> targets = new ArrayList<String>();
-       private Map<Object, Object> properties = new HashMap<Object, Object>();
-
-       public void run() {
-               Project project = new Project();
-
-               try {
-                       String path = buildFile.getURL().getPath();
-                       project.setUserProperty("ant.file", path);
-                       project.setBaseDir(extractBaseDir(path));
-
-                       project.init();
-                       ProjectHelper projectHelper = new ProjectHelper2();
-                       project.addReference(ProjectHelper.PROJECTHELPER_REFERENCE,
-                                       projectHelper);
-                       projectHelper.parse(project, buildFile.getURL());
-               } catch (Exception e) {
-                       throw new SlcException("Could not parse " + buildFile, e);
-               }
-
-               if (properties != null) {
-                       for (Map.Entry<Object, Object> entry : properties.entrySet()) {
-                               project.setUserProperty(entry.getKey().toString(), entry
-                                               .getValue().toString());
-                       }
-               }
-
-               project.fireBuildStarted();
-               Throwable exception = null;
-               try {
-                       project.addBuildListener(new LoggingListener());
-                       if (targets.size() == 0) {
-                               project.executeTarget(project.getDefaultTarget());
-                       } else {
-                               project.executeTargets(new Vector<String>(targets));
-                       }
-               } catch (Throwable e) {
-                       exception = e;
-                       throw new SlcException("Could not run Ant script " + buildFile, e);
-               } finally {
-                       project.fireBuildFinished(exception);
-               }
-       }
-
-       private File extractBaseDir(String path) {
-               if(this.baseDir!=null)
-                       return this.baseDir;
-               
-               String baseDir = null;
-               if (path.length() > 1) {
-                       int indx = path.lastIndexOf('/', path.length() - 1);
-                       if (indx == -1 || indx == 0) {
-                               baseDir = "/";
-                       } else {
-                               baseDir = path.substring(0, indx) + "/";
-                       }
-               } else {
-                       baseDir = "/";
-               }
-               File file = new File(baseDir);
-               if (file.exists()) {
-                       return file;
-               } else {
-                       return new File(System.getProperty("user.dir"));
-               }
-       }
-
-       public void setBuildFile(Resource buildFile) {
-               this.buildFile = buildFile;
-       }
-
-       public void setTargets(List<String> targets) {
-               this.targets = targets;
-       }
-
-       public void setProperties(Map<Object, Object> properties) {
-               this.properties = properties;
-       }
-
-       public void setBaseDir(File baseDir) {
-               this.baseDir = baseDir;
-       }
-
-       protected static class LoggingListener implements BuildListener {
-
-               public void buildFinished(BuildEvent event) {
-                       if (log.isDebugEnabled())
-                               log.debug("Ant build finished: " + event);
-               }
-
-               public void buildStarted(BuildEvent event) {
-                       if (log.isDebugEnabled())
-                               log.debug("Ant build started: " + event);
-               }
-
-               public void messageLogged(BuildEvent event) {
-                       if (event.getPriority() == Project.MSG_DEBUG) {
-                               if (log.isTraceEnabled())
-                                       log.trace(event.getMessage());
-                       } else if (event.getPriority() == Project.MSG_VERBOSE) {
-                               if (log.isDebugEnabled())
-                                       log.debug(event.getMessage());
-                       } else if (event.getPriority() == Project.MSG_INFO) {
-                               log.info(event.getMessage());
-
-                       } else if (event.getPriority() == Project.MSG_WARN) {
-                               log.warn(event.getMessage());
-
-                       } else if (event.getPriority() == Project.MSG_ERR) {
-                               log.error(event.getMessage());
-                       } else {
-                               log.error(event.getMessage());
-                       }
-               }
-
-               public void targetFinished(BuildEvent event) {
-                       if (log.isTraceEnabled())
-                               log.debug("Target finished: " + event.getTarget());
-               }
-
-               public void targetStarted(BuildEvent event) {
-                       if (log.isTraceEnabled())
-                               log.debug("Target started: " + event.getTarget());
-               }
-
-               public void taskFinished(BuildEvent event) {
-               }
-
-               public void taskStarted(BuildEvent event) {
-               }
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/attachment/Attachment.java b/org.argeo.slc.core/src/org/argeo/slc/core/attachment/Attachment.java
deleted file mode 100644 (file)
index ecde0b9..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-public interface Attachment {
-       public String getUuid();
-
-       public void setUuid(String uuid);
-
-       public String getName();
-
-       public String getContentType();
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/attachment/AttachmentUploader.java b/org.argeo.slc.core/src/org/argeo/slc/core/attachment/AttachmentUploader.java
deleted file mode 100644 (file)
index eb484c9..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-import org.springframework.core.io.Resource;
-
-public interface AttachmentUploader {
-       public void upload(Attachment attachment, Resource resource);
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/attachment/AttachmentsEnabled.java b/org.argeo.slc.core/src/org/argeo/slc/core/attachment/AttachmentsEnabled.java
deleted file mode 100644 (file)
index 780a6a4..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-public interface AttachmentsEnabled {
-       public void addAttachment(Attachment attachment);
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/attachment/AttachmentsStorage.java b/org.argeo.slc.core/src/org/argeo/slc/core/attachment/AttachmentsStorage.java
deleted file mode 100644 (file)
index 2214afa..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-
-public interface AttachmentsStorage {
-       public void retrieveAttachment(Attachment attachment,
-                       OutputStream outputStream);
-
-       /** Does NOT close the provided input stream. */
-       public void storeAttachment(Attachment attachment, InputStream inputStream);
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/attachment/FileAttachmentsStorage.java b/org.argeo.slc.core/src/org/argeo/slc/core/attachment/FileAttachmentsStorage.java
deleted file mode 100644 (file)
index 3b7e62d..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.core.io.Resource;
-
-public class FileAttachmentsStorage implements AttachmentsStorage,
-               AttachmentUploader, InitializingBean {
-       private final static Log log = LogFactory
-                       .getLog(FileAttachmentsStorage.class);
-
-       private File attachmentsDirectory;
-
-       private String attachmentsTocFileName = "attachmentsToc.csv";
-
-       private DateFormat dateFormatDay = new SimpleDateFormat("yyyy-MM-dd");
-       private DateFormat dateFormatTime = new SimpleDateFormat("HH:mm:ss");
-
-       public void afterPropertiesSet() {
-               if (attachmentsDirectory == null) {
-
-                       String osgiInstanceArea = System.getProperty("osgi.instance.area");
-                       if (osgiInstanceArea != null) {
-                               if (osgiInstanceArea.startsWith("file:"))
-                                       osgiInstanceArea = osgiInstanceArea.substring("file:"
-                                                       .length());
-                               attachmentsDirectory = new File(osgiInstanceArea
-                                               + File.separator + "slcAttachments");
-                       }
-
-                       if (attachmentsDirectory == null) {
-                               String tempDir = System.getProperty("java.io.tmpdir");
-                               attachmentsDirectory = new File(tempDir + File.separator
-                                               + "slcAttachments");
-                       }
-               }
-               if (!attachmentsDirectory.exists())
-                       attachmentsDirectory.mkdirs();
-               if (log.isDebugEnabled())
-                       log.debug("File attachment storage initialized in directory "
-                                       + attachmentsDirectory);
-       }
-
-       public void retrieveAttachment(Attachment attachment,
-                       OutputStream outputStream) {
-               File file = getFile(attachment);
-               InputStream in = null;
-               try {
-                       byte[] buffer = new byte[1024 * 1024];
-                       in = new FileInputStream(file);
-                       int read = -1;
-                       while ((read = in.read(buffer)) >= 0) {
-                               outputStream.write(buffer, 0, read);
-                       }
-                       if (log.isTraceEnabled())
-                               log.trace("Read " + attachment + " from " + file);
-               } catch (IOException e) {
-                       throw new SlcException("Cannot write attachment " + attachment
-                                       + " to " + file, e);
-               } finally {
-                       IOUtils.closeQuietly(in);
-               }
-       }
-
-       public void storeAttachment(Attachment attachment, InputStream inputStream) {
-               File file = getFile(attachment);
-               FileOutputStream out = null;
-               try {
-                       byte[] buffer = new byte[1024 * 1024];
-                       out = new FileOutputStream(file);
-                       int read = -1;
-                       while ((read = inputStream.read(buffer)) >= 0) {
-                               out.write(buffer, 0, read);
-                       }
-                       if (log.isTraceEnabled())
-                               log.trace("Wrote " + attachment + " to " + file);
-                       updateAttachmentToc(attachment, file);
-               } catch (IOException e) {
-                       throw new SlcException("Cannot write attachment " + attachment
-                                       + " to " + file, e);
-               } finally {
-                       IOUtils.closeQuietly(out);
-               }
-
-       }
-
-       public void upload(Attachment attachment, Resource resource) {
-               try {
-                       storeAttachment(attachment, resource.getInputStream());
-               } catch (IOException e) {
-                       throw new SlcException("Cannot upload attachment " + attachment, e);
-               }
-       }
-
-       /** For monitoring purposes only */
-       protected void updateAttachmentToc(Attachment attachment, File file) {
-               Date date = new Date(file.lastModified());
-               FileWriter writer = null;
-               try {
-                       writer = new FileWriter(attachmentsDirectory + File.separator
-                                       + attachmentsTocFileName, true);
-                       writer.append(dateFormatDay.format(date));
-                       writer.append(',');
-                       writer.append(dateFormatTime.format(date));
-                       writer.append(',');
-                       writer.append(attachment.getUuid());
-                       writer.append(',');
-                       writer.append(attachment.getName());
-                       writer.append(',');
-                       writer.append(attachment.getContentType());
-                       writer.append(',');
-                       writer.append(Long.toString(file.length()));
-                       writer.append(',');
-                       writer.append(file.getCanonicalPath());
-                       writer.append('\n');
-               } catch (IOException e) {
-                       log.warn("Could not update attachments TOC for " + attachment
-                                       + " and file " + file, e);
-               } finally {
-                       IOUtils.closeQuietly(writer);
-               }
-
-       }
-
-       protected File getFile(Attachment attachment) {
-               File file = new File(attachmentsDirectory + File.separator
-                               + attachment.getUuid());
-               return file;
-       }
-
-       public void setAttachmentsDirectory(File attachmentsDirectory) {
-               this.attachmentsDirectory = attachmentsDirectory;
-       }
-
-       public void setAttachmentsTocFileName(String attachmentsTocFileName) {
-               this.attachmentsTocFileName = attachmentsTocFileName;
-       }
-
-       public void setDateFormatDay(DateFormat dateFormatDay) {
-               this.dateFormatDay = dateFormatDay;
-       }
-
-       public void setDateFormatTime(DateFormat dateFormatTime) {
-               this.dateFormatTime = dateFormatTime;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/attachment/SimpleAttachment.java b/org.argeo.slc.core/src/org/argeo/slc/core/attachment/SimpleAttachment.java
deleted file mode 100644 (file)
index 6248dd7..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-import java.io.Serializable;
-import java.util.UUID;
-
-public class SimpleAttachment implements Attachment, Serializable {
-       private static final long serialVersionUID = 6615155908800610606L;
-       private String uuid = UUID.randomUUID().toString();
-       private String name;
-       private String contentType = "";
-
-       public SimpleAttachment() {
-       }
-
-       public SimpleAttachment(String uuid, String name, String contentType) {
-               super();
-               this.uuid = uuid;
-               this.name = name;
-               this.contentType = contentType;
-       }
-
-       public String getUuid() {
-               return uuid;
-       }
-
-       public void setUuid(String uuid) {
-               this.uuid = uuid;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       public String getContentType() {
-               return contentType;
-       }
-
-       public void setContentType(String contentType) {
-               this.contentType = contentType;
-       }
-
-       public String toString() {
-               return "Attachment #" + uuid + "(" + name + ", " + contentType + ")";
-       }
-
-       public boolean equals(Object obj) {
-               if (obj instanceof Attachment) {
-                       Attachment attachment = (Attachment) obj;
-                       if (uuid != null && attachment.getUuid() != null)
-                               return uuid.equals(attachment.getUuid());
-
-                       if (name != null && attachment.getName() != null)
-                               return name.equals(attachment.getName());
-
-                       return hashCode() == attachment.hashCode();
-               }
-               return false;
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/build/ResourceDistribution.java b/org.argeo.slc.core/src/org/argeo/slc/core/build/ResourceDistribution.java
deleted file mode 100644 (file)
index 4ebbe92..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.build;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.argeo.slc.SlcException;
-import org.argeo.slc.StreamReadable;
-import org.argeo.slc.build.Distribution;
-import org.springframework.core.io.Resource;
-
-/** A software distribution archive accessible via a {@link Resource}. */
-public class ResourceDistribution implements Distribution, StreamReadable {
-       private Resource resource;
-
-       public ResourceDistribution() {
-       }
-
-       public ResourceDistribution(Resource location) {
-               this.resource = location;
-       }
-
-       public String getDistributionId() {
-               return resource.toString();
-       }
-
-       public Resource getResource() {
-               return resource;
-       }
-
-       public void setResource(Resource resource) {
-               this.resource = resource;
-       }
-
-       public InputStream getInputStream() {
-               try {
-                       return resource.getInputStream();
-               } catch (IOException e) {
-                       throw new SlcException("Cannot get input stream", e);
-               }
-       }
-
-       @Override
-       public String toString() {
-               return resource.toString();
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/build/VersionDistributionId.java b/org.argeo.slc.core/src/org/argeo/slc/core/build/VersionDistributionId.java
deleted file mode 100644 (file)
index c11dc00..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.build;\r
-\r
-import java.util.StringTokenizer;\r
-\r
-/**\r
- * <p>\r
- * An implementation of the distribution id using the standard\r
- * Major.Minor.Release notation. And additional arbitrary string can also be\r
- * added.\r
- * </p>\r
- * \r
- * <p>\r
- * <b>Examples:</b><br>\r
- * 0.2.6<br>\r
- * 2.4.12.RC1\r
- * </p>\r
- */\r
-public class VersionDistributionId {\r
-\r
-       private Integer major;\r
-       private Integer minor;\r
-       private Integer release;\r
-       private String additional;\r
-\r
-       /** Parse the provided string in order to set the various components. */\r
-       public void setVersionString(String str) {\r
-               StringTokenizer st = new StringTokenizer(str, ".");\r
-               if (st.hasMoreTokens())\r
-                       major = Integer.parseInt(st.nextToken());\r
-               if (st.hasMoreTokens())\r
-                       minor = Integer.parseInt(st.nextToken());\r
-               if (st.hasMoreTokens())\r
-                       release = Integer.parseInt(st.nextToken());\r
-               if (st.hasMoreTokens())\r
-                       additional = st.nextToken();\r
-       }\r
-\r
-       public Integer getMajor() {\r
-               return major;\r
-       }\r
-\r
-       public void setMajor(Integer major) {\r
-               this.major = major;\r
-       }\r
-\r
-       public Integer getMinor() {\r
-               return minor;\r
-       }\r
-\r
-       public void setMinor(Integer minor) {\r
-               this.minor = minor;\r
-       }\r
-\r
-       public Integer getRelease() {\r
-               return release;\r
-       }\r
-\r
-       public void setRelease(Integer release) {\r
-               this.release = release;\r
-       }\r
-\r
-       public String getAdditional() {\r
-               return additional;\r
-       }\r
-\r
-       public void setAdditional(String additional) {\r
-               this.additional = additional;\r
-       }\r
-\r
-       @Override\r
-       public boolean equals(Object obj) {\r
-               // TODO Auto-generated method stub\r
-               return super.equals(obj);\r
-       }\r
-\r
-       @Override\r
-       public String toString() {\r
-               return major + "." + minor + "." + release\r
-                               + (additional != null ? "." + additional : "");\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/build/VersionedResourceDistribution.java b/org.argeo.slc.core/src/org/argeo/slc/core/build/VersionedResourceDistribution.java
deleted file mode 100644 (file)
index 52307ec..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.build;
-
-import org.argeo.slc.NameVersion;
-import org.springframework.core.io.Resource;
-
-/**
- * The distribution of a software package (jar, zip, RPM, etc.) which is
- * versioned. The archive itself is accessible via a {@link Resource}.
- */
-public class VersionedResourceDistribution extends ResourceDistribution
-               implements NameVersion {
-       private String name;
-       private String version;
-
-       public VersionedResourceDistribution() {
-               super();
-       }
-
-       public VersionedResourceDistribution(NameVersion nameVersion,
-                       Resource resource) {
-               this(nameVersion.getName(), nameVersion.getVersion(), resource);
-       }
-
-       public VersionedResourceDistribution(String name, String version,
-                       Resource resource) {
-               super(resource);
-               this.name = name;
-               this.version = version;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       public String getVersion() {
-               return version;
-       }
-
-       public void setVersion(String version) {
-               this.version = version;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/build/package.html b/org.argeo.slc.core/src/org/argeo/slc/core/build/package.html
deleted file mode 100644 (file)
index 5da2052..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<html>\r
-<head></head>\r
-<body>\r
-SLC Build: building of software systems.\r
-</body>\r
-</html>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/deploy/DefaultResourceSet.java b/org.argeo.slc.core/src/org/argeo/slc/core/deploy/DefaultResourceSet.java
deleted file mode 100644 (file)
index abdcfee..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.context.ResourceLoaderAware;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.ResourceLoader;
-import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
-import org.springframework.core.io.support.ResourcePatternResolver;
-import org.springframework.util.AntPathMatcher;
-import org.springframework.util.PathMatcher;
-
-public class DefaultResourceSet implements ResourceLoaderAware,
-               InitializingBean, ResourceSet {
-       private final static Log log = LogFactory.getLog(DefaultResourceSet.class);
-       public final static String DEFAULT_EXCLUDES = "**/.svn/**";
-
-       private String base;
-       private String include;
-       private List<String> includes = new ArrayList<String>();
-       private String exclude;
-       private List<String> excludes = new ArrayList<String>();
-       private Boolean useDefaultExcludes = true;
-       private ResourcePatternResolver resourcePatternResolver;
-       private PathMatcher excludePathMatcher = new AntPathMatcher();
-
-       private ResourceLoader resourceLoader;
-
-       /** List the resources, identified by their relative path. */
-       public Map<String, Resource> listResources() {
-               try {
-                       Map<String, Resource> res = new TreeMap<String, Resource>();
-                       if (base == null)
-                               return res;
-                       String baseResUrl = getResourceLoaderToUse().getResource(base)
-                                       .getURL().toString();
-                       for (String includePattern : includes)
-                               processInclude(res, includePattern, baseResUrl);
-                       return res;
-               } catch (IOException e) {
-                       throw new SlcException("Cannot list resource from " + base, e);
-               }
-       }
-
-       protected void processInclude(Map<String, Resource> res, String include,
-                       String baseResUrl) throws IOException {
-               String pattern = base + "/" + include;
-               if (log.isTraceEnabled())
-                       log.trace("Look for resources with pattern '" + pattern
-                                       + "' in base url " + baseResUrl);
-               Resource[] resources = resourcePatternResolver.getResources(pattern);
-               resources: for (Resource resource : resources) {
-                       String url = resource.getURL().toString();
-                       String relPath = url.substring(baseResUrl.length());
-
-                       // skip dir
-                       if (relPath.charAt(relPath.length() - 1) == '/') {
-                               if (log.isTraceEnabled())
-                                       log.trace("Skip directory " + relPath + "=" + resource);
-                               continue resources;
-                       }
-
-                       // make sure there is not starting '/'
-                       if (relPath.charAt(0) == '/')
-                               relPath = relPath.substring(1);
-
-                       // skip excludes
-                       for (String exclude : excludes)
-                               if (excludePathMatcher.match(exclude, relPath)) {
-                                       if (log.isTraceEnabled())
-                                               log.trace("Exclude " + relPath + "=" + resource);
-                                       continue resources;
-                               }
-
-                       // check if already exists
-                       if (res.containsKey(relPath))
-                               log.warn(relPath + " already matched by " + res.get(relPath)
-                                               + ", " + resource + " will override it.");
-
-                       // store the marched resource
-                       res.put(relPath, resource);
-                       if (log.isTraceEnabled())
-                               log.trace(relPath + "=" + resource);
-               }
-
-       }
-
-       public void afterPropertiesSet() throws Exception {
-               if (resourcePatternResolver == null)
-                       resourcePatternResolver = new PathMatchingResourcePatternResolver(
-                                       getResourceLoaderToUse());
-               if (include != null)
-                       addCommaSeparatedToList(include, includes);
-               if (exclude != null)
-                       addCommaSeparatedToList(exclude, excludes);
-
-               if (includes.size() == 0)
-                       includes.add("**");
-
-               if (useDefaultExcludes)
-                       addCommaSeparatedToList(DEFAULT_EXCLUDES, excludes);
-       }
-
-       private void addCommaSeparatedToList(String str, List<String> lst) {
-               StringTokenizer st = new StringTokenizer(str, ",");
-               while (st.hasMoreTokens()) {
-                       String token = st.nextToken();
-                       if (!lst.contains(token))
-                               lst.add(token);
-               }
-       }
-
-       public void setResourceLoader(ResourceLoader resourceLoader) {
-               this.resourceLoader = resourceLoader;
-       }
-
-       /**
-        * Can be overridden in order to provide the proper resource loader used to
-        * resolve resources.
-        */
-       public ResourceLoader getResourceLoaderToUse() {
-               return resourceLoader;
-       }
-
-       public void setBase(String base) {
-               this.base = base;
-       }
-
-       public void setInclude(String include) {
-               this.include = include;
-       }
-
-       public void setIncludes(List<String> includes) {
-               this.includes = includes;
-       }
-
-       public void setExclude(String exclude) {
-               this.exclude = exclude;
-       }
-
-       public void setExcludes(List<String> excludes) {
-               this.excludes = excludes;
-       }
-
-       public void setUseDefaultExcludes(Boolean useDefaultExcludes) {
-               this.useDefaultExcludes = useDefaultExcludes;
-       }
-
-       public void setExcludePathMatcher(PathMatcher excludePathMatcher) {
-               this.excludePathMatcher = excludePathMatcher;
-       }
-
-       public void setResourcePatternResolver(
-                       ResourcePatternResolver resourcePatternResolver) {
-               this.resourcePatternResolver = resourcePatternResolver;
-       }
-
-       public ResourcePatternResolver getResourcePatternResolver() {
-               return resourcePatternResolver;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/deploy/DigestCheck.java b/org.argeo.slc.core/src/org/argeo/slc/core/deploy/DigestCheck.java
deleted file mode 100644 (file)
index be8355f..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.argeo.slc.SlcException;
-import org.springframework.core.io.Resource;
-import org.springframework.util.DigestUtils;
-
-/** Add Spring capabilities to {@link DigestUtils} */
-public class DigestCheck extends DigestUtils {
-       public static String digest(String algorithm, Resource resource) {
-               try {
-                       File file = resource.getFile();
-                       return org.argeo.util.DigestUtils.digest(algorithm, file);
-               } catch (IOException e) {
-                       try {
-                               return org.argeo.util.DigestUtils.digest(algorithm,
-                                               resource.getInputStream());
-                       } catch (IOException e1) {
-                               throw new SlcException("Cannot digest " + resource
-                                               + " with algorithm " + algorithm, e);
-                       }
-               }
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/deploy/LocalFilesDeployment.java b/org.argeo.slc.core/src/org/argeo/slc/core/deploy/LocalFilesDeployment.java
deleted file mode 100644 (file)
index 79ad835..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Map;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.argeo.slc.SlcException;
-import org.springframework.core.io.Resource;
-
-public class LocalFilesDeployment implements Runnable {
-       private String targetBase = "";
-       private ResourceSet resourceSet;
-
-       public LocalFilesDeployment() {
-       }
-
-       public LocalFilesDeployment(ResourceSet resourceSet) {
-               this.resourceSet = resourceSet;
-       }
-
-       public void run() {
-               Map<String, Resource> resources = resourceSet.listResources();
-               for (String relPath : resources.keySet()) {
-                       File targetFile = new File(targetBase + File.separator + relPath);
-                       File parentDir = targetFile.getParentFile();
-                       if (!parentDir.exists())
-                               parentDir.mkdirs();
-
-                       Resource resource = resources.get(relPath);
-
-                       InputStream in = null;
-                       OutputStream out = null;
-                       try {
-                               in = resource.getInputStream();
-                               out = FileUtils.openOutputStream(targetFile);
-                               IOUtils.copy(in, out);
-                       } catch (IOException e) {
-                               throw new SlcException("Cannot extract " + resource + " to "
-                                               + targetFile, e);
-                       } finally {
-                               IOUtils.closeQuietly(in);
-                               IOUtils.closeQuietly(out);
-                       }
-               }
-       }
-
-       public void setTargetBase(String targetBase) {
-               this.targetBase = targetBase;
-       }
-
-       public void setResourceSet(ResourceSet resourceSet) {
-               this.resourceSet = resourceSet;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/deploy/MultiResourceSet.java b/org.argeo.slc.core/src/org/argeo/slc/core/deploy/MultiResourceSet.java
deleted file mode 100644 (file)
index 8da17ba..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.springframework.core.io.Resource;
-
-public class MultiResourceSet implements ResourceSet {
-       private List<ResourceSet> resourceSets = new ArrayList<ResourceSet>();
-
-       public Map<String, Resource> listResources() {
-               Map<String, Resource> res = new HashMap<String, Resource>();
-               for (ResourceSet resourceSet : resourceSets) {
-                       res.putAll(resourceSet.listResources());
-               }
-               return res;
-       }
-
-       /** Last listed override previous for the same relative paths. */
-       public void setResourceSets(List<ResourceSet> resourceSets) {
-               this.resourceSets = resourceSets;
-       }
-
-       public List<ResourceSet> getResourceSets() {
-               return resourceSets;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/deploy/ResourceSet.java b/org.argeo.slc.core/src/org/argeo/slc/core/deploy/ResourceSet.java
deleted file mode 100644 (file)
index 01c01ab..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.util.Map;
-
-import org.springframework.core.io.Resource;
-
-public interface ResourceSet {
-       /**
-        * List the resources, identified by their relative path. Relative paths
-        * must NOT start with a '/'.
-        */
-       public Map<String, Resource> listResources();
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/deploy/SimpleExecutables.java b/org.argeo.slc.core/src/org/argeo/slc/core/deploy/SimpleExecutables.java
deleted file mode 100644 (file)
index 5a5b825..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.io.File;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.build.Distribution;
-import org.argeo.slc.deploy.DeploymentData;
-import org.argeo.slc.deploy.InstalledExecutables;
-import org.argeo.slc.deploy.TargetData;
-
-public class SimpleExecutables implements InstalledExecutables {
-       private final static Log log = LogFactory.getLog(SimpleExecutables.class);
-
-       private String baseDir;
-       private Map<String, String> paths = new TreeMap<String, String>();
-
-       private Distribution distribution;
-
-       public String getExecutablePath(String key) {
-               String path = paths.get(key);
-               if (path == null) {
-                       if (log.isDebugEnabled())
-                               log.debug("No executable path found for key " + key
-                                               + ", using the key as executable name.");
-                       path = key;
-               }
-
-               if (baseDir != null)
-                       path = baseDir + File.separator + path;
-               return path;
-       }
-
-       public String getDeployedSystemId() {
-               // TODO Auto-generated method stub
-               return null;
-       }
-
-       public DeploymentData getDeploymentData() {
-               // TODO Auto-generated method stub
-               return null;
-       }
-
-       public Distribution getDistribution() {
-               return distribution;
-       }
-
-       public TargetData getTargetData() {
-               // TODO Auto-generated method stub
-               return null;
-       }
-
-       public String getBaseDir() {
-               return baseDir;
-       }
-
-       public void setBaseDir(String baseDir) {
-               this.baseDir = baseDir;
-       }
-
-       public Map<String, String> getPaths() {
-               return paths;
-       }
-
-       public void setPaths(Map<String, String> paths) {
-               this.paths = paths;
-       }
-
-       public void setDistribution(Distribution distribution) {
-               this.distribution = distribution;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/deploy/VersionedDirSync.java b/org.argeo.slc.core/src/org/argeo/slc/core/deploy/VersionedDirSync.java
deleted file mode 100644 (file)
index 13d2543..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.deploy.VersioningDriver;
-
-/**
- * Synchronizes an URL to a local directory, taking into account versioning
- * information if possible.
- */
-public class VersionedDirSync implements Runnable {
-       private final static Log log = LogFactory.getLog(VersionedDirSync.class);
-
-       private VersioningDriver versioningDriver;
-       private File dir;
-       private String url;
-       private Boolean clean = false;
-
-       private Boolean changed = null;
-
-       public void run() {
-               changed = null;
-               if (clean) {
-                       try {
-                               log.info("Clean " + dir);
-                               FileUtils.deleteDirectory(dir);
-                       } catch (IOException e) {
-                               throw new SlcException("Cannot delete checkout directory "
-                                               + dir, e);
-                       }
-                       dir.mkdirs();
-               }
-               log.info("Checkout " + url + " to " + dir);
-               changed = versioningDriver.checkout(url, dir, true);
-               if (log.isDebugEnabled())
-                       log.debug("Synchronized " + url + " to " + dir);
-       }
-
-       public void setVersioningDriver(VersioningDriver versioningDriver) {
-               this.versioningDriver = versioningDriver;
-       }
-
-       public void setDir(File dir) {
-               this.dir = dir;
-       }
-
-       public void setUrl(String url) {
-               this.url = url;
-       }
-
-       /** Delete before checkout */
-       public void setClean(Boolean clean) {
-               this.clean = clean;
-       }
-
-       /** Whether last call has changed the directory */
-       public Boolean getChanged() {
-               if (changed == null)
-                       throw new SlcException("Sync has not run");
-               return changed;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/deploy/package.html b/org.argeo.slc.core/src/org/argeo/slc/core/deploy/package.html
deleted file mode 100644 (file)
index f3a4c5b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<html>\r
-<head></head>\r
-<body>\r
-SLC Deploy: deployment of software systems.\r
-</body>\r
-</html>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractExecutionFlowGenerator.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractExecutionFlowGenerator.java
deleted file mode 100644 (file)
index dc55b40..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.GenericBeanDefinition;
-import org.springframework.core.Ordered;
-import org.springframework.core.PriorityOrdered;
-
-public abstract class AbstractExecutionFlowGenerator implements
-               BeanFactoryPostProcessor, PriorityOrdered {
-       private final Log log = LogFactory.getLog(getClass());
-
-       protected abstract Map<String, BeanDefinition> createExecutionFlowDefinitions(
-                       ConfigurableListableBeanFactory beanFactory);
-
-       public void postProcessBeanFactory(
-                       ConfigurableListableBeanFactory beanFactory) throws BeansException {
-               if (!(beanFactory instanceof BeanDefinitionRegistry)) {
-                       throw new SlcException("Can only work on "
-                                       + BeanDefinitionRegistry.class);
-               }
-
-               Map<String, BeanDefinition> definitions = createExecutionFlowDefinitions(beanFactory);
-
-               for (String beanName : definitions.keySet()) {
-                       if (log.isTraceEnabled())
-                               log.debug("Registering execution flow " + beanName);
-                       ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(
-                                       beanName, definitions.get(beanName));
-               }
-       }
-
-       protected GenericBeanDefinition createDefaultFlowDefinition(
-                       List<Runnable> executables) {
-               GenericBeanDefinition bd = new GenericBeanDefinition();
-               bd.setBeanClass(DefaultExecutionFlow.class);
-
-               MutablePropertyValues mpv = new MutablePropertyValues();
-               mpv.addPropertyValue("executables", executables);
-
-               bd.setPropertyValues(mpv);
-               return bd;
-       }
-
-       public int getOrder() {
-               return Ordered.HIGHEST_PRECEDENCE;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java
deleted file mode 100644 (file)
index 1d401c6..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.execution.ExecutionContext;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.RealizedFlow;
-
-/** Provides the base feature of an execution module manager. */
-public abstract class AbstractExecutionModulesManager implements
-               ExecutionModulesManager {
-       private final static Log log = LogFactory
-                       .getLog(AbstractExecutionModulesManager.class);
-
-       // private List<FilteredNotifier> filteredNotifiers = Collections
-       // .synchronizedList(new ArrayList<FilteredNotifier>());
-
-       protected abstract ExecutionFlow findExecutionFlow(String moduleName,
-                       String moduleVersion, String flowName);
-
-       protected abstract ExecutionContext findExecutionContext(String moduleName,
-                       String moduleVersion);
-
-       protected abstract ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
-                       String moduleName, String moduleVersion);
-
-       public void execute(RealizedFlow realizedFlow) {
-               if (log.isTraceEnabled())
-                       log.trace("Executing " + realizedFlow);
-
-               String moduleName = realizedFlow.getModuleName();
-               String moduleVersion = realizedFlow.getModuleVersion();
-
-               Map<? extends String, ? extends Object> variablesToAdd = getExecutionFlowDescriptorConverter(
-                               moduleName, moduleVersion).convertValues(
-                               realizedFlow.getFlowDescriptor());
-               ExecutionContext executionContext = findExecutionContext(moduleName,
-                               moduleVersion);
-               for (String key : variablesToAdd.keySet())
-                       executionContext.setVariable(key, variablesToAdd.get(key));
-
-               ExecutionFlow flow = findExecutionFlow(moduleName, moduleVersion,
-                               realizedFlow.getFlowDescriptor().getName());
-
-               //
-               // Actually runs the flow, IN THIS THREAD
-               //
-               executionContext.beforeFlow(flow);
-               try {
-                       flow.run();
-               } finally {
-                       executionContext.afterFlow(flow);
-               }
-               //
-               //
-               //
-       }
-
-       // public void dispatchUpdateStatus(ExecutionProcess process,
-       // String oldStatus, String newStatus) {
-       // // filtered notifiers
-       // for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
-       // .hasNext();) {
-       // FilteredNotifier filteredNotifier = it.next();
-       // if (filteredNotifier.receiveFrom(process))
-       // filteredNotifier.getNotifier().updateStatus(process, oldStatus,
-       // newStatus);
-       // }
-       //
-       // }
-
-       // public void dispatchAddSteps(ExecutionProcess process,
-       // List<ExecutionStep> steps) {
-       // process.addSteps(steps);
-       // for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
-       // .hasNext();) {
-       // FilteredNotifier filteredNotifier = it.next();
-       // if (filteredNotifier.receiveFrom(process))
-       // filteredNotifier.getNotifier().addSteps(process, steps);
-       // }
-       // }
-
-       // public void registerProcessNotifier(ExecutionProcessNotifier notifier,
-       // Map<String, String> properties) {
-       // filteredNotifiers.add(new FilteredNotifier(notifier, properties));
-       // }
-       //
-       // public void unregisterProcessNotifier(ExecutionProcessNotifier notifier,
-       // Map<String, String> properties) {
-       // filteredNotifiers.remove(notifier);
-       // }
-
-       // protected class FilteredNotifier {
-       // private final ExecutionProcessNotifier notifier;
-       // private final String processId;
-       //
-       // public FilteredNotifier(ExecutionProcessNotifier notifier,
-       // Map<String, String> properties) {
-       // super();
-       // this.notifier = notifier;
-       // if (properties == null)
-       // properties = new HashMap<String, String>();
-       // if (properties.containsKey(SLC_PROCESS_ID))
-       // processId = properties.get(SLC_PROCESS_ID);
-       // else
-       // processId = null;
-       // }
-       //
-       // /**
-       // * Whether event from this process should be received by this listener.
-       // */
-       // public Boolean receiveFrom(ExecutionProcess process) {
-       // if (processId != null)
-       // if (process.getUuid().equals(processId))
-       // return true;
-       // else
-       // return false;
-       // return true;
-       // }
-       //
-       // @Override
-       // public int hashCode() {
-       // return notifier.hashCode();
-       // }
-       //
-       // @Override
-       // public boolean equals(Object obj) {
-       // if (obj instanceof FilteredNotifier) {
-       // FilteredNotifier fn = (FilteredNotifier) obj;
-       // return notifier.equals(fn.notifier);
-       // } else if (obj instanceof ExecutionProcessNotifier) {
-       // ExecutionProcessNotifier epn = (ExecutionProcessNotifier) obj;
-       // return notifier.equals(epn);
-       // } else
-       // return false;
-       // }
-       //
-       // public ExecutionProcessNotifier getNotifier() {
-       // return notifier;
-       // }
-       //
-       // }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractExecutionValue.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractExecutionValue.java
deleted file mode 100644 (file)
index 131ffec..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.Serializable;
-
-/** Value to be used by an execution */
-public abstract class AbstractExecutionValue implements Serializable {
-       private static final long serialVersionUID = 1558444746120706961L;
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractSpecAttribute.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractSpecAttribute.java
deleted file mode 100644 (file)
index 109c033..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.Serializable;
-
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-
-/** Canonical implementation of the execution spec attribute booleans. */
-public abstract class AbstractSpecAttribute implements ExecutionSpecAttribute,
-               Serializable {
-       private static final long serialVersionUID = 6494963738891709440L;
-       private Boolean isImmutable = false;
-       private Boolean isConstant = false;
-       private Boolean isHidden = false;
-
-       private String description;
-
-       /** Has to be set at instantiation */
-       public Boolean getIsImmutable() {
-               return isImmutable;
-       }
-
-       public void setIsImmutable(Boolean isImmutable) {
-               this.isImmutable = isImmutable;
-       }
-
-       /** Cannot be overridden at runtime */
-       public Boolean getIsConstant() {
-               return isConstant;
-       }
-
-       public void setIsConstant(Boolean isConstant) {
-               this.isConstant = isConstant;
-       }
-
-       /** Should not be shown to the end user */
-       public Boolean getIsHidden() {
-               return isHidden;
-       }
-
-       public void setIsHidden(Boolean isHidden) {
-               this.isHidden = isHidden;
-       }
-
-       /*
-        * DEPRECATED
-        */
-       /** @deprecated use {@link #getIsImmutable()} instead */
-       public Boolean getIsParameter() {
-               return isImmutable;
-       }
-
-       /** @deprecated use {@link #getIsConstant()} instead */
-       public Boolean getIsFrozen() {
-               return isConstant;
-       }
-
-       /** @deprecated use {@link #setIsImmutable(Boolean)} instead */
-       public void setIsParameter(Boolean isParameter) {
-               this.isImmutable = isParameter;
-       }
-
-       /** @deprecated use {@link #setIsConstant(Boolean)} instead */
-       public void setIsFrozen(Boolean isFrozen) {
-               this.isConstant = isFrozen;
-       }
-
-       public void setDescription(String description) {
-               this.description = description;
-       }
-
-       public String getDescription() {
-               return description;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractSpringExecutionModule.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractSpringExecutionModule.java
deleted file mode 100644 (file)
index b2252f6..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.argeo.slc.execution.ExecutionModule;
-
-@Deprecated
-public abstract class AbstractSpringExecutionModule implements ExecutionModule
-                {
-/*
-       protected ApplicationContext applicationContext;
-
-       protected ExecutionContext executionContext;
-
-       protected ExecutionFlowDescriptorConverter descriptorConverter = new DefaultDescriptorConverter();
-
-       public ExecutionModuleDescriptor getDescriptor() {
-               ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
-               md.setName(getName());
-               md.setVersion(getVersion());
-
-               Map<String, ExecutionFlow> executionFlows = listFlows();
-               for (String name : executionFlows.keySet()) {
-                       ExecutionFlow executionFlow = executionFlows.get(name);
-
-                       Assert.notNull(executionFlow.getName());
-                       Assert.state(name.equals(executionFlow.getName()));
-
-                       ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
-                       Assert.notNull(executionSpec);
-                       Assert.notNull(executionSpec.getName());
-
-                       Map<String, Object> values = new TreeMap<String, Object>();
-                       for (String key : executionSpec.getAttributes().keySet()) {
-                               ExecutionSpecAttribute attribute = executionSpec
-                                               .getAttributes().get(key);
-
-                               if (executionFlow.isSetAsParameter(key)) {
-                                       Object value = executionFlow.getParameter(key);
-                                       if (attribute instanceof PrimitiveSpecAttribute) {
-                                               PrimitiveValue primitiveValue = new PrimitiveValue();
-                                               primitiveValue
-                                                               .setType(((PrimitiveSpecAttribute) attribute)
-                                                                               .getType());
-                                               primitiveValue.setValue(value);
-                                               values.put(key, primitiveValue);
-                                       } else if (attribute instanceof RefSpecAttribute) {
-                                               RefValue refValue = new RefValue();
-                                               if (value instanceof ScopedObject) {
-                                                       refValue.setLabel("RUNTIME "
-                                                                       + value.getClass().getName());
-                                               } else {
-                                                       refValue.setLabel("STATIC "
-                                                                       + value.getClass().getName());
-                                               }
-                                               values.put(key, refValue);
-                                       } else if (attribute instanceof ResourceSpecAttribute) {
-                                               PrimitiveValue primitiveValue = new PrimitiveValue();
-                                               primitiveValue
-                                                               .setType(((ResourceSpecAttribute) attribute)
-                                                                               .getType());
-                                               primitiveValue.setValue(value);
-                                               values.put(key, primitiveValue);
-                                       } else {
-                                               throw new SlcException("Unkown spec attribute type "
-                                                               + attribute.getClass());
-                                       }
-                               }
-
-                       }
-
-                       ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name,
-                                       values, executionSpec);
-                       if (executionFlow.getPath() != null)
-                               efd.setPath(executionFlow.getPath());
-
-                       // Add execution spec if necessary
-                       if (!md.getExecutionSpecs().contains(executionSpec))
-                               md.getExecutionSpecs().add(executionSpec);
-
-                       // Add execution flow
-                       md.getExecutionFlows().add(efd);
-               }
-
-               return md;
-       }
-
-       protected Map<String, ExecutionFlow> listFlows() {
-               GenericBeanFactoryAccessor accessor = new GenericBeanFactoryAccessor(
-                               applicationContext);
-               Map<String, ExecutionFlow> executionFlows = accessor
-                               .getBeansOfType(ExecutionFlow.class);
-               return executionFlows;
-       }
-
-       public void execute(ExecutionFlowDescriptor executionFlowDescriptor) {
-               if (descriptorConverter != null)
-                       executionContext.addVariables(descriptorConverter
-                                       .convertValues(executionFlowDescriptor));
-               ExecutionFlow flow = (ExecutionFlow) applicationContext.getBean(
-                               executionFlowDescriptor.getName(), ExecutionFlow.class);
-               flow.run();
-       }
-
-       public void setApplicationContext(ApplicationContext applicationContext)
-                       throws BeansException {
-               this.applicationContext = applicationContext;
-       }
-
-       public void setExecutionContext(ExecutionContext executionContext) {
-               this.executionContext = executionContext;
-       }
-
-       public void setDescriptorConverter(
-                       ExecutionFlowDescriptorConverter descriptorConverter) {
-               this.descriptorConverter = descriptorConverter;
-       }*/
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultAgent.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultAgent.java
deleted file mode 100644 (file)
index c692820..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLDecoder;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import org.argeo.slc.DefaultNameVersion;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionModuleDescriptor;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.ExecutionProcess;
-import org.argeo.slc.execution.SlcAgent;
-
-/** Implements the base methods of an SLC agent. */
-public class DefaultAgent implements SlcAgent {
-       // private final static Log log = LogFactory.getLog(DefaultAgent.class);
-       /** UTF-8 charset for encoding. */
-       private final static String UTF8 = "UTF-8";
-
-       private String agentUuid = null;
-       private ExecutionModulesManager modulesManager;
-
-       private ThreadGroup processesThreadGroup;
-       private Map<String, ProcessThread> runningProcesses = Collections
-                       .synchronizedMap(new HashMap<String, ProcessThread>());
-
-       private String defaultModulePrefix = null;
-
-       /*
-        * LIFECYCLE
-        */
-       /** Initialization */
-       public void init() {
-               agentUuid = initAgentUuid();
-               processesThreadGroup = new ThreadGroup("SLC Processes of Agent #"
-                               + agentUuid);
-       }
-
-       /** Clean up (needs to be called by overriding method) */
-       public void destroy() {
-       }
-
-       /**
-        * Called during initialization in order to determines the agent UUID. To be
-        * overridden. By default creates a new one per instance.
-        */
-       protected String initAgentUuid() {
-               return UUID.randomUUID().toString();
-       }
-
-       /*
-        * SLC AGENT
-        */
-       public void process(ExecutionProcess process) {
-               ProcessThread processThread = createProcessThread(processesThreadGroup,
-                               modulesManager, process);
-               processThread.start();
-               runningProcesses.put(process.getUuid(), processThread);
-
-               // clean up old processes
-               Iterator<ProcessThread> it = runningProcesses.values().iterator();
-               while (it.hasNext()) {
-                       ProcessThread pThread = it.next();
-                       if (!pThread.isAlive())
-                               it.remove();
-               }
-       }
-
-       public String process(List<URI> uris) {
-               DefaultProcess process = new DefaultProcess();
-               for (URI uri : uris) {
-                       String[] path = uri.getPath().split("/");
-                       if (path.length < 3)
-                               throw new SlcException("Badly formatted URI: " + uri);
-                       NameVersion nameVersion = new DefaultNameVersion(path[1]);
-                       StringBuilder flow = new StringBuilder();
-                       for (int i = 2; i < path.length; i++)
-                               flow.append('/').append(path[i]);
-
-                       Map<String, Object> values = getQueryMap(uri.getQuery());
-                       // Get execution module descriptor
-                       ExecutionModuleDescriptor emd = getExecutionModuleDescriptor(
-                                       nameVersion.getName(), nameVersion.getVersion());
-                       process.getRealizedFlows().add(
-                                       emd.asRealizedFlow(flow.toString(), values));
-               }
-               process(process);
-               return process.getUuid();
-       }
-
-       public void kill(String processUuid) {
-               if (runningProcesses.containsKey(processUuid)) {
-                       runningProcesses.get(processUuid).interrupt();
-               } else {
-                       // assume is finished
-               }
-       }
-
-       public void waitFor(String processUuid, Long millis) {
-               if (runningProcesses.containsKey(processUuid)) {
-                       try {
-                               if (millis != null)
-                                       runningProcesses.get(processUuid).join(millis);
-                               else
-                                       runningProcesses.get(processUuid).join();
-                       } catch (InterruptedException e) {
-                               // silent
-                       }
-               } else {
-                       // assume is finished
-               }
-       }
-
-       /** Creates the thread which will coordinate the execution for this agent. */
-       protected ProcessThread createProcessThread(
-                       ThreadGroup processesThreadGroup,
-                       ExecutionModulesManager modulesManager, ExecutionProcess process) {
-               ProcessThread processThread = new ProcessThread(processesThreadGroup,
-                               modulesManager, process);
-               return processThread;
-       }
-
-       public ExecutionModuleDescriptor getExecutionModuleDescriptor(
-                       String moduleName, String moduleVersion) {
-               // Get execution module descriptor
-               ExecutionModuleDescriptor emd;
-               try {
-                       modulesManager
-                                       .start(new DefaultNameVersion(moduleName, moduleVersion));
-                       emd = modulesManager.getExecutionModuleDescriptor(moduleName,
-                                       moduleVersion);
-               } catch (SlcException e) {
-                       if (defaultModulePrefix != null) {
-                               moduleName = defaultModulePrefix + "." + moduleName;
-                               modulesManager.start(new DefaultNameVersion(moduleName,
-                                               moduleVersion));
-                               emd = modulesManager.getExecutionModuleDescriptor(moduleName,
-                                               moduleVersion);
-                       } else
-                               throw e;
-               }
-               return emd;
-       }
-
-       public List<ExecutionModuleDescriptor> listExecutionModuleDescriptors() {
-               return modulesManager.listExecutionModules();
-       }
-
-       public boolean ping() {
-               return true;
-       }
-
-       /*
-        * UTILITIES
-        */
-       /**
-        * @param query
-        *            can be null
-        */
-       static Map<String, Object> getQueryMap(String query) {
-               Map<String, Object> map = new LinkedHashMap<String, Object>();
-               if (query == null)
-                       return map;
-               String[] params = query.split("&");
-               for (String param : params) {
-                       String[] arr = param.split("=");
-                       String name = arr[0];
-                       Object value = arr.length > 1 ? param.split("=")[1] : Boolean.TRUE;
-                       try {
-                               map.put(URLDecoder.decode(name, UTF8),
-                                               URLDecoder.decode(value.toString(), UTF8));
-                       } catch (UnsupportedEncodingException e) {
-                               throw new SlcException("Cannot decode '" + param + "'", e);
-                       }
-               }
-               return map;
-       }
-
-       /*
-        * BEAN
-        */
-       public void setModulesManager(ExecutionModulesManager modulesManager) {
-               this.modulesManager = modulesManager;
-       }
-
-       public void setDefaultModulePrefix(String defaultModulePrefix) {
-               this.defaultModulePrefix = defaultModulePrefix;
-       }
-
-       public String getAgentUuid() {
-               return agentUuid;
-       }
-
-       @Override
-       public String toString() {
-               return "Agent #" + getAgentUuid();
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultAgentCli.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultAgentCli.java
deleted file mode 100644 (file)
index e02d50f..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-package org.argeo.slc.core.execution;
-
-import java.net.URI;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.DefaultNameVersion;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionFlowDescriptor;
-import org.argeo.slc.execution.ExecutionModuleDescriptor;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.argeo.slc.execution.SlcAgent;
-import org.argeo.slc.execution.SlcAgentCli;
-
-/**
- * Authenticates thread and executes synchronously a command line execution.
- * Reference implementation of args to URIs algorithm.
- */
-public class DefaultAgentCli implements SlcAgentCli {
-       private final static Log log = LogFactory.getLog(DefaultAgentCli.class);
-
-       private final static String UTF8 = "UTF-8";
-       private SlcAgent agent;
-//     private AuthenticationManager authenticationManager;
-
-       private Long timeout = 24 * 60 * 60 * 1000l;
-
-       public String process(String[] args) {
-//             if (SecurityContextHolder.getContext().getAuthentication() == null) {
-//                     OsAuthenticationToken oat = new OsAuthenticationToken();
-//                     Authentication authentication = authenticationManager
-//                                     .authenticate(oat);
-//                     SecurityContextHolder.getContext()
-//                                     .setAuthentication(authentication);
-//             }
-
-               if (args.length > 0 && args[0].equals("help")) {
-                       StringBuilder buf = new StringBuilder();
-                       help(args, buf);
-                       log.info("\n" + buf);
-                       return buf.toString();
-               } else {
-                       List<URI> uris = asURIs(args);
-                       String processUuid = agent.process(uris);
-                       agent.waitFor(processUuid, timeout);
-                       return processUuid;
-               }
-       }
-
-       protected void help(String[] rawArgs, StringBuilder buf) {
-               String[] args = Arrays.copyOfRange(rawArgs, 1, rawArgs.length);
-               if (args.length == 0) {// modules
-                       for (ExecutionModuleDescriptor emd : agent
-                                       .listExecutionModuleDescriptors()) {
-                               appendModule(emd, buf);
-                       }
-               } else if (args.length == 1 && !args[0].contains("/")) {// single module
-                       NameVersion nameVersion = new DefaultNameVersion(args[0]);
-                       ExecutionModuleDescriptor emd = agent.getExecutionModuleDescriptor(
-                                       nameVersion.getName(), nameVersion.getVersion());
-                       appendModule(emd, buf);
-
-                       // flows
-                       for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) {
-                               buf.append(" ").append(efd.getName());
-                               if (efd.getDescription() != null
-                                               && !efd.getDescription().trim().equals(""))
-                                       buf.append(" : ").append(" ").append(efd.getDescription());
-                               buf.append('\n');
-                       }
-                       return;
-               } else {
-                       List<URI> uris = asURIs(args);
-                       for (URI uri : uris) {
-                               appendUriHelp(uri, buf);
-                       }
-               }
-       }
-
-       protected void appendUriHelp(URI uri, StringBuilder buf) {
-               String[] path = uri.getPath().split("/");
-               NameVersion nameVersion = new DefaultNameVersion(path[1]);
-               ExecutionModuleDescriptor emd = agent.getExecutionModuleDescriptor(
-                               nameVersion.getName(), nameVersion.getVersion());
-
-               StringBuilder flow = new StringBuilder();
-               for (int i = 2; i < path.length; i++)
-                       flow.append('/').append(path[i]);
-               String flowPath = flow.toString();
-               ExecutionFlowDescriptor efd = findExecutionFlowDescriptor(emd, flowPath);
-               if (efd == null)
-                       throw new SlcException("Flow " + uri + " not found");
-
-               appendModule(emd, buf);
-
-               buf.append(" ").append(efd.getName());
-               if (efd.getDescription() != null
-                               && !efd.getDescription().trim().equals(""))
-                       buf.append(" : ").append(" ").append(efd.getDescription());
-               buf.append('\n');
-               Map<String, Object> values = DefaultAgent.getQueryMap(uri.getQuery());
-               ExecutionSpec spec = efd.getExecutionSpec();
-               for (String attrKey : spec.getAttributes().keySet()) {
-                       ExecutionSpecAttribute esa = spec.getAttributes().get(attrKey);
-                       buf.append("  --").append(attrKey);
-                       if (values.containsKey(attrKey))
-                               buf.append(" ").append(values.get(attrKey));
-                       if (esa.getValue() != null)
-                               buf.append(" (").append(esa.getValue()).append(')');
-                       buf.append('\n');
-               }
-       }
-
-       private void appendModule(ExecutionModuleDescriptor emd, StringBuilder buf) {
-               buf.append("# ").append(emd.getName());
-               if (emd.getDescription() != null
-                               && !emd.getDescription().trim().equals(""))
-                       buf.append(" : ").append(emd.getDescription());
-               if (emd.getVersion() != null)
-                       buf.append(" (v").append(emd.getVersion()).append(")");
-               buf.append('\n');
-       }
-
-       public static List<URI> asURIs(String[] args) {
-               try {
-                       List<URI> uris = new ArrayList<URI>();
-                       List<String> leftOvers = new ArrayList<String>();
-
-                       Boolean hasArgs = false;
-                       String currKey = null;
-                       StringBuilder currUri = null;
-                       Iterator<String> argIt = Arrays.asList(args).iterator();
-                       while (argIt.hasNext()) {
-                               String arg = argIt.next();
-                               if (!arg.startsWith("-")) {
-                                       if (currKey != null) {// value
-                                               currUri.append(URLEncoder.encode(arg, UTF8));
-                                               currKey = null;
-                                       } else { // module
-                                               if (currUri != null) {
-                                                       uris.add(new URI(currUri.toString()));
-                                               }
-                                               currUri = new StringBuilder("flow:");
-
-                                               String currModule = arg;
-                                               currUri.append('/').append(currModule);
-                                               if (!arg.contains("/")) {
-                                                       // flow path not in arg go to next arg
-                                                       if (!argIt.hasNext())
-                                                               throw new SlcException("No flow found");
-                                                       String currFlow = argIt.next();
-                                                       if (!currFlow.startsWith("/"))
-                                                               currFlow = "/" + currFlow;
-                                                       currUri.append(currFlow);
-                                               }
-                                       }
-                               } else {
-                                       if (currUri == null) {// first args
-                                               leftOvers.add(arg);
-                                       } else {
-                                               String key;
-                                               if (arg.startsWith("--"))
-                                                       key = arg.substring(2);
-                                               else if (arg.startsWith("-"))
-                                                       key = arg.substring(1);
-                                               else {
-                                                       throw new SlcException("Cannot intepret key: "
-                                                                       + arg);
-                                               }
-
-                                               if (!hasArgs) {
-                                                       currUri.append('?');
-                                                       hasArgs = true;
-                                               } else {
-                                                       currUri.append('&');
-                                               }
-
-                                               // deal with boolean keys
-                                               if (currKey != null) {// value
-                                                       currUri.append(URLEncoder.encode("true", UTF8));
-                                                       currKey = null;
-                                               }
-
-                                               currKey = key;
-                                               currUri.append(URLEncoder.encode(key, UTF8))
-                                                               .append('=');
-                                       }
-                               }
-                       }
-                       if (currUri != null)
-                               uris.add(new URI(currUri.toString()));
-                       return uris;
-               } catch (Exception e) {
-                       throw new SlcException("Cannot convert " + Arrays.toString(args)
-                                       + " to flow URI", e);
-               }
-       }
-
-       private ExecutionFlowDescriptor findExecutionFlowDescriptor(
-                       ExecutionModuleDescriptor emd, String flowPath) {
-               ExecutionFlowDescriptor flowDescriptor = null;
-               for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) {
-                       String name = efd.getName();
-                       // normalize name as flow path
-                       if (!name.startsWith("/"))
-                               name = "/" + name;
-                       if (name.endsWith("/"))
-                               name = name.substring(0, name.length() - 1);
-                       if (name.equals(flowPath)) {
-                               flowDescriptor = efd;
-                               break;
-                       }
-               }
-               return flowDescriptor;
-       }
-
-       public void setAgent(SlcAgent agent) {
-               this.agent = agent;
-       }
-
-//     public void setAuthenticationManager(
-//                     AuthenticationManager authenticationManager) {
-//             this.authenticationManager = authenticationManager;
-//     }
-
-       public void setTimeout(Long timeout) {
-               this.timeout = timeout;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionFlow.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionFlow.java
deleted file mode 100644 (file)
index bebde75..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionContext;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.springframework.beans.factory.BeanNameAware;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.validation.MapBindingResult;
-
-/** Default implementation of an execution flow. */
-public class DefaultExecutionFlow implements ExecutionFlow, InitializingBean,
-               BeanNameAware {
-       private final static Log log = LogFactory
-                       .getLog(DefaultExecutionFlow.class);
-
-       private final ExecutionSpec executionSpec;
-       private String name = null;
-       private Map<String, Object> parameters = new HashMap<String, Object>();
-       private List<Runnable> executables = new ArrayList<Runnable>();
-
-       private String path;
-
-       private Boolean failOnError = true;
-
-       // Only needed if stacked execution flows are used
-       private ExecutionContext executionContext = null;
-
-       public DefaultExecutionFlow() {
-               this.executionSpec = new DefaultExecutionSpec();
-       }
-
-       public DefaultExecutionFlow(ExecutionSpec executionSpec) {
-               this.executionSpec = executionSpec;
-       }
-
-       public DefaultExecutionFlow(ExecutionSpec executionSpec,
-                       Map<String, Object> parameters) {
-               // be sure to have an execution spec
-               this.executionSpec = (executionSpec == null) ? new DefaultExecutionSpec()
-                               : executionSpec;
-
-               // only parameters contained in the executionSpec can be set
-               for (String parameter : parameters.keySet()) {
-                       if (!executionSpec.getAttributes().containsKey(parameter)) {
-                               throw new SlcException("Parameter " + parameter
-                                               + " is not defined in the ExecutionSpec");
-                       }
-               }
-
-               // set the parameters
-               this.parameters.putAll(parameters);
-
-               // check that all the required parameters are defined
-               MapBindingResult errors = new MapBindingResult(parameters, "execution#"
-                               + getName());
-               for (String key : executionSpec.getAttributes().keySet()) {
-                       ExecutionSpecAttribute attr = executionSpec.getAttributes()
-                                       .get(key);
-
-                       if (attr.getIsImmutable() && !isSetAsParameter(key)) {
-                               errors.rejectValue(key, "Immutable but not set");
-                               break;
-                       }
-
-                       if (attr.getIsConstant() && !isSetAsParameter(key)) {
-                               errors.rejectValue(key, "Constant but not set as parameter");
-                               break;
-                       }
-
-                       if (attr.getIsHidden() && !isSetAsParameter(key)) {
-                               errors.rejectValue(key, "Hidden but not set as parameter");
-                               break;
-                       }
-               }
-
-               if (errors.hasErrors())
-                       throw new SlcException("Could not prepare execution flow: "
-                                       + errors.toString());
-
-       }
-
-       public void run() {
-               try {
-                       for (Runnable executable : executables) {
-                               if (Thread.interrupted()) {
-                                       log.error("Flow '" + getName() + "' killed before '"
-                                                       + executable + "'");
-                                       Thread.currentThread().interrupt();
-                                       return;
-                                       // throw new ThreadDeath();
-                               }
-                               this.doExecuteRunnable(executable);
-                       }
-               } catch (RuntimeException e) {
-                       if (Thread.interrupted()) {
-                               log.error("Flow '" + getName()
-                                               + "' killed while receiving an unrelated exception", e);
-                               Thread.currentThread().interrupt();
-                               return;
-                               // throw new ThreadDeath();
-                       }
-                       if (failOnError)
-                               throw e;
-                       else {
-                               log.error("Execution flow failed,"
-                                               + " but process did not fail"
-                                               + " because failOnError property"
-                                               + " is set to false: " + e);
-                               if (log.isTraceEnabled())
-                                       e.printStackTrace();
-                       }
-               }
-       }
-
-       /**
-        * List sub-runnables that would be executed if run() method would be
-        * called.
-        */
-       public Iterator<Runnable> runnables() {
-               return executables.iterator();
-       }
-
-       /**
-        * If there is one and only one runnable wrapped return it, throw an
-        * exeception otherwise.
-        */
-       public Runnable getRunnable() {
-               if (executables.size() == 1)
-                       return executables.get(0);
-               else
-                       throw new SlcException("There are " + executables.size()
-                                       + " runnables in flow " + getName());
-       }
-
-       public void doExecuteRunnable(Runnable runnable) {
-               try {
-                       if (executionContext != null)
-                               if (runnable instanceof ExecutionFlow)
-                                       executionContext.beforeFlow((ExecutionFlow) runnable);
-                       runnable.run();
-               } finally {
-                       if (executionContext != null)
-                               if (runnable instanceof ExecutionFlow)
-                                       executionContext.afterFlow((ExecutionFlow) runnable);
-               }
-       }
-
-       public void afterPropertiesSet() throws Exception {
-               if (path == null) {
-                       if (name.charAt(0) == '/') {
-                               path = name.substring(0, name.lastIndexOf('/'));
-                       }
-               }
-
-               if (path != null) {
-                       for (Runnable executable : executables) {
-                               if (executable instanceof DefaultExecutionFlow) {
-                                       // so we don't need to have DefaultExecutionFlow
-                                       // implementing StructureAware
-                                       // FIXME: probably has side effects
-                                       DefaultExecutionFlow flow = (DefaultExecutionFlow) executable;
-                                       String newPath = path + '/' + flow.getName();
-                                       flow.setPath(newPath);
-                                       log.warn(newPath + " was forcibly set on " + flow);
-                               }
-                       }
-               }
-       }
-
-       public void setBeanName(String name) {
-               this.name = name;
-       }
-
-       public void setExecutables(List<Runnable> executables) {
-               this.executables = executables;
-       }
-
-       public void setParameters(Map<String, Object> attributes) {
-               this.parameters = attributes;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public ExecutionSpec getExecutionSpec() {
-               return executionSpec;
-       }
-
-       public Object getParameter(String parameterName) {
-               // Verify that there is a spec attribute
-               ExecutionSpecAttribute specAttr = null;
-               if (executionSpec.getAttributes().containsKey(parameterName)) {
-                       specAttr = executionSpec.getAttributes().get(parameterName);
-               } else {
-                       throw new SlcException("Key " + parameterName
-                                       + " is not defined in the specifications of " + toString());
-               }
-
-               if (parameters.containsKey(parameterName)) {
-                       Object paramValue = parameters.get(parameterName);
-                       return paramValue;
-               } else {
-                       if (specAttr.getValue() != null) {
-                               return specAttr.getValue();
-                       }
-               }
-               throw new SlcException("Key " + parameterName
-                               + " is not set as parameter in " + toString());
-       }
-
-       public Boolean isSetAsParameter(String key) {
-               return parameters.containsKey(key)
-                               || (executionSpec.getAttributes().containsKey(key) && executionSpec
-                                               .getAttributes().get(key).getValue() != null);
-       }
-
-       @Override
-       public String toString() {
-               return new StringBuffer("Execution flow ").append(name).toString();
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               return ((ExecutionFlow) obj).getName().equals(name);
-       }
-
-       @Override
-       public int hashCode() {
-               return name.hashCode();
-       }
-
-       public String getPath() {
-               return path;
-       }
-
-       public void setPath(String path) {
-               this.path = path;
-       }
-
-       public Boolean getFailOnError() {
-               return failOnError;
-       }
-
-       public void setFailOnError(Boolean failOnError) {
-               this.failOnError = failOnError;
-       }
-
-       public void setExecutionContext(ExecutionContext executionContext) {
-               this.executionContext = executionContext;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java
deleted file mode 100644 (file)
index beac917..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionFlowDescriptor;
-import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
-import org.argeo.slc.execution.ExecutionModuleDescriptor;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.springframework.aop.scope.ScopedObject;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.util.StringUtils;
-
-/**
- * Performs conversion in both direction between data exchanged with the agent
- * and the data in the application context.
- */
-public class DefaultExecutionFlowDescriptorConverter implements
-               ExecutionFlowDescriptorConverter, ApplicationContextAware {
-       public final static String REF_VALUE_TYPE_BEAN_NAME = "beanName";
-
-       /** Workaround for https://www.spartadn.com/bugzilla/show_bug.cgi?id=206 */
-       private final static String REF_VALUE_INTERNAL = "[internal]";
-
-       private final static Log log = LogFactory
-                       .getLog(DefaultExecutionFlowDescriptorConverter.class);
-
-       private ApplicationContext applicationContext;
-
-       @SuppressWarnings("unused")
-       public Map<String, Object> convertValues(
-                       ExecutionFlowDescriptor executionFlowDescriptor) {
-               Map<String, Object> values = executionFlowDescriptor.getValues();
-               Map<String, Object> convertedValues = new HashMap<String, Object>();
-               ExecutionSpec executionSpec = executionFlowDescriptor
-                               .getExecutionSpec();
-
-               if (executionSpec == null && log.isTraceEnabled())
-                       log.warn("Execution spec is null for " + executionFlowDescriptor);
-
-               if (values != null && executionSpec != null) {
-                       values: for (String key : values.keySet()) {
-                               ExecutionSpecAttribute attribute = executionSpec
-                                               .getAttributes().get(key);
-
-                               if (attribute == null)
-                                       throw new FlowConfigurationException(
-                                                       "No spec attribute defined for '" + key + "'");
-
-                               if (attribute.getIsConstant())
-                                       continue values;
-
-                               Object value = values.get(key);
-                               if (value instanceof PrimitiveValue) {
-                                       PrimitiveValue primitiveValue = (PrimitiveValue) value;
-                                       // TODO: check class <=> type
-                                       convertedValues.put(key, primitiveValue.getValue());
-                               } else if (value instanceof RefValue) {
-                                       RefValue refValue = (RefValue) value;
-                                       String type = refValue.getType();
-                                       if (REF_VALUE_TYPE_BEAN_NAME.equals(type)) {
-                                               // FIXME: UI should send all information about spec
-                                               // - targetClass
-                                               // - name
-                                               // String executionSpecName = executionSpec.getName();
-                                               // ExecutionSpec localSpec = (ExecutionSpec)
-                                               // applicationContext
-                                               // .getBean(executionSpecName);
-                                               // RefSpecAttribute localAttr = (RefSpecAttribute)
-                                               // localSpec
-                                               // .getAttributes().get(key);
-                                               // Class<?> targetClass = localAttr.getTargetClass();
-                                               //
-                                               // String primitiveType = PrimitiveUtils
-                                               // .classAsType(targetClass);
-                                               String primitiveType = null;
-                                               if (primitiveType != null) {
-                                                       // not active
-                                                       String ref = refValue.getRef();
-                                                       Object obj = PrimitiveUtils.convert(primitiveType,
-                                                                       ref);
-                                                       convertedValues.put(key, obj);
-                                               } else {
-                                                       String ref = refValue.getRef();
-                                                       if (ref != null && !ref.equals(REF_VALUE_INTERNAL)) {
-                                                               Object obj = null;
-                                                               if (applicationContext.containsBean(ref)) {
-                                                                       obj = applicationContext.getBean(ref);
-                                                               } else {
-                                                                       // FIXME: hack in order to pass primitive
-                                                                       obj = ref;
-                                                               }
-                                                               convertedValues.put(key, obj);
-                                                       } else {
-                                                               log.warn("Cannot interpret " + refValue);
-                                                       }
-                                               }
-                                       } else if (PrimitiveUtils.typeAsClass(type) != null) {
-                                               String ref = refValue.getRef();
-                                               Object obj = PrimitiveUtils.convert(type, ref);
-                                               convertedValues.put(key, obj);
-                                       } else {
-                                               throw new FlowConfigurationException(
-                                                               "Ref value type not supported: "
-                                                                               + refValue.getType());
-                                       }
-                               } else {
-                                       // default is to take the value as is
-                                       convertedValues.put(key, value);
-                               }
-                       }
-               }
-               return convertedValues;
-       }
-
-       public void addFlowsToDescriptor(ExecutionModuleDescriptor md,
-                       Map<String, ExecutionFlow> executionFlows) {
-               SortedSet<ExecutionFlowDescriptor> set = new TreeSet<ExecutionFlowDescriptor>(
-                               new ExecutionFlowDescriptorComparator());
-               for (String name : executionFlows.keySet()) {
-                       ExecutionFlow executionFlow = executionFlows.get(name);
-
-                       ExecutionFlowDescriptor efd = getExecutionFlowDescriptor(executionFlow);
-                       ExecutionSpec executionSpec = efd.getExecutionSpec();
-
-                       // Add execution spec if necessary
-                       if (!md.getExecutionSpecs().contains(executionSpec))
-                               md.getExecutionSpecs().add(executionSpec);
-
-                       // Add execution flow
-                       set.add(efd);
-                       // md.getExecutionFlows().add(efd);
-               }
-               md.getExecutionFlows().addAll(set);
-       }
-
-       public ExecutionFlowDescriptor getExecutionFlowDescriptor(
-                       ExecutionFlow executionFlow) {
-               if (executionFlow.getName() == null)
-                       throw new FlowConfigurationException("Flow name is null: "
-                                       + executionFlow);
-               String name = executionFlow.getName();
-
-               ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
-               if (executionSpec == null)
-                       throw new FlowConfigurationException("Execution spec is null: "
-                                       + executionFlow);
-               if (executionSpec.getName() == null)
-                       throw new FlowConfigurationException(
-                                       "Execution spec name is null: " + executionSpec);
-
-               Map<String, Object> values = new TreeMap<String, Object>();
-               for (String key : executionSpec.getAttributes().keySet()) {
-                       ExecutionSpecAttribute attribute = executionSpec.getAttributes()
-                                       .get(key);
-
-                       if (attribute instanceof PrimitiveSpecAttribute) {
-                               if (executionFlow.isSetAsParameter(key)) {
-                                       Object value = executionFlow.getParameter(key);
-                                       PrimitiveValue primitiveValue = new PrimitiveValue();
-                                       primitiveValue.setType(((PrimitiveSpecAttribute) attribute)
-                                                       .getType());
-                                       primitiveValue.setValue(value);
-                                       values.put(key, primitiveValue);
-                               } else {
-                                       // no need to add a primitive value if it is not set,
-                                       // all necessary information is in the spec
-                               }
-                       } else if (attribute instanceof RefSpecAttribute) {
-                               if (attribute.getIsConstant()) {
-                                       values.put(key, new RefValue(REF_VALUE_INTERNAL));
-                               } else
-                                       values.put(
-                                                       key,
-                                                       buildRefValue((RefSpecAttribute) attribute,
-                                                                       executionFlow, key));
-                       } else {
-                               throw new FlowConfigurationException(
-                                               "Unkown spec attribute type " + attribute.getClass());
-                       }
-
-               }
-
-               ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name, null,
-                               values, executionSpec);
-               // Takes description from spring
-               BeanFactory bf = getBeanFactory();
-               if (bf != null) {
-                       BeanDefinition bd = getBeanFactory().getBeanDefinition(name);
-                       efd.setDescription(bd.getDescription());
-               }
-               return efd;
-       }
-
-       protected RefValue buildRefValue(RefSpecAttribute rsa,
-                       ExecutionFlow executionFlow, String key) {
-               RefValue refValue = new RefValue();
-               // FIXME: UI should be able to deal with other types
-               refValue.setType(REF_VALUE_TYPE_BEAN_NAME);
-               Class<?> targetClass = rsa.getTargetClass();
-               String primitiveType = PrimitiveUtils.classAsType(targetClass);
-               if (primitiveType != null) {
-                       if (executionFlow.isSetAsParameter(key)) {
-                               Object value = executionFlow.getParameter(key);
-                               refValue.setRef(value.toString());
-                       }
-                       refValue.setType(primitiveType);
-                       return refValue;
-               } else {
-
-                       if (executionFlow.isSetAsParameter(key)) {
-                               String ref = null;
-                               Object value = executionFlow.getParameter(key);
-                               if (applicationContext == null) {
-                                       log.warn("No application context declared, cannot scan ref value.");
-                                       ref = value.toString();
-                               } else {
-
-                                       // look for a ref to the value
-                                       Map<String, ?> beans = getBeanFactory()
-                                                       .getBeansOfType(targetClass, false, false);
-                                       // TODO: also check scoped beans
-                                       beans: for (String beanName : beans.keySet()) {
-                                               Object obj = beans.get(beanName);
-                                               if (value instanceof ScopedObject) {
-                                                       // don't call methods of the target of the scope
-                                                       if (obj instanceof ScopedObject)
-                                                               if (value == obj) {
-                                                                       ref = beanName;
-                                                                       break beans;
-                                                               }
-                                               } else {
-                                                       if (obj.equals(value)) {
-                                                               ref = beanName;
-                                                               break beans;
-                                                       }
-                                               }
-                                       }
-                               }
-                               if (ref == null) {
-                                       if (log.isTraceEnabled())
-                                               log.trace("Cannot define reference for ref spec attribute "
-                                                               + key
-                                                               + " in "
-                                                               + executionFlow
-                                                               + " ("
-                                                               + rsa
-                                                               + ")."
-                                                               + " If it is an inner bean consider put it frozen.");
-                                       ref = REF_VALUE_INTERNAL;
-                               } else {
-                                       if (log.isTraceEnabled())
-                                               log.trace(ref
-                                                               + " is the reference for ref spec attribute "
-                                                               + key + " in " + executionFlow + " (" + rsa
-                                                               + ")");
-                               }
-                               refValue.setRef(ref);
-                       }
-                       return refValue;
-               }
-       }
-
-       /** @return can be null */
-       private ConfigurableListableBeanFactory getBeanFactory() {
-               if (applicationContext == null)
-                       return null;
-               return ((ConfigurableApplicationContext) applicationContext)
-                               .getBeanFactory();
-       }
-
-       /** Must be use within the execution application context */
-       public void setApplicationContext(ApplicationContext applicationContext)
-                       throws BeansException {
-               this.applicationContext = applicationContext;
-       }
-
-       private static class ExecutionFlowDescriptorComparator implements
-                       Comparator<ExecutionFlowDescriptor> {
-               @SuppressWarnings("deprecation")
-               public int compare(ExecutionFlowDescriptor o1,
-                               ExecutionFlowDescriptor o2) {
-                       // TODO: write unit tests for this
-
-                       String name1 = o1.getName();
-                       String name2 = o2.getName();
-
-                       String path1 = o1.getPath();
-                       String path2 = o2.getPath();
-
-                       // Check whether name include path
-                       int lastIndex1 = name1.lastIndexOf('/');
-                       // log.debug(name1+", "+lastIndex1);
-                       if (!StringUtils.hasText(path1) && lastIndex1 >= 0) {
-                               path1 = name1.substring(0, lastIndex1);
-                               name1 = name1.substring(lastIndex1 + 1);
-                       }
-
-                       int lastIndex2 = name2.lastIndexOf('/');
-                       if (!StringUtils.hasText(path2) && lastIndex2 >= 0) {
-                               path2 = name2.substring(0, lastIndex2);
-                               name2 = name2.substring(lastIndex2 + 1);
-                       }
-
-                       // Perform the actual comparison
-                       if (StringUtils.hasText(path1) && StringUtils.hasText(path2)) {
-                               if (path1.equals(path2))
-                                       return name1.compareTo(name2);
-                               else if (path1.startsWith(path2))
-                                       return -1;
-                               else if (path2.startsWith(path1))
-                                       return 1;
-                               else
-                                       return path1.compareTo(path2);
-                       } else if (!StringUtils.hasText(path1)
-                                       && StringUtils.hasText(path2)) {
-                               return 1;
-                       } else if (StringUtils.hasText(path1)
-                                       && !StringUtils.hasText(path2)) {
-                               return -1;
-                       } else if (!StringUtils.hasText(path1)
-                                       && !StringUtils.hasText(path2)) {
-                               return name1.compareTo(name2);
-                       } else {
-                               return 0;
-                       }
-               }
-
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionSpec.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionSpec.java
deleted file mode 100644 (file)
index 2bce125..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.springframework.beans.factory.BeanNameAware;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ConfigurableApplicationContext;
-
-/** Spring based implementation of execution specifications. */
-public class DefaultExecutionSpec implements ExecutionSpec, BeanNameAware,
-               ApplicationContextAware, InitializingBean, Serializable {
-       private static final long serialVersionUID = 5159882223926926539L;
-       private final static Log log = LogFactory
-                       .getLog(DefaultExecutionSpec.class);
-       private transient ApplicationContext applicationContext;
-
-       private String description;
-       private Map<String, ExecutionSpecAttribute> attributes = new HashMap<String, ExecutionSpecAttribute>();
-
-       private String name = INTERNAL_NAME;
-
-       public Map<String, ExecutionSpecAttribute> getAttributes() {
-               return attributes;
-       }
-
-       public void setAttributes(Map<String, ExecutionSpecAttribute> attributes) {
-               this.attributes = attributes;
-       }
-
-       public void setBeanName(String name) {
-               this.name = name;
-       }
-
-       /**
-        * The Spring bean name (only relevant for specs declared has high-level
-        * beans)
-        */
-       public String getName() {
-               return name;
-       }
-
-       public boolean equals(Object obj) {
-               return ((ExecutionSpec) obj).getName().equals(name);
-       }
-
-       /**
-        * The Spring bean description (only relevant for specs declared has
-        * high-level beans)
-        */
-       public String getDescription() {
-               return description;
-       }
-
-       private ConfigurableListableBeanFactory getBeanFactory() {
-               return ((ConfigurableApplicationContext) applicationContext)
-                               .getBeanFactory();
-       }
-
-       public void setApplicationContext(ApplicationContext applicationContext) {
-               this.applicationContext = applicationContext;
-       }
-
-       public void afterPropertiesSet() throws Exception {
-               if (description == null) {
-                       try {
-                               description = getBeanFactory().getBeanDefinition(name)
-                                               .getDescription();
-                       } catch (NoSuchBeanDefinitionException e) {
-                               // silent
-                       }
-               }
-
-               for (String key : attributes.keySet()) {
-                       ExecutionSpecAttribute attr = attributes.get(key);
-                       if (attr instanceof RefSpecAttribute) {
-                               RefSpecAttribute rsa = (RefSpecAttribute) attr;
-                               if (rsa.getChoices() == null) {
-                                       List<RefValueChoice> choices = buildRefValueChoices(rsa);
-                                       rsa.setChoices(choices);
-                               }
-                               if (log.isTraceEnabled())
-                                       log.debug("Spec attr " + key + " has "
-                                                       + rsa.getChoices().size() + " choices");
-                       }
-               }
-       }
-
-       /**
-        * Generates a list of ref value choices based on the bean available in the
-        * application ocntext.
-        */
-       protected List<RefValueChoice> buildRefValueChoices(RefSpecAttribute rsa) {
-               List<RefValueChoice> choices = new ArrayList<RefValueChoice>();
-               if (applicationContext == null) {
-                       log.warn("No application context declared,"
-                                       + " cannot scan ref value choices.");
-                       return choices;
-               }
-
-               beanNames: for (String beanName : getBeanFactory().getBeanNamesForType(
-                               rsa.getTargetClass(), true, false)) {
-
-                       // Since Spring 3, systemProperties is implicitly defined but has no
-                       // bean definition
-                       if (beanName.equals("systemProperties"))
-                               continue beanNames;
-
-                       BeanDefinition bd = getBeanFactory().getBeanDefinition(beanName);
-                       RefValueChoice choice = new RefValueChoice();
-                       choice.setName(beanName);
-                       choice.setDescription(bd.getDescription());
-                       if (log.isTraceEnabled())
-                               log.debug("Found choice " + beanName + " for " + rsa);
-
-                       choices.add(choice);
-
-               }
-               return choices;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionStack.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionStack.java
deleted file mode 100644 (file)
index d1d06c6..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
-import java.util.UUID;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.argeo.slc.execution.ExecutionStack;
-
-/** Canonical implementation of an execution stack. */
-public class DefaultExecutionStack implements ExecutionStack {
-
-       private final static Log log = LogFactory
-                       .getLog(DefaultExecutionStack.class);
-
-       private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
-
-       public synchronized void enterFlow(ExecutionFlow executionFlow) {
-               ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
-               stack.push(runtime);
-
-               Map<String, ExecutionSpecAttribute> specAttrs = executionFlow
-                               .getExecutionSpec().getAttributes();
-               for (String key : specAttrs.keySet()) {
-                       if (executionFlow.isSetAsParameter(key)) {
-                               runtime.getLocalVariables().put(key,
-                                               executionFlow.getParameter(key));
-                       }
-               }
-       }
-
-       public synchronized String getCurrentStackLevelUuid() {
-               return stack.peek().getUuid();
-       }
-
-       public synchronized Integer getStackSize() {
-               return stack.size();
-       }
-
-       /**
-        * Looks for a set variable in the stack, starting at the upper flows
-        * 
-        * @return the variable or <code>null</code> if not found
-        */
-       public synchronized Object findLocalVariable(String key) {
-               Object obj = null;
-               for (int i = 0; i < stack.size(); i++) {
-                       if (stack.get(i).getLocalVariables().containsKey(key)) {
-                               obj = stack.get(i).getLocalVariables().get(key);
-                               break;
-                       }
-               }
-               return obj;
-       }
-
-       public synchronized void leaveFlow(ExecutionFlow executionFlow) {
-               ExecutionFlowRuntime leftEf = stack.pop();
-
-               if (!leftEf.getExecutionFlow().getName()
-                               .equals(executionFlow.getName()))
-                       throw new SlcException("Asked to leave " + executionFlow
-                                       + " but last is " + leftEf);
-
-               leftEf.getScopedObjects().clear();
-               leftEf.getLocalVariables().clear();
-       }
-
-       public synchronized void addScopedObject(String name, Object obj) {
-               ExecutionFlowRuntime runtime = stack.peek();
-               // TODO: check that the object is not set yet ?
-               if (log.isDebugEnabled()) {
-                       Object existing = findScopedObject(name);
-                       if (existing != null)
-                               log.warn("Scoped object " + name + " of type " + obj.getClass()
-                                               + " already registered in " + runtime);
-               }
-               runtime.getScopedObjects().put(name, obj);
-       }
-
-       /** @return </code>null<code> if not found */
-       public synchronized Object findScopedObject(String name) {
-               Object obj = null;
-               for (int i = stack.size() - 1; i >= 0; i--) {
-                       if (stack.get(i).getScopedObjects().containsKey(name)) {
-                               obj = stack.get(i).getScopedObjects().get(name);
-                               break;
-                       }
-               }
-               return obj;
-       }
-
-       protected static class ExecutionFlowRuntime {
-               private final ExecutionFlow executionFlow;
-               private final Map<String, Object> scopedObjects = new HashMap<String, Object>();
-               private final Map<String, Object> localVariables = new HashMap<String, Object>();
-               private final String uuid = UUID.randomUUID().toString();
-
-               public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
-                       this.executionFlow = executionFlow;
-               }
-
-               public ExecutionFlow getExecutionFlow() {
-                       return executionFlow;
-               }
-
-               public Map<String, Object> getScopedObjects() {
-                       return scopedObjects;
-               }
-
-               public String getUuid() {
-                       return uuid;
-               }
-
-               public Map<String, Object> getLocalVariables() {
-                       return localVariables;
-               }
-
-               @Override
-               public String toString() {
-                       return "Stack Level #" + uuid;
-               }
-
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultProcess.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultProcess.java
deleted file mode 100644 (file)
index 3021180..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.argeo.slc.core.execution;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import org.argeo.slc.execution.ExecutionProcess;
-import org.argeo.slc.execution.ExecutionStep;
-import org.argeo.slc.execution.RealizedFlow;
-
-/** Canonical implementation of an {@link ExecutionProcess} as a bean. */
-public class DefaultProcess implements ExecutionProcess {
-       private String uuid = UUID.randomUUID().toString();
-       private String status = ExecutionProcess.NEW;
-
-       private List<ExecutionStep> steps = new ArrayList<ExecutionStep>();
-       private List<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();
-
-       public String getUuid() {
-               return uuid;
-       }
-
-       public String getStatus() {
-               return status;
-       }
-
-       public void setStatus(String status) {
-               this.status = status;
-       }
-
-       public void addSteps(List<ExecutionStep> steps) {
-               steps.addAll(steps);
-       }
-
-       public List<RealizedFlow> getRealizedFlows() {
-               return realizedFlows;
-       }
-
-       public List<ExecutionStep> getSteps() {
-               return steps;
-       }
-
-       public void setSteps(List<ExecutionStep> steps) {
-               this.steps = steps;
-       }
-
-       public void setUuid(String uuid) {
-               this.uuid = uuid;
-       }
-
-       public void setRealizedFlows(List<RealizedFlow> realizedFlows) {
-               this.realizedFlows = realizedFlows;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionAspect.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionAspect.java
deleted file mode 100644 (file)
index b50b78f..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.execution.ExecutionContext;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionStack;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-
-@Aspect
-/** Aspect intercepting calls on execution flows and contexts. */
-public class ExecutionAspect {
-       private final static Log log = LogFactory.getLog(ExecutionAspect.class);
-
-       private ExecutionStack executionStack;
-       private ExecutionContext executionContext;
-
-       @Around("flowExecution()")
-       public void aroundFlow(ProceedingJoinPoint pjp) throws Throwable {
-               // IMPORTANT: Make sure that the execution context is called before the
-               // execution stack
-               executionContext.getUuid();
-
-               ExecutionFlow executionFlow = (ExecutionFlow) pjp.getTarget();
-               executionStack.enterFlow(executionFlow);
-               executionContext.setVariable(ExecutionContext.VAR_FLOW_ID,
-                               executionStack.getCurrentStackLevelUuid());
-               executionContext.setVariable(ExecutionContext.VAR_FLOW_NAME,
-                               executionFlow.getName());
-
-               logStackEvent("=> ", executionFlow);
-               try {
-                       // Actually execute the flow
-                       pjp.proceed();
-               } finally {
-                       logStackEvent("<= ", executionFlow);
-                       executionStack.leaveFlow(executionFlow);
-               }
-       }
-
-       @Around("getVariable()")
-       public Object aroundGetVariable(ProceedingJoinPoint pjp) throws Throwable {
-               Object obj = pjp.proceed();
-               // if the variable was not found, look in the stack starting at the
-               // upper flows
-               if (obj == null) {
-                       String key = pjp.getArgs()[0].toString();
-                       obj = executionStack.findLocalVariable(key);
-               }
-               return obj;
-       }
-
-       @Pointcut("execution(void org.argeo.slc.execution.ExecutionFlow.run())")
-       public void flowExecution() {
-       }
-
-       @Pointcut("execution(* org.argeo.slc.execution.ExecutionContext.getVariable(..))")
-       public void getVariable() {
-       }
-
-       public void setExecutionStack(ExecutionStack executionStack) {
-               this.executionStack = executionStack;
-       }
-
-       public void setExecutionContext(ExecutionContext executionContext) {
-               this.executionContext = executionContext;
-       }
-
-       protected void logStackEvent(String symbol, ExecutionFlow executionFlow) {
-               Integer stackSize = executionStack.getStackSize();
-               if (log.isTraceEnabled())
-                       log.debug(depthSpaces(stackSize) + symbol + executionFlow + " #"
-                                       + executionStack.getCurrentStackLevelUuid() + ", depth="
-                                       + stackSize);
-               if (log.isDebugEnabled())
-                       log.debug(depthSpaces(stackSize) + symbol + executionFlow);
-       }
-
-       protected void logRunnableExecution(ExecutionFlow executionFlow,
-                       Runnable runnable) {
-               Integer stackSize = executionStack.getStackSize();
-               if (log.isDebugEnabled())
-                       log.debug(depthSpaces(stackSize + 1)
-                                       + runnable.getClass().getSimpleName() + " in "
-                                       + executionFlow);
-       }
-
-       private String depthSpaces(int depth) {
-               StringBuffer buf = new StringBuffer(depth * 2);
-               for (int i = 0; i < depth; i++)
-                       buf.append("  ");
-               return buf.toString();
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionParameterPostProcessor.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionParameterPostProcessor.java
deleted file mode 100644 (file)
index 84c932e..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution;\r
-\r
-import java.beans.PropertyDescriptor;\r
-import java.util.HashSet;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.execution.ExecutionContext;\r
-import org.argeo.slc.execution.ExecutionFlow;\r
-import org.springframework.beans.BeansException;\r
-import org.springframework.beans.MutablePropertyValues;\r
-import org.springframework.beans.PropertyValue;\r
-import org.springframework.beans.PropertyValues;\r
-import org.springframework.beans.factory.BeanDefinitionStoreException;\r
-import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;\r
-import org.springframework.beans.factory.config.TypedStringValue;\r
-import org.springframework.beans.factory.support.ManagedList;\r
-import org.springframework.beans.factory.support.ManagedMap;\r
-import org.springframework.beans.factory.support.ManagedSet;\r
-import org.springframework.util.ObjectUtils;\r
-import org.springframework.util.StringUtils;\r
-\r
-/**\r
- * Spring post processor which ensures that execution parameters are properly\r
- * set. It is used at two levels: first during instantiation for instantiation\r
- * parameters which allow to implement templates, then at runtime in order to\r
- * interpret @{} placeholders when object of scope execution are instantiated.\r
- */\r
-public class ExecutionParameterPostProcessor extends\r
-               InstantiationAwareBeanPostProcessorAdapter {\r
-\r
-       private final static Log log = LogFactory\r
-                       .getLog(ExecutionParameterPostProcessor.class);\r
-\r
-       private ExecutionContext executionContext;\r
-       private InstantiationManager instantiationManager;\r
-\r
-       private String placeholderPrefix = "@{";\r
-       private String placeholderSuffix = "}";\r
-       private String nullValue;\r
-\r
-       @Override\r
-       public PropertyValues postProcessPropertyValues(PropertyValues pvs,\r
-                       PropertyDescriptor[] pds, Object bean, String beanName)\r
-                       throws BeansException {\r
-\r
-               // TODO: resolve at execution only if scope is execution\r
-               // TODO: deal with placeholders in RuntimeBeanReference and\r
-               // RuntimeBeanNameReference\r
-\r
-               MutablePropertyValues newPvs = new MutablePropertyValues();\r
-\r
-               boolean changesOccured = false;\r
-\r
-               for (PropertyValue pv : pvs.getPropertyValues()) {\r
-                       Object convertedValue = resolveValue(beanName, bean, pv.getValue());\r
-                       newPvs.addPropertyValue(new PropertyValue(pv, convertedValue));\r
-                       if (convertedValue != pv.getValue()) {\r
-                               changesOccured = true;\r
-                       }\r
-               }\r
-\r
-               return changesOccured ? newPvs : pvs;\r
-       }\r
-\r
-       @Override\r
-       public boolean postProcessAfterInstantiation(Object bean, String beanName)\r
-                       throws BeansException {\r
-               if (bean instanceof ExecutionFlow)\r
-                       instantiationManager.flowInitializationStarted(\r
-                                       (ExecutionFlow) bean, beanName);\r
-               return true;\r
-       }\r
-\r
-       @Override\r
-       public Object postProcessAfterInitialization(Object bean, String beanName)\r
-                       throws BeansException {\r
-               if (bean instanceof ExecutionFlow)\r
-                       instantiationManager.flowInitializationFinished(\r
-                                       (ExecutionFlow) bean, beanName);\r
-               return bean;\r
-       }\r
-\r
-       protected String resolvePlaceholder(Object bean, String placeholder) {\r
-               if (instantiationManager.isInFlowInitialization())\r
-                       return instantiationManager.getInitializingFlowParameter(\r
-                                       placeholder).toString();\r
-\r
-               else {// execution\r
-                               // next call fail if no execution context available\r
-                       Object obj = executionContext.getVariable(placeholder);\r
-                       if (obj != null) {\r
-                               return obj.toString();\r
-                       }\r
-               }\r
-\r
-               return null;\r
-       }\r
-\r
-       public Object resolveValue(String beanName, Object bean, Object value) {\r
-               if (value instanceof TypedStringValue) {\r
-                       TypedStringValue tsv = (TypedStringValue) value;\r
-                       String originalValue = tsv.getValue();\r
-\r
-                       String convertedValue = resolveString(beanName, bean, originalValue);\r
-                       if (convertedValue == null)\r
-                               return null;\r
-                       return convertedValue.equals(originalValue) ? value\r
-                                       : new TypedStringValue(convertedValue);\r
-               } else if (value instanceof String) {\r
-                       String originalValue = value.toString();\r
-                       String convertedValue = resolveString(beanName, bean, originalValue);\r
-                       if (convertedValue == null)\r
-                               return null;\r
-                       return convertedValue.equals(originalValue) ? value\r
-                                       : convertedValue;\r
-               } else if (value instanceof ManagedMap) {\r
-                       Map<?, ?> mapVal = (Map<?, ?>) value;\r
-\r
-                       Map<Object, Object> newContent = new ManagedMap<Object, Object>();\r
-                       boolean entriesModified = false;\r
-                       for (Iterator<?> it = mapVal.entrySet().iterator(); it.hasNext();) {\r
-                               Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next();\r
-                               Object key = entry.getKey();\r
-                               int keyHash = (key != null ? key.hashCode() : 0);\r
-                               Object newKey = resolveValue(beanName, bean, key);\r
-                               int newKeyHash = (newKey != null ? newKey.hashCode() : 0);\r
-                               Object val = entry.getValue();\r
-                               Object newVal = resolveValue(beanName, bean, val);\r
-                               newContent.put(newKey, newVal);\r
-                               entriesModified = entriesModified\r
-                                               || (newVal != val || newKey != key || newKeyHash != keyHash);\r
-                       }\r
-\r
-                       return entriesModified ? newContent : value;\r
-               } else if (value instanceof ManagedList) {\r
-                       List<?> listVal = (List<?>) value;\r
-                       List<Object> newContent = new ManagedList<Object>();\r
-                       boolean valueModified = false;\r
-\r
-                       for (int i = 0; i < listVal.size(); i++) {\r
-                               Object elem = listVal.get(i);\r
-                               Object newVal = resolveValue(beanName, bean, elem);\r
-                               newContent.add(newVal);\r
-                               if (!ObjectUtils.nullSafeEquals(newVal, elem)) {\r
-                                       valueModified = true;\r
-                               }\r
-                       }\r
-                       return valueModified ? newContent : value;\r
-               } else if (value instanceof ManagedSet) {\r
-                       Set<?> setVal = (Set<?>) value;\r
-                       Set<Object> newContent = new ManagedSet<Object>();\r
-                       boolean entriesModified = false;\r
-                       for (Iterator<?> it = setVal.iterator(); it.hasNext();) {\r
-                               Object elem = it.next();\r
-                               int elemHash = (elem != null ? elem.hashCode() : 0);\r
-                               Object newVal = resolveValue(beanName, bean, elem);\r
-                               int newValHash = (newVal != null ? newVal.hashCode() : 0);\r
-                               newContent.add(newVal);\r
-                               entriesModified = entriesModified\r
-                                               || (newVal != elem || newValHash != elemHash);\r
-                       }\r
-                       return entriesModified ? newContent : value;\r
-               } else {\r
-                       // log.debug(beanName + ": " + value.getClass() + " : " + value);\r
-                       return value;\r
-               }\r
-\r
-       }\r
-\r
-       private String resolveString(String beanName, Object bean, String strVal) {\r
-               // in case <null/> is passed\r
-               if (strVal == null)\r
-                       return null;\r
-\r
-               String value = parseStringValue(bean, strVal, new HashSet<String>());\r
-\r
-               if (value == null)\r
-                       throw new SlcException("Could not resolve placeholder '" + strVal\r
-                                       + "' in bean '" + beanName + "'");\r
-\r
-               return (value.equals(nullValue) ? null : value);\r
-       }\r
-\r
-       public void setPlaceholderPrefix(String placeholderPrefix) {\r
-               this.placeholderPrefix = placeholderPrefix;\r
-       }\r
-\r
-       public void setPlaceholderSuffix(String placeholderSuffix) {\r
-               this.placeholderSuffix = placeholderSuffix;\r
-       }\r
-\r
-       public void setNullValue(String nullValue) {\r
-               this.nullValue = nullValue;\r
-       }\r
-\r
-       public void setInstantiationManager(\r
-                       InstantiationManager instantiationManager) {\r
-               this.instantiationManager = instantiationManager;\r
-       }\r
-\r
-       public void setExecutionContext(ExecutionContext executionContext) {\r
-               this.executionContext = executionContext;\r
-       }\r
-\r
-       //\r
-       // Following methods hacked from the internals of\r
-       // PropertyPlaceholderConfigurer\r
-       //\r
-\r
-       protected String parseStringValue(Object bean, String strVal,\r
-                       Set<String> visitedPlaceholders)\r
-                       throws BeanDefinitionStoreException {\r
-\r
-               // in case <null/> is passed\r
-               if (strVal == null)\r
-                       return null;\r
-\r
-               StringBuffer buf = new StringBuffer(strVal);\r
-\r
-               int startIndex = strVal.indexOf(placeholderPrefix);\r
-               while (startIndex != -1) {\r
-                       int endIndex = findPlaceholderEndIndex(buf, startIndex);\r
-                       if (endIndex != -1) {\r
-                               String placeholder = buf.substring(startIndex\r
-                                               + placeholderPrefix.length(), endIndex);\r
-                               if (!visitedPlaceholders.add(placeholder)) {\r
-                                       throw new BeanDefinitionStoreException(\r
-                                                       "Circular placeholder reference '" + placeholder\r
-                                                                       + "' in property definitions");\r
-                               }\r
-                               // Recursive invocation, parsing placeholders contained in\r
-                               // the placeholder key.\r
-                               placeholder = parseStringValue(bean, placeholder,\r
-                                               visitedPlaceholders);\r
-                               // Now obtain the value for the fully resolved key...\r
-                               String propVal = resolvePlaceholder(bean, placeholder);\r
-                               if (propVal != null) {\r
-                                       // Recursive invocation, parsing placeholders contained\r
-                                       // in the\r
-                                       // previously resolved placeholder value.\r
-                                       propVal = parseStringValue(bean, propVal,\r
-                                                       visitedPlaceholders);\r
-                                       buf.replace(startIndex,\r
-                                                       endIndex + placeholderSuffix.length(), propVal);\r
-                                       if (log.isTraceEnabled()) {\r
-                                               log.trace("Resolved placeholder '" + placeholder + "'");\r
-                                       }\r
-                                       startIndex = buf.indexOf(placeholderPrefix, startIndex\r
-                                                       + propVal.length());\r
-                               } else {\r
-                                       throw new BeanDefinitionStoreException(\r
-                                                       "Could not resolve placeholder '" + placeholder\r
-                                                                       + "'");\r
-                               }\r
-                               visitedPlaceholders.remove(placeholder);\r
-                       } else {\r
-                               startIndex = -1;\r
-                       }\r
-               }\r
-\r
-               return buf.toString();\r
-       }\r
-\r
-       private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {\r
-               int index = startIndex + placeholderPrefix.length();\r
-               int withinNestedPlaceholder = 0;\r
-               while (index < buf.length()) {\r
-                       if (StringUtils.substringMatch(buf, index, placeholderSuffix)) {\r
-                               if (withinNestedPlaceholder > 0) {\r
-                                       withinNestedPlaceholder--;\r
-                                       index = index + placeholderSuffix.length();\r
-                               } else {\r
-                                       return index;\r
-                               }\r
-                       } else if (StringUtils\r
-                                       .substringMatch(buf, index, placeholderPrefix)) {\r
-                               withinNestedPlaceholder++;\r
-                               index = index + placeholderPrefix.length();\r
-                       } else {\r
-                               index++;\r
-                       }\r
-               }\r
-               return -1;\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionResources.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionResources.java
deleted file mode 100644 (file)
index 759a125..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-
-import org.springframework.core.io.Resource;
-
-/** Provides write access to resources during execution */
-public interface ExecutionResources {
-       /** The base directory where this execution can write */
-       public File getWritableBaseDir();
-
-       /** Allocates a local file in the writable area and return it as a resource. */
-       public Resource getWritableResource(String relativePath);
-
-       /**
-        * Allocates a local file in the writable area and return it as a fully
-        * qualified OS path.
-        */
-       public String getWritableOsPath(String relativePath);
-
-       /**
-        * Allocates a local file in the writable area and return it as a
-        * {@link File}.
-        */
-       public File getWritableOsFile(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/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionResourcesFactoryBean.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionResourcesFactoryBean.java
deleted file mode 100644 (file)
index 0b887da..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.core.io.Resource;
-import org.springframework.util.Assert;
-
-/** Workaround when execution placedholders needs to be passed. */
-public class ExecutionResourcesFactoryBean implements FactoryBean<Resource> {
-       private ExecutionResources executionResources;
-       private String relativePath;
-
-       public Resource getObject() throws Exception {
-               Assert.notNull(executionResources, "executionResources is null");
-               Assert.notNull(relativePath, "relativePath is null");
-               return executionResources.getWritableResource(relativePath);
-       }
-
-       public Class<? extends Object> getObjectType() {
-               return Resource.class;
-       }
-
-       public boolean isSingleton() {
-               return true;
-       }
-
-       public void setExecutionResources(ExecutionResources executionResources) {
-               this.executionResources = executionResources;
-       }
-
-       public void setRelativePath(String relativePath) {
-               this.relativePath = relativePath;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionScope.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionScope.java
deleted file mode 100644 (file)
index 4ac0de2..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-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.execution.ExecutionContext;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionStack;
-import org.springframework.beans.factory.ObjectFactory;
-import org.springframework.beans.factory.config.Scope;
-
-/**
- * When Spring beans are instantiated with this scope, the same instance is
- * reused across an execution.
- */
-public class ExecutionScope implements Scope {
-       private final static Log log = LogFactory.getLog(ExecutionScope.class);
-
-       private final ThreadLocal<ExecutionStack> executionStack = new ThreadLocal<ExecutionStack>();
-       public final ThreadLocal<String> executionStackBeanName = new ThreadLocal<String>();
-
-       private final ThreadLocal<ExecutionContext> executionContext = new ThreadLocal<ExecutionContext>();
-       private final ThreadLocal<String> executionContextBeanName = new ThreadLocal<String>();
-
-       public Object get(String name, ObjectFactory<?> objectFactory) {
-               if (log.isTraceEnabled())
-                       log.debug("Get execution scoped bean " + name);
-
-               // shortcuts
-               if (executionStackBeanName.get() != null
-                               && name.equals(executionStackBeanName.get())) {
-                       return executionStack.get();
-               }
-
-               if (executionContextBeanName.get() != null
-                               && name.equals(executionContextBeanName.get())) {
-                       return executionContext.get();
-               }
-
-               // execution context must be defined first
-               if (executionContext.get() == null) {
-                       Object obj = objectFactory.getObject();
-                       if (obj instanceof ExecutionContext) {
-                               return dealWithSpecialScopedObject(name, executionContext,
-                                               executionContextBeanName, (ExecutionContext) obj);
-                       } else {
-                               // TODO: use execution context wrapper
-                               throw new SlcException("No execution context has been defined.");
-                       }
-               }
-
-               // for other scoped objects, an executions stack must be available
-               if (executionStack.get() == null) {
-                       Object obj = objectFactory.getObject();
-                       if (obj instanceof ExecutionStack) {
-                               return dealWithSpecialScopedObject(name, executionStack,
-                                               executionStackBeanName, (ExecutionStack) obj);
-                       } else {
-                               throw new SlcException("No execution stack has been defined.");
-                       }
-               }
-
-               // see if the execution stack already knows the object
-               Object obj = executionStack.get().findScopedObject(name);
-               if (obj == null) {
-                       obj = objectFactory.getObject();
-                       if (obj instanceof ExecutionContext)
-                               throw new SlcException(
-                                               "Only one execution context can be defined per thread");
-                       if (obj instanceof ExecutionStack)
-                               throw new SlcException(
-                                               "Only one execution stack can be defined per thread");
-
-                       checkForbiddenClasses(obj);
-
-                       executionStack.get().addScopedObject(name, obj);
-               }
-               return obj;
-
-       }
-
-       protected <T> T dealWithSpecialScopedObject(String name,
-                       ThreadLocal<T> threadLocal,
-                       ThreadLocal<String> threadLocalBeanName, T newObj) {
-
-               T obj = threadLocal.get();
-               if (obj == null) {
-                       obj = newObj;
-                       threadLocal.set(obj);
-                       threadLocalBeanName.set(name);
-                       if (log.isTraceEnabled()) {
-                               log.debug(obj.getClass() + " instantiated. (beanName=" + name
-                                               + ")");
-                       }
-                       return obj;
-               } else {
-                       throw new SlcException("Only one scoped " + obj.getClass()
-                                       + " can be defined per thread");
-               }
-
-       }
-
-       protected void checkForbiddenClasses(Object obj) {
-               Class<?> clss = obj.getClass();
-               if (ExecutionFlow.class.isAssignableFrom(clss)
-                               || ExecutionSpec.class.isAssignableFrom(clss)) {
-                       throw new UnsupportedException("Execution scoped object", clss);
-               }
-       }
-
-       public String getConversationId() {
-               // TODO: is it the most relevant?
-               return executionContext.get().getUuid();
-       }
-
-       public void registerDestructionCallback(String name, Runnable callback) {
-               if (Thread.currentThread() instanceof ExecutionThread) {
-                       ExecutionThread executionThread = (ExecutionThread) Thread
-                                       .currentThread();
-                       executionThread.registerDestructionCallback(name, callback);
-               }
-       }
-
-       public Object remove(String name) {
-               if (log.isDebugEnabled())
-                       log.debug("Remove object " + name);
-               throw new UnsupportedOperationException();
-       }
-
-       public Object resolveContextualObject(String key) {
-               return executionContext.get().getVariable(key);
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionThread.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/ExecutionThread.java
deleted file mode 100644 (file)
index 31e952d..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.security.auth.Subject;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionFlowDescriptor;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.ExecutionStep;
-import org.argeo.slc.execution.RealizedFlow;
-
-/** Thread of a single execution */
-public class ExecutionThread extends Thread {
-       public final static String SYSPROP_EXECUTION_AUTO_UPGRADE = "slc.execution.autoupgrade";
-       private final static Log log = LogFactory.getLog(ExecutionThread.class);
-
-       private ExecutionModulesManager executionModulesManager;
-       private final RealizedFlow realizedFlow;
-       private final AccessControlContext accessControlContext;
-
-       private List<Runnable> destructionCallbacks = new ArrayList<Runnable>();
-
-       public ExecutionThread(ProcessThreadGroup processThreadGroup, ExecutionModulesManager executionModulesManager,
-                       RealizedFlow realizedFlow) {
-               super(processThreadGroup, "Flow " + realizedFlow.getFlowDescriptor().getName());
-               this.realizedFlow = realizedFlow;
-               this.executionModulesManager = executionModulesManager;
-               accessControlContext = AccessController.getContext();
-       }
-
-       public void run() {
-               // authenticate thread
-               // Authentication authentication = getProcessThreadGroup()
-               // .getAuthentication();
-               // if (authentication == null)
-               // throw new SlcException("Can only execute authenticated threads");
-               // SecurityContextHolder.getContext().setAuthentication(authentication);
-
-               // Retrieve execution flow descriptor
-               ExecutionFlowDescriptor executionFlowDescriptor = realizedFlow.getFlowDescriptor();
-               String flowName = executionFlowDescriptor.getName();
-
-               getProcessThreadGroup().dispatchAddStep(
-                               new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.PHASE_START, "Flow " + flowName));
-
-               try {
-                       Subject subject = Subject.getSubject(accessControlContext);
-                       try {
-                               Subject.doAs(subject, new PrivilegedExceptionAction<Void>() {
-
-                                       @Override
-                                       public Void run() throws Exception {
-                                               String autoUpgrade = System.getProperty(SYSPROP_EXECUTION_AUTO_UPGRADE);
-                                               if (autoUpgrade != null && autoUpgrade.equals("true"))
-                                                       executionModulesManager.upgrade(realizedFlow.getModuleNameVersion());
-                                               executionModulesManager.start(realizedFlow.getModuleNameVersion());
-                                               //
-                                               // START FLOW
-                                               //
-                                               executionModulesManager.execute(realizedFlow);
-                                               // END FLOW
-                                               return null;
-                                       }
-
-                               });
-                       } catch (PrivilegedActionException privilegedActionException) {
-                               throw (Exception) privilegedActionException.getCause();
-                       }
-               } catch (FlowConfigurationException e) {
-                       String msg = "Configuration problem with flow " + flowName + ":\n" + e.getMessage();
-                       log.error(msg);
-                       getProcessThreadGroup().dispatchAddStep(
-                                       new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.ERROR, msg + " " + e.getMessage()));
-               } catch (Exception e) {
-                       // TODO: re-throw exception ?
-                       String msg = "Execution of flow " + flowName + " failed.";
-                       log.error(msg, e);
-                       getProcessThreadGroup().dispatchAddStep(
-                                       new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.ERROR, msg + " " + e.getMessage()));
-               } finally {
-                       getProcessThreadGroup().dispatchAddStep(
-                                       new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.PHASE_END, "Flow " + flowName));
-                       processDestructionCallbacks();
-               }
-       }
-
-       private synchronized void processDestructionCallbacks() {
-               for (int i = destructionCallbacks.size() - 1; i >= 0; i--) {
-                       try {
-                               destructionCallbacks.get(i).run();
-                       } catch (Exception e) {
-                               log.warn("Could not process destruction callback " + i + " in thread " + getName(), e);
-                       }
-               }
-       }
-
-       /**
-        * Gather object destruction callback to be called in reverse order at the
-        * end of the thread
-        */
-       synchronized void registerDestructionCallback(String name, Runnable callback) {
-               destructionCallbacks.add(callback);
-       }
-
-       protected ProcessThreadGroup getProcessThreadGroup() {
-               return (ProcessThreadGroup) getThreadGroup();
-       }
-}
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/FileExecutionResources.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/FileExecutionResources.java
deleted file mode 100644 (file)
index d225cd1..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionContext;
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.core.io.Resource;
-import org.springframework.util.Assert;
-
-/** Implements write access to resources based on standard Java {@link File} */
-public class FileExecutionResources implements ExecutionResources {
-       private final static Log log = LogFactory
-                       .getLog(FileExecutionResources.class);
-       protected final static String DEFAULT_EXECUTION_RESOURCES_DIRNAME = "executionResources";
-       public final static String DEFAULT_EXECUTION_RESOURCES_TMP_PATH = System
-                       .getProperty("java.io.tmpdir")
-                       + File.separator
-                       + System.getProperty("user.name")
-                       + File.separator
-                       + "slc"
-                       + File.separator + DEFAULT_EXECUTION_RESOURCES_DIRNAME;
-
-       private File baseDir;
-       private ExecutionContext executionContext;
-       private String prefixDatePattern = "yyMMdd_HHmmss_SSS";
-       private SimpleDateFormat sdf = null;
-
-       private Boolean withExecutionSubdirectory = true;
-
-       public FileExecutionResources() {
-               // Default base directory
-               String osgiInstanceArea = System.getProperty("osgi.instance.area");
-               String osgiInstanceAreaDefault = System
-                               .getProperty("osgi.instance.area.default");
-
-               if (osgiInstanceArea != null) {
-                       // within OSGi with -data specified
-                       osgiInstanceArea = removeFilePrefix(osgiInstanceArea);
-                       baseDir = new File(osgiInstanceArea + File.separator
-                                       + DEFAULT_EXECUTION_RESOURCES_DIRNAME);
-               } else if (osgiInstanceAreaDefault != null) {
-                       // within OSGi without -data specified
-                       osgiInstanceAreaDefault = removeFilePrefix(osgiInstanceAreaDefault);
-                       baseDir = new File(osgiInstanceAreaDefault + File.separator
-                                       + DEFAULT_EXECUTION_RESOURCES_DIRNAME);
-               } else {// outside OSGi
-                       baseDir = new File(DEFAULT_EXECUTION_RESOURCES_TMP_PATH);
-               }
-       }
-
-       protected SimpleDateFormat sdf() {
-               // Lazy init in case prefix has been externally set
-               if (sdf == null)
-                       sdf = new SimpleDateFormat(prefixDatePattern);
-               return sdf;
-       }
-
-       public Resource getWritableResource(String relativePath) {
-               File file = getFile(relativePath);
-               File parentDir = file.getParentFile();
-
-               if (!parentDir.exists()) {
-                       // Creates if necessary
-                       if (log.isTraceEnabled())
-                               log.trace("Creating parent directory " + parentDir);
-                       parentDir.mkdirs();
-               }
-               Resource resource = new FileSystemResource(file);
-
-               if (log.isTraceEnabled())
-                       log.trace("Returns writable resource " + resource);
-               return resource;
-       }
-
-       public String getWritableOsPath(String relativePath) {
-               try {
-                       return getFile(relativePath).getCanonicalPath();
-               } catch (IOException e) {
-                       throw new SlcException("Cannot find canonical path", e);
-               }
-       }
-
-       public File getWritableOsFile(String relativePath) {
-               return getFile(relativePath);
-       }
-
-       public String getAsOsPath(Resource resource, Boolean overwrite) {
-               File file = fileFromResource(resource);
-               if (file != null)
-                       try {
-                               if (log.isTraceEnabled())
-                                       log.debug("Directly interpret " + resource + " as OS file "
-                                                       + file);
-                               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;
-               try {
-                       String path = resource.getURL().getPath();
-                       file = getFile(path);
-                       if (file.exists() && !overwrite)
-                               return file.getCanonicalPath();
-
-                       file.getParentFile().mkdirs();
-                       in = resource.getInputStream();
-                       out = new FileOutputStream(file);
-                       IOUtils.copy(in, out);
-                       if (log.isDebugEnabled())
-                               log.debug("Retrieved " + resource + " to OS file " + file);
-                       return file.getCanonicalPath();
-               } catch (IOException e) {
-                       throw new SlcException("Could not make resource " + resource
-                                       + " an OS file.", e);
-               } finally {
-                       IOUtils.closeQuietly(in);
-                       IOUtils.closeQuietly(out);
-               }
-       }
-
-       /**
-        * 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;
-               }
-
-       }
-
-       protected File getFile(String relativePath) {
-               File writableBaseDir = getWritableBaseDir();
-               return new File(writableBaseDir.getPath() + File.separator
-                               + relativePath.replace('/', File.separatorChar));
-       }
-
-       public File getWritableBaseDir() {
-               if (withExecutionSubdirectory) {
-                       Date executionContextCreationDate = (Date) executionContext
-                                       .getVariable(ExecutionContext.VAR_EXECUTION_CONTEXT_CREATION_DATE);
-                       Assert.notNull(executionContext, "execution context is null");
-                       String path = baseDir.getPath() + File.separator
-                                       + sdf().format(executionContextCreationDate);
-                       // TODO write execution id somewhere? like in a txt file
-                       return new File(path);
-               } else {
-                       return baseDir;
-               }
-       }
-
-       protected String removeFilePrefix(String url) {
-               if (url.startsWith("file:"))
-                       return url.substring("file:".length());
-               else if (url.startsWith("reference:file:"))
-                       return url.substring("reference:file:".length());
-               else
-                       return url;
-       }
-
-       public void setBaseDir(File baseDir) {
-               this.baseDir = baseDir;
-       }
-
-       public void setExecutionContext(ExecutionContext executionContext) {
-               this.executionContext = executionContext;
-       }
-
-       public void setPrefixDatePattern(String prefixDatePattern) {
-               this.prefixDatePattern = prefixDatePattern;
-       }
-
-       public File getBaseDir() {
-               return baseDir;
-       }
-
-       public ExecutionContext getExecutionContext() {
-               return executionContext;
-       }
-
-       public String getPrefixDatePattern() {
-               return prefixDatePattern;
-       }
-
-       /** Default is true. */
-       public void setWithExecutionSubdirectory(Boolean withExecutionSubdirectory) {
-               this.withExecutionSubdirectory = withExecutionSubdirectory;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/FlowConfigurationException.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/FlowConfigurationException.java
deleted file mode 100644 (file)
index aeda5ac..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.argeo.slc.core.execution;
-
-import org.argeo.slc.SlcException;
-
-/** The stack trace of such exceptions does not need to be displayed */
-public class FlowConfigurationException extends SlcException {
-       private static final long serialVersionUID = 8456260596346797321L;
-
-       public FlowConfigurationException(String message) {
-               super(message);
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/InstantiationManager.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/InstantiationManager.java
deleted file mode 100644 (file)
index 60e93ec..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution;\r
-\r
-import java.util.Stack;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.execution.ExecutionFlow;\r
-import org.argeo.slc.execution.ExecutionSpecAttribute;\r
-\r
-/** Manage parameters that need to be set during the instantiation of a flow */\r
-public class InstantiationManager {\r
-\r
-       private final static Log log = LogFactory\r
-                       .getLog(InstantiationManager.class);\r
-\r
-       private ThreadLocal<Stack<ExecutionFlow>> flowStack = new ThreadLocal<Stack<ExecutionFlow>>();\r
-\r
-       public Object createRef(String name) {\r
-\r
-               if ((flowStack.get() == null) || flowStack.get().empty()) {\r
-                       throw new SlcException("No flow is currently initializing."\r
-                                       + " Declare ParameterRef as inner beans or prototypes.");\r
-               }\r
-\r
-               return getInitializingFlowParameter(name);\r
-       }\r
-\r
-       public void flowInitializationStarted(ExecutionFlow flow, String flowName) {\r
-               // set the flow name if it is DefaultExecutionFlow\r
-               if (flow instanceof DefaultExecutionFlow) {\r
-                       ((DefaultExecutionFlow) flow).setBeanName(flowName);\r
-               }\r
-\r
-               if (log.isTraceEnabled())\r
-                       log.trace("Start initialization of " + flow.hashCode() + " ("\r
-                                       + flow + " - " + flow.getClass() + ")");\r
-\r
-               // log.info("# flowInitializationStarted " + flowName);\r
-               // create a stack for this thread if there is none\r
-               if (flowStack.get() == null) {\r
-                       flowStack.set(new Stack<ExecutionFlow>());\r
-               }\r
-               flowStack.get().push(flow);\r
-       }\r
-\r
-       public void flowInitializationFinished(ExecutionFlow flow, String flowName) {\r
-               if (log.isTraceEnabled())\r
-                       log.trace("Finish initialization of " + flow.hashCode() + " ("\r
-                                       + flow + " - " + flow.getClass() + ")");\r
-\r
-               if (flowStack.get() != null) {\r
-                       ExecutionFlow registeredFlow = flowStack.get().pop();\r
-                       if (registeredFlow != null) {\r
-                               if (!flow.getName().equals(registeredFlow.getName()))\r
-                                       throw new SlcException("Current flow is " + flow);\r
-                               // log.info("# flowInitializationFinished " + flowName);\r
-                               // initializingFlow.set(null);\r
-                       }\r
-               } else {\r
-                       // happens for flows imported as services\r
-                       log.warn("flowInitializationFinished - Flow Stack is null");\r
-               }\r
-       }\r
-\r
-       protected ExecutionFlow findInitializingFlowWithParameter(String key) {\r
-               if ((flowStack.get() == null) || flowStack.get().empty())\r
-                       throw new SlcException("No initializing flow available.");\r
-\r
-               // first look in the outer flow (that may override parameters)\r
-               for (int i = 0; i < flowStack.get().size(); i++) {\r
-                       if (flowStack.get().elementAt(i).isSetAsParameter(key)) {\r
-                               return flowStack.get().elementAt(i);\r
-                       }\r
-               }\r
-               throw new SlcException("Key " + key + " is not set as parameter in "\r
-                               + flowStack.get().firstElement().toString() + " (stack size="\r
-                               + flowStack.get().size() + ")");\r
-\r
-       }\r
-\r
-       public Object getInitializingFlowParameter(String key) {\r
-               return findInitializingFlowWithParameter(key).getParameter(key);\r
-       }\r
-\r
-       public Class<?> getInitializingFlowParameterClass(String key) {\r
-               ExecutionSpecAttribute attr = findInitializingFlowWithParameter(key)\r
-                               .getExecutionSpec().getAttributes().get(key);\r
-               if (attr instanceof RefSpecAttribute)\r
-                       return ((RefSpecAttribute) attr).getTargetClass();\r
-               else if (attr instanceof PrimitiveSpecAttribute) {\r
-                       String type = ((PrimitiveSpecAttribute) attr).getType();\r
-                       Class<?> clss = PrimitiveUtils.typeAsClass(type);\r
-                       if (clss == null)\r
-                               throw new SlcException("Cannot convert type " + type\r
-                                               + " to class.");\r
-                       return clss;\r
-               } else\r
-                       return null;\r
-       }\r
-\r
-       public Boolean isInFlowInitialization() {\r
-               return (flowStack.get() != null) && !flowStack.get().empty();\r
-       }\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/MapExecutionContext.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/MapExecutionContext.java
deleted file mode 100644 (file)
index 324f973..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionContext;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionStack;
-import org.springframework.beans.BeanWrapper;
-import org.springframework.beans.BeanWrapperImpl;
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-
-public class MapExecutionContext implements ExecutionContext,
-               ApplicationContextAware {
-       private final Map<String, Object> variables = Collections
-                       .synchronizedMap(new HashMap<String, Object>());
-
-       private final String uuid;
-
-       private ApplicationContext applicationContext;
-       private ExecutionStack executionStack;
-
-       public MapExecutionContext() {
-               uuid = UUID.randomUUID().toString();
-               variables.put(VAR_EXECUTION_CONTEXT_ID, uuid);
-               variables.put(VAR_EXECUTION_CONTEXT_CREATION_DATE, new Date());
-       }
-
-       public void setVariable(String key, Object value) {
-               // check if we do not refer to a bean
-               int lastInd = key.lastIndexOf('.');
-               if (applicationContext != null && lastInd > 0) {
-                       String beanName = key.substring(0, lastInd);
-                       String propertyName = key.substring(lastInd + 1);
-                       if (applicationContext.containsBean(beanName)) {
-                               BeanWrapper beanWrapper = new BeanWrapperImpl(
-                                               applicationContext.getBean(beanName));
-                               if (!beanWrapper.isWritableProperty(propertyName))
-                                       throw new SlcException("No writable property "
-                                                       + propertyName + " in bean " + beanName);
-                               beanWrapper.setPropertyValue(propertyName, value);
-                       }
-               }
-
-               variables.put(key, value);
-       }
-
-       public Object getVariable(String key) {
-               // check if we do not refer to a bean
-               int lastInd = key.lastIndexOf('.');
-               if (applicationContext != null && lastInd > 0) {
-                       String beanName = key.substring(0, lastInd);
-                       String propertyName = key.substring(lastInd + 1);
-                       if (applicationContext.containsBean(beanName)) {
-                               BeanWrapper beanWrapper = new BeanWrapperImpl(
-                                               applicationContext.getBean(beanName));
-                               if (!beanWrapper.isReadableProperty(propertyName))
-                                       throw new SlcException("No readable property "
-                                                       + propertyName + " in bean " + beanName);
-                               Object obj = beanWrapper.getPropertyValue(propertyName);
-                               return obj;
-                       }
-               }
-
-               Object value = variables.get(key);
-               // try system property in last resort
-               if (value == null)
-                       value = System.getProperty(key);
-
-               // if the variable was not found, look in the stack starting at the
-               // upper flows
-               if (value == null) {
-                       value = executionStack.findLocalVariable(key);
-               }
-               return value;
-       }
-
-       public String getUuid() {
-               return uuid;
-       }
-
-       @Override
-       public void beforeFlow(ExecutionFlow executionFlow) {
-               // getUuid();
-               executionStack.enterFlow(executionFlow);
-               setVariable(ExecutionContext.VAR_FLOW_ID,
-                               executionStack.getCurrentStackLevelUuid());
-               setVariable(ExecutionContext.VAR_FLOW_NAME, executionFlow.getName());
-       }
-
-       @Override
-       public void afterFlow(ExecutionFlow executionFlow) {
-               executionStack.leaveFlow(executionFlow);
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (obj instanceof ExecutionContext)
-                       return uuid.equals(((ExecutionContext) obj).getUuid());
-               return false;
-       }
-
-       @Override
-       public String toString() {
-               return getClass().getSimpleName() + "#" + uuid;
-       }
-
-       public void setApplicationContext(ApplicationContext applicationContext)
-                       throws BeansException {
-               this.applicationContext = applicationContext;
-       }
-
-       public void setExecutionStack(ExecutionStack executionStack) {
-               this.executionStack = executionStack;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/OsFileFactoryBean.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/OsFileFactoryBean.java
deleted file mode 100644 (file)
index e524970..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.core.io.Resource;
-import org.springframework.util.Assert;
-
-/** Retrieve an OS File from the given resource. */
-public class OsFileFactoryBean implements FactoryBean<String> {
-       private ExecutionResources executionResources;
-       private Resource resource;
-       private Boolean overwrite = false;
-
-       /** Return an existing file on the file system. */
-       public String getObject() throws Exception {
-               Assert.notNull(executionResources, "executionResources is null");
-               Assert.notNull(resource, "resource is null");
-               return executionResources.getAsOsPath(resource, overwrite);
-       }
-
-       /** Return {@link Object} because CGLIB is unable to proxy {@link File}. */
-       public Class<? extends Object> getObjectType() {
-               return CharSequence.class;
-       }
-
-       public boolean isSingleton() {
-               return false;
-       }
-
-       /** The execution resources object. */
-       public void setExecutionResources(ExecutionResources executionResources) {
-               this.executionResources = executionResources;
-       }
-
-       /** The resource to access. */
-       public void setResource(Resource resource) {
-               this.resource = resource;
-       }
-
-       /**
-        * Whether to overwrite the resource if it already exists. Default is
-        * <code>false</code>.
-        */
-       public void setOverwrite(Boolean overwrite) {
-               this.overwrite = overwrite;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/ParameterRef.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/ParameterRef.java
deleted file mode 100644 (file)
index 45dd096..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.FactoryBean;
-
-public class ParameterRef implements FactoryBean<Object> {
-       private final static Log log = LogFactory.getLog(ParameterRef.class);
-
-       private InstantiationManager instantiationManager;
-       private String name;
-
-       /** Cached object. */
-       private Object object;
-
-       public ParameterRef() {
-       }
-
-       public ParameterRef(String name) {
-               this.name = name;
-       }
-
-       public Object getObject() throws Exception {
-               if (log.isTraceEnabled())
-                       log.debug("Parameter ref called for " + name);
-
-               if (object == null)
-                       object = instantiationManager.getInitializingFlowParameter(name);
-               return object;
-       }
-
-       public Class<?> getObjectType() {
-               if (object == null)
-                       return instantiationManager.getInitializingFlowParameterClass(name);
-               else
-                       return object.getClass();
-       }
-
-       public boolean isSingleton() {
-               return true;
-       }
-
-       public void setInstantiationManager(
-                       InstantiationManager instantiationManager) {
-               this.instantiationManager = instantiationManager;
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveAccessor.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveAccessor.java
deleted file mode 100644 (file)
index 18d1b98..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-/** Abstraction of access to primitive values */
-public interface PrimitiveAccessor {
-       public final static String TYPE_STRING = "string";
-       /**
-        * As of Argeo 1, passwords are NOT stored encrypted, just hidden in the UI,
-        * but stored in plain text in JCR. Use keyring instead.
-        */
-       public final static String TYPE_PASSWORD = "password";
-       public final static String TYPE_INTEGER = "integer";
-       public final static String TYPE_LONG = "long";
-       public final static String TYPE_FLOAT = "float";
-       public final static String TYPE_DOUBLE = "double";
-       public final static String TYPE_BOOLEAN = "boolean";
-
-       public String getType();
-
-       public Object getValue();
-
-       public void setValue(Object value);
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveSpecAttribute.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveSpecAttribute.java
deleted file mode 100644 (file)
index fe8412c..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.argeo.slc.SlcException;
-
-/**
- * A spec attribute wrapping a primitive value.
- * 
- * @see PrimitiveAccessor
- */
-public class PrimitiveSpecAttribute extends AbstractSpecAttribute implements
-               PrimitiveAccessor {
-       private static final long serialVersionUID = -566676381839825483L;
-       private String type = "string";
-       private Object value = null;
-
-       public PrimitiveSpecAttribute() {
-       }
-
-       public PrimitiveSpecAttribute(String type, Object value) {
-               this.type = type;
-               this.value = value;
-       }
-
-       public Object getValue() {
-               return value;
-       }
-
-       public void setValue(Object value) {
-               this.value = value;
-       }
-
-       public String getType() {
-               return type;
-       }
-
-       public void setType(String type) {
-               // check whether type is recognized.
-               if (PrimitiveUtils.typeAsClass(type) == null)
-                       throw new SlcException("Unrecognized type " + type);
-               this.type = type;
-
-       }
-
-       @Override
-       public String toString() {
-               return "Primitive spec attribute [" + type + "]"
-                               + (value != null ? "=" + value : "");
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveUtils.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveUtils.java
deleted file mode 100644 (file)
index 4268b8b..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-/** Converts to and from primitive types. */
-public class PrimitiveUtils {
-       /**
-        * @deprecated Use {@link PrimitiveAccessor#TYPE_STRING} instead
-        */
-       public final static String TYPE_STRING = PrimitiveAccessor.TYPE_STRING;
-       /**
-        * @deprecated Use {@link PrimitiveAccessor#TYPE_INTEGER} instead
-        */
-       public final static String TYPE_INTEGER = PrimitiveAccessor.TYPE_INTEGER;
-       /**
-        * @deprecated Use {@link PrimitiveAccessor#TYPE_LONG} instead
-        */
-       public final static String TYPE_LONG = PrimitiveAccessor.TYPE_LONG;
-       /**
-        * @deprecated Use {@link PrimitiveAccessor#TYPE_FLOAT} instead
-        */
-       public final static String TYPE_FLOAT = PrimitiveAccessor.TYPE_FLOAT;
-       /**
-        * @deprecated Use {@link PrimitiveAccessor#TYPE_DOUBLE} instead
-        */
-       public final static String TYPE_DOUBLE = PrimitiveAccessor.TYPE_DOUBLE;
-       /**
-        * @deprecated Use {@link PrimitiveAccessor#TYPE_BOOLEAN} instead
-        */
-       public final static String TYPE_BOOLEAN = PrimitiveAccessor.TYPE_BOOLEAN;
-
-       private PrimitiveUtils() {
-
-       }
-
-       /** @return the class or null if the provided type is not a primitive */
-       public static Class<?> typeAsClass(String type) {
-               if (PrimitiveAccessor.TYPE_STRING.equals(type))
-                       return String.class;
-               else if (PrimitiveAccessor.TYPE_PASSWORD.equals(type))
-                       return char[].class;
-               else if (PrimitiveAccessor.TYPE_INTEGER.equals(type))
-                       return Integer.class;
-               else if (PrimitiveAccessor.TYPE_LONG.equals(type))
-                       return Long.class;
-               else if (PrimitiveAccessor.TYPE_FLOAT.equals(type))
-                       return Float.class;
-               else if (PrimitiveAccessor.TYPE_DOUBLE.equals(type))
-                       return Double.class;
-               else if (PrimitiveAccessor.TYPE_BOOLEAN.equals(type))
-                       return Boolean.class;
-               else
-                       return null;
-       }
-
-       /** @return the type or null if the provided class is not a primitive */
-       public static String classAsType(Class<?> clss) {
-               if (String.class.isAssignableFrom(clss))
-                       return PrimitiveAccessor.TYPE_STRING;
-               else if (char[].class.isAssignableFrom(clss))
-                       return PrimitiveAccessor.TYPE_PASSWORD;
-               else if (Integer.class.isAssignableFrom(clss))
-                       return PrimitiveAccessor.TYPE_INTEGER;
-               else if (Long.class.isAssignableFrom(clss))
-                       return PrimitiveAccessor.TYPE_LONG;
-               else if (Float.class.isAssignableFrom(clss))
-                       return PrimitiveAccessor.TYPE_FLOAT;
-               else if (Double.class.isAssignableFrom(clss))
-                       return PrimitiveAccessor.TYPE_DOUBLE;
-               else if (Boolean.class.isAssignableFrom(clss))
-                       return PrimitiveAccessor.TYPE_BOOLEAN;
-               else
-                       return null;
-       }
-
-       /** Parse string as an object. Passwords are returned as String.*/
-       public static Object convert(String type, String str) {
-               if (PrimitiveAccessor.TYPE_STRING.equals(type)) {
-                       return str;
-               } else if (PrimitiveAccessor.TYPE_PASSWORD.equals(type)) {
-                       return str;
-               } else if (PrimitiveAccessor.TYPE_INTEGER.equals(type)) {
-                       return (Integer.parseInt(str));
-               } else if (PrimitiveAccessor.TYPE_LONG.equals(type)) {
-                       return (Long.parseLong(str));
-               } else if (PrimitiveAccessor.TYPE_FLOAT.equals(type)) {
-                       return (Float.parseFloat(str));
-               } else if (PrimitiveAccessor.TYPE_DOUBLE.equals(type)) {
-                       return (Double.parseDouble(str));
-               } else if (PrimitiveAccessor.TYPE_BOOLEAN.equals(type)) {
-                       return (Boolean.parseBoolean(str));
-               } else {
-                       return str;
-               }
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveValue.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/PrimitiveValue.java
deleted file mode 100644 (file)
index 3dedb9c..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-/** Primitive value to be used by an execution. */
-public class PrimitiveValue extends AbstractExecutionValue implements
-               PrimitiveAccessor {
-       private static final long serialVersionUID = 533414290998374166L;
-
-       private String type;
-
-       private Object value;
-
-       public PrimitiveValue() {
-       }
-
-       public PrimitiveValue(String type, Object value) {
-               super();
-               this.type = type;
-               this.value = value;
-       }
-
-       public String getType() {
-               return type;
-       }
-
-       public void setType(String type) {
-               this.type = type;
-       }
-
-       public Object getValue() {
-               return value;
-       }
-
-       public void setValue(Object value) {
-               this.value = value;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/ProcessThread.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/ProcessThread.java
deleted file mode 100644 (file)
index 9267896..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.security.auth.Subject;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.ExecutionProcess;
-import org.argeo.slc.execution.ExecutionStep;
-import org.argeo.slc.execution.RealizedFlow;
-
-/**
- * Main thread coordinating an {@link ExecutionProcess}, launching parallel or
- * sequential {@link ExecutionThread}s.
- */
-public class ProcessThread extends Thread {
-       private final static Log log = LogFactory.getLog(ProcessThread.class);
-
-       private final ExecutionModulesManager executionModulesManager;
-       private final ExecutionProcess process;
-       private final ProcessThreadGroup processThreadGroup;
-
-       private Set<ExecutionThread> executionThreads = Collections.synchronizedSet(new HashSet<ExecutionThread>());
-
-       // private Boolean hadAnError = false;
-       private Boolean killed = false;
-
-       private final AccessControlContext accessControlContext;
-
-       public ProcessThread(ThreadGroup processesThreadGroup, ExecutionModulesManager executionModulesManager,
-                       ExecutionProcess process) {
-               super(processesThreadGroup, "SLC Process #" + process.getUuid());
-               this.executionModulesManager = executionModulesManager;
-               this.process = process;
-               processThreadGroup = new ProcessThreadGroup(process);
-               accessControlContext = AccessController.getContext();
-       }
-
-       public final void run() {
-               // authenticate thread
-               // Authentication authentication = getProcessThreadGroup()
-               // .getAuthentication();
-               // if (authentication == null)
-               // throw new SlcException("Can only execute authenticated threads");
-               // SecurityContextHolder.getContext().setAuthentication(authentication);
-
-               log.info("\n##\n## SLC Process #" + process.getUuid() + " STARTED\n##\n");
-
-               // Start logging
-               new LoggingThread().start();
-
-               process.setStatus(ExecutionProcess.RUNNING);
-               try {
-                       Subject subject = Subject.getSubject(accessControlContext);
-                       try {
-                               Subject.doAs(subject, new PrivilegedExceptionAction<Void>() {
-
-                                       @Override
-                                       public Void run() throws Exception {
-                                               process();
-                                               return null;
-                                       }
-
-                               });
-                       } catch (PrivilegedActionException privilegedActionException) {
-                               Throwable cause = privilegedActionException.getCause();
-                               if (cause instanceof InterruptedException)
-                                       throw (InterruptedException) cause;
-                               else
-                                       throw new SlcException("Cannot process", cause);
-                       }
-                       // process();
-               } catch (InterruptedException e) {
-                       die();
-                       return;
-               } catch (Exception e) {
-                       String msg = "Process " + getProcess().getUuid() + " failed unexpectedly.";
-                       log.error(msg, e);
-                       getProcessThreadGroup()
-                                       .dispatchAddStep(new ExecutionStep("Process", ExecutionStep.ERROR, msg + " " + e.getMessage()));
-               }
-
-               // waits for all execution threads to complete (in case they were
-               // started asynchronously)
-               for (ExecutionThread executionThread : executionThreads) {
-                       if (executionThread.isAlive()) {
-                               try {
-                                       executionThread.join();
-                               } catch (InterruptedException e) {
-                                       die();
-                                       return;
-                               }
-                       }
-               }
-
-               computeFinalStatus();
-       }
-
-       /** Make sure this is called BEFORE all the threads are interrupted. */
-       private void computeFinalStatus() {
-               // String oldStatus = process.getStatus();
-               // TODO: error management at flow level?
-               if (killed)
-                       process.setStatus(ExecutionProcess.KILLED);
-               else if (processThreadGroup.hadAnError())
-                       process.setStatus(ExecutionProcess.ERROR);
-               else
-                       process.setStatus(ExecutionProcess.COMPLETED);
-               // executionModulesManager.dispatchUpdateStatus(process, oldStatus,
-               // process.getStatus());
-               log.info("\n## SLC Process #" + process.getUuid() + " " + process.getStatus() + "\n");
-       }
-
-       /** Called when being killed */
-       private synchronized void die() {
-               killed = true;
-               computeFinalStatus();
-               for (ExecutionThread executionThread : executionThreads) {
-                       try {
-                               executionThread.interrupt();
-                       } catch (Exception e) {
-                               log.error("Cannot interrupt " + executionThread);
-                       }
-               }
-               processThreadGroup.interrupt();
-       }
-
-       /**
-        * Implementation specific execution. To be overridden in order to deal with
-        * custom process types. Default expects an {@link SlcExecution}.
-        */
-       protected void process() throws InterruptedException {
-               List<RealizedFlow> flowsToProcess = new ArrayList<RealizedFlow>();
-               flowsToProcess.addAll(process.getRealizedFlows());
-               while (flowsToProcess.size() > 0) {
-                       RealizedFlow realizedFlow = flowsToProcess.remove(0);
-                       execute(realizedFlow, true);
-               }
-       }
-
-       /** @return the (distinct) thread used for this execution */
-       protected final void execute(RealizedFlow realizedFlow, Boolean synchronous) throws InterruptedException {
-               if (killed)
-                       return;
-
-               ExecutionThread thread = new ExecutionThread(processThreadGroup, executionModulesManager, realizedFlow);
-               executionThreads.add(thread);
-               thread.start();
-
-               if (synchronous)
-                       thread.join();
-
-               return;
-       }
-
-       // public void notifyError() {
-       // hadAnError = true;
-       // }
-       //
-       // public synchronized void flowCompleted() {
-       // // notifyAll();
-       // }
-
-       public ExecutionProcess getProcess() {
-               return process;
-       }
-
-       public ProcessThreadGroup getProcessThreadGroup() {
-               return processThreadGroup;
-       }
-
-       public ExecutionModulesManager getExecutionModulesManager() {
-               return executionModulesManager;
-       }
-
-       private class LoggingThread extends Thread {
-
-               public LoggingThread() {
-                       super("SLC Process Logger #" + process.getUuid());
-               }
-
-               public void run() {
-                       boolean run = true;
-                       while (run) {
-                               List<ExecutionStep> newSteps = new ArrayList<ExecutionStep>();
-                               processThreadGroup.getSteps().drainTo(newSteps);
-                               if (newSteps.size() > 0) {
-                                       // System.out.println(steps.size() + " steps");
-                                       process.addSteps(newSteps);
-                               }
-
-                               try {
-                                       Thread.sleep(1000);
-                               } catch (InterruptedException e) {
-                                       break;
-                               }
-
-                               if (!ProcessThread.this.isAlive() && processThreadGroup.getSteps().size() == 0)
-                                       run = false;
-                       }
-               }
-
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/ProcessThreadGroup.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/ProcessThreadGroup.java
deleted file mode 100644 (file)
index 17dbff8..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-
-import org.argeo.slc.execution.ExecutionProcess;
-import org.argeo.slc.execution.ExecutionStep;
-
-/** The thread group attached to a given {@link SlcExecution}. */
-public class ProcessThreadGroup extends ThreadGroup {
-//     private final Authentication authentication;
-       private final static Integer STEPS_BUFFER_CAPACITY = 5000;
-
-       private BlockingQueue<ExecutionStep> steps = new ArrayBlockingQueue<ExecutionStep>(
-                       STEPS_BUFFER_CAPACITY);
-
-       private Boolean hadAnError = false;
-
-       public ProcessThreadGroup(ExecutionProcess executionProcess) {
-               super("SLC Process #" + executionProcess.getUuid() + " thread group");
-//             this.authentication = SecurityContextHolder.getContext()
-//                             .getAuthentication();
-       }
-
-//     public Authentication getAuthentication() {
-//             return authentication;
-//     }
-
-       public void dispatchAddStep(ExecutionStep step) {
-               // ExecutionProcess slcProcess = processThread.getProcess();
-               // List<ExecutionStep> steps = new ArrayList<ExecutionStep>();
-               // steps.add(step);
-               // TODO clarify why we don't dispatch steps, must be a reason
-               // dispatchAddSteps(steps);
-               // slcProcess.addSteps(steps);
-               if (step.getType().equals(ExecutionStep.ERROR))
-                       hadAnError = true;
-               this.steps.add(step);
-       }
-
-       // public void dispatchAddSteps(List<ExecutionStep> steps) {
-       // ExecutionProcess slcProcess = processThread.getProcess();
-       // executionModulesManager.dispatchAddSteps(slcProcess, steps);
-       // }
-
-       public BlockingQueue<ExecutionStep> getSteps() {
-               return steps;
-       }
-
-       public Boolean hadAnError() {
-               return hadAnError;
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/RefSpecAttribute.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/RefSpecAttribute.java
deleted file mode 100644 (file)
index 8e4f617..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.List;
-
-/** A spec attribute whose value is a reference to a full fledged object. */
-public class RefSpecAttribute extends AbstractSpecAttribute implements
-               Cloneable {
-       private static final long serialVersionUID = -3427797452955753574L;
-       private transient Class<?> targetClass = String.class;
-       /** Read only. */
-       private String targetClassName;
-       private transient Object value = null;
-
-       /** List to be chosen from */
-       private List<RefValueChoice> choices = null;
-
-       public Object getValue() {
-               return value;
-       }
-
-       public void setValue(Object value) {
-               this.value = value;
-       }
-
-       /** Default is {@link String} */
-       public Class<?> getTargetClass() {
-               return targetClass;
-       }
-
-       public void setTargetClass(Class<?> targetClass) {
-               this.targetClass = targetClass;
-               this.targetClassName = targetClass.getName();
-       }
-
-       public String getTargetClassName() {
-               return targetClassName;
-       }
-
-       /** @return can be null */
-       public List<RefValueChoice> getChoices() {
-               return choices;
-       }
-
-       public void setChoices(List<RefValueChoice> choices) {
-               this.choices = choices;
-       }
-
-       @Override
-       protected Object clone() throws CloneNotSupportedException {
-               RefSpecAttribute rsa = new RefSpecAttribute();
-               rsa.setTargetClass(targetClass);
-               rsa.setChoices(choices);
-               return rsa;
-       }
-
-       @Override
-       public String toString() {
-               return "Ref spec attribute [" + targetClass + "]"
-                               + (value != null ? "=" + value : "");
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/RefValue.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/RefValue.java
deleted file mode 100644 (file)
index 0a24bc4..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-/** Reference value to be used by an execution */
-public class RefValue extends AbstractExecutionValue {
-       private static final long serialVersionUID = -8951231456757181687L;
-       private String ref;
-       private String type;
-
-       public RefValue() {
-       }
-
-       public RefValue(String ref) {
-               super();
-               this.ref = ref;
-       }
-
-       public String getRef() {
-               return ref;
-       }
-
-       public void setRef(String ref) {
-               this.ref = ref;
-       }
-
-       public String getType() {
-               return type;
-       }
-
-       public void setType(String type) {
-               this.type = type;
-       }
-
-       @Override
-       public String toString() {
-               return "Ref Value [" + type + "=" + ref + "]";
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/RefValueChoice.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/RefValueChoice.java
deleted file mode 100644 (file)
index 5e1f9c2..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.Serializable;
-
-/** A choice of ref value to be shown to the end user. */
-public class RefValueChoice implements Serializable {
-       private static final long serialVersionUID = -1133645722307507774L;
-       private String name;
-       private String description;
-
-       public RefValueChoice() {
-       }
-
-       public RefValueChoice(String name, String description) {
-               this.name = name;
-               this.description = description;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       public String getDescription() {
-               return description;
-       }
-
-       public void setDescription(String description) {
-               this.description = description;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/SedFilteredResource.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/SedFilteredResource.java
deleted file mode 100644 (file)
index c793f49..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.core.io.ByteArrayResource;
-import org.springframework.core.io.Resource;
-
-/** Experimental and suboptimal */
-public class SedFilteredResource implements FactoryBean<Resource>,
-               InitializingBean {
-       private Resource source;
-
-       private List<String> filters = new ArrayList<String>();
-       private Map<Pattern, String> patterns = new HashMap<Pattern, String>();
-
-       private String charset = "UTF-8";
-       private Charset cs;
-       private CharsetDecoder decoder;
-
-       // private CharsetEncoder encoder;
-
-       public Resource getObject() throws Exception {
-               if (filters.size() == 0)
-                       return source;
-
-               // int capacity = 100 * 1024;// 100 KB
-               ByteBuffer bb;
-               if (source instanceof ByteArrayResource) {
-                       bb = ByteBuffer.wrap(((ByteArrayResource) source).getByteArray());
-               } else {
-                       FileInputStream fis = null;
-                       try {
-                               File file = source.getFile();
-                               fis = new FileInputStream(file);
-                               FileChannel fc = fis.getChannel();
-
-                               // Get the file's size and then map it into memory
-                               int sz = (int) fc.size();
-                               bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
-                       } catch (IOException e) {
-                               // ReadableByteChannel channel = Channels.newChannel(source
-                               // .getInputStream());
-                               // bb = ByteBuffer.allocateDirect(capacity);
-                               // int read = 0;
-                               // do {
-                               // read = channel.read(bb);
-                               // } while (read > 0);
-                               // FIXME : use nio to parse the stream as it goes
-                               bb = ByteBuffer.wrap(IOUtils.toByteArray(source
-                                               .getInputStream()));
-                       } finally {
-                               IOUtils.closeQuietly(fis);
-                       }
-               }
-               CharBuffer cb = decoder.decode(bb);
-               for (Pattern pattern : patterns.keySet()) {
-                       Matcher matcher = pattern.matcher(cb);
-                       String output = matcher.replaceAll(patterns.get(pattern));
-                       cb = CharBuffer.wrap(output);
-               }
-               // ByteBuffer bbout = encoder.encode(cb);
-               // ByteArrayOutputStream out = new ByteArrayOutputStream(capacity);
-               // WritableByteChannel wchannel = Channels.newChannel(out);
-               // wchannel.write(bbout);
-               ByteArrayResource res = new ByteArrayResource(cb.toString().getBytes());
-               return res;
-       }
-
-       public Class<?> getObjectType() {
-               return Resource.class;
-       }
-
-       public boolean isSingleton() {
-               return true;
-       }
-
-       public void afterPropertiesSet() throws Exception {
-               cs = Charset.forName(charset);
-               decoder = cs.newDecoder();
-               // encoder = cs.newEncoder();
-
-               for (String sedStr : filters) {
-                       sedStr = sedStr.trim();
-                       if (sedStr.length() < 4)
-                               throw new SlcException(sedStr + " not properly formatted.");
-                       if (sedStr.charAt(0) != 's')
-                               throw new SlcException(sedStr + " not properly formatted.");
-                       Character sep = sedStr.charAt(1);
-                       List<String> tokens = new ArrayList<String>(4);
-                       StringTokenizer st = new StringTokenizer(sedStr, sep.toString());
-                       while (st.hasMoreTokens())
-                               tokens.add(st.nextToken());
-                       if (tokens.size() != 3 && tokens.size() != 4)
-                               throw new SlcException(sedStr + " not properly formatted.");
-                       patterns.put(Pattern.compile(tokens.get(1)), tokens.get(2));
-               }
-       }
-
-       public void setSource(Resource source) {
-               this.source = source;
-       }
-
-       public void setFilters(List<String> filters) {
-               this.filters = filters;
-       }
-
-       public void setCharset(String charset) {
-               this.charset = charset;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/defaults.xml b/org.argeo.slc.core/src/org/argeo/slc/core/execution/defaults.xml
deleted file mode 100644 (file)
index d84ba10..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (C) 2007-2012 Argeo GmbH
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-            http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
-       <bean id="slcDefault.executionResources" parent="slcTemplate.fileResources"
-               scope="execution" lazy-init="true">
-               <aop:scoped-proxy proxy-target-class="false" />
-               <property name="executionContext" ref="executionContext" />
-       </bean>
-
-       <bean id="slcDefault.writableResource" parent="slcTemplate.writableResource"
-               abstract="true">
-               <property name="executionResources" ref="slcDefault.executionResources" />
-       </bean>
-
-       <bean id="slcDefault.osFile" parent="slcTemplate.osFile" abstract="true">
-               <property name="executionResources" ref="slcDefault.executionResources" />
-       </bean>
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/doc/ConsoleContextDescriber.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/doc/ConsoleContextDescriber.java
deleted file mode 100644 (file)
index 6504a3d..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.doc;
-
-import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.PropertyValue;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-
-public class ConsoleContextDescriber implements ContextDescriber {
-       public void describeContext(BeanDefinitionRegistry registry) {
-               String[] beanNames = registry.getBeanDefinitionNames();
-               for (String beanName : beanNames) {
-                       log("\n## BEAN: " + beanName);
-                       describeBean(registry.getBeanDefinition(beanName));
-               }
-       }
-
-       public void describeBean(BeanDefinition beanDefinition) {
-               log("BeanDefinition class: "+beanDefinition.getClass());
-               log("# ATTRIBUTES");
-               for(String attr:beanDefinition.attributeNames()){
-                       log(attr+"="+beanDefinition.getAttribute(attr));
-               }
-               log("# PROPERTIES");
-               MutablePropertyValues pValues = beanDefinition.getPropertyValues();
-               for (PropertyValue pv : pValues.getPropertyValues()) {
-                       log(pv.getName() + "= (" + pv.getValue().getClass() + ") "
-                                       + pv.getValue());
-               }
-       }
-
-       protected void log(Object obj){
-               System.out.println(obj);
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/doc/ContextDescriber.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/doc/ContextDescriber.java
deleted file mode 100644 (file)
index 713019b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.doc;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-
-public interface ContextDescriber {
-       public void describeContext(BeanDefinitionRegistry registry);
-       public void describeBean(BeanDefinition bd);
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/CompositeRunnableFactory.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/CompositeRunnableFactory.java
deleted file mode 100644 (file)
index f1e80d3..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.Map;\r
-\r
-import org.argeo.slc.SlcException;\r
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
-\r
-/**\r
- * Composite <code>RunnableFactory</code>, redirecting the Runnable \r
- * creation to on of the configured <code>RunnableFactory</code> depending\r
- * on an entry of the data of the <code>RunnableDataNode</code>.\r
- */\r
-public class CompositeRunnableFactory implements RunnableFactory {\r
-\r
-       /**\r
-        * Key used to access factory ID in the data of the <code>RunnableDataNode</code>\r
-        */\r
-       private String factoryKey;\r
-\r
-       /**\r
-        * Maps a factory ID to an ExecutionFlowFactory\r
-        */\r
-       private Map<String, RunnableFactory> factories;\r
-\r
-       public void createAndRegisterRunnable(RunnableDataNode node,\r
-                       BeanDefinitionRegistry beanDefinitionRegistry) {\r
-               findFactory(node).createAndRegisterRunnable(node, beanDefinitionRegistry);\r
-       }       \r
-       \r
-       /**\r
-        * Finds the <code>RunnableFactory</code> to use for a <code>RunnableDataNode</code>\r
-        * @param node\r
-        * @return the <code>RunnableFactory</code> to use for the <code>RunnableDataNode</code>\r
-        */\r
-       private RunnableFactory findFactory(RunnableDataNode node) {\r
-               // get the factory ID from the data of the RunnableDescriptor\r
-               Map<String, Object> data = node.getData();\r
-               if (!data.containsKey(factoryKey)) {\r
-                       throw new SlcException("No data value for key '" + factoryKey + "'");\r
-               }\r
-               String factoryId = data.get(factoryKey).toString();\r
-               \r
-               // see if we have a factory for the factory ID\r
-               if ((factories != null) && factories.containsKey(factoryId)) {\r
-                       return factories.get(factoryId);\r
-               }\r
-               // if not, look for a bean of name equals to the factory ID\r
-               else {\r
-                       throw new SlcException("Not implemented");\r
-               }               \r
-       }\r
-       \r
-       public void setFactoryKey(String factoryKey) {\r
-               this.factoryKey = factoryKey;\r
-       }\r
-\r
-       public void setFactories(Map<String, RunnableFactory> factories) {\r
-               this.factories = factories;\r
-       }\r
-\r
-\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/DefaultRunnableDataNode.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/DefaultRunnableDataNode.java
deleted file mode 100644 (file)
index daed350..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-/**\r
- * Default implementation of <code>RunnableDataNode</code>\r
- *\r
- */\r
-public class DefaultRunnableDataNode implements RunnableDataNode {\r
-\r
-       private List<RunnableDataNode> children = new ArrayList<RunnableDataNode>();\r
-       \r
-       private RunnableDataNode parent;\r
-       \r
-       /**\r
-        * Data of the RunnableDataNode. Does not contain\r
-        * parent data.\r
-        */\r
-       private Map<String, Object> properData = new HashMap<String, Object>();\r
-       \r
-       private String path;\r
-       \r
-       private String beanName;\r
-\r
-       public boolean isLeaf() {\r
-               return children.size() == 0;\r
-       }\r
-       \r
-       public List<RunnableDataNode> getChildren() {\r
-               return children;\r
-       }\r
-\r
-       public void addChild(RunnableDataNode child) {\r
-               child.setParent(this);\r
-               children.add(child);\r
-       }\r
-       \r
-       public Map<String, Object> getData() {\r
-               Map<String, Object> data = new HashMap<String, Object>();\r
-               if(parent != null) {\r
-                       Map<String, Object> parentData = parent.getData();\r
-                       if(parentData != null) {\r
-                               data.putAll(parentData);\r
-                       }\r
-               }\r
-               // entries defined in parentData can be overridden\r
-               // in properData\r
-               if(properData != null) {\r
-                       data.putAll(properData);\r
-               }\r
-               return data;\r
-       }\r
-\r
-       public Map<String, Object> getProperData() {\r
-               return properData;\r
-       }\r
-\r
-       public void setProperData(Map<String, Object> properData) {\r
-               this.properData = properData;\r
-       }\r
-\r
-       public String getPath() {\r
-               return path;\r
-       }\r
-\r
-       public void setPath(String path) {\r
-               this.path = path;\r
-       }\r
-\r
-       public String getBeanName() {\r
-               return beanName;\r
-       }\r
-\r
-       public void setBeanName(String beanName) {\r
-               this.beanName = beanName;\r
-       }\r
-\r
-       public void setParent(RunnableDataNode parent) {\r
-               this.parent = parent;\r
-       }\r
-\r
-       public RunnableDataNode getParent() {\r
-               return parent;\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/ExecutionFlowGenerator.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/ExecutionFlowGenerator.java
deleted file mode 100644 (file)
index d9400e4..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.HashMap;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.springframework.aop.scope.ScopedProxyUtils;\r
-import org.springframework.beans.BeansException;\r
-import org.springframework.beans.MutablePropertyValues;\r
-import org.springframework.beans.factory.config.BeanDefinitionHolder;\r
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;\r
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;\r
-import org.springframework.beans.factory.config.RuntimeBeanReference;\r
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
-import org.springframework.beans.factory.support.GenericBeanDefinition;\r
-import org.springframework.core.Ordered;\r
-\r
-/**\r
- * Generates <code>ExecutionFlows</code> and <code>Runnables</code> as\r
- * beans in the Spring Application Context.\r
- * Called by the Application Context as a <code>BeanFactoryPostProcessor</code>.\r
- * Two kinds of beans are generated:\r
- * <code>RunnableCallFlow</code>, calling a list of <code>Runnables</code> from the\r
- * Application Context after configuring the <code>ExecutionContext</code>, \r
- * and outputs of a <code>RunnableFactory</code>.\r
- */\r
-public class ExecutionFlowGenerator implements BeanFactoryPostProcessor,\r
-               Ordered {\r
-       \r
-       private final Log log = LogFactory.getLog(getClass());\r
-\r
-       /**\r
-        * Source providing a list of <code>RunnableCallFlowDescriptor</code> \r
-        * used to create <code>RunnableCallFlow</code> and a list of \r
-        * <code>RunnableDataNode</code> used to create any kind of flow via a factory\r
-        */\r
-       protected ExecutionFlowGeneratorSource source;\r
-       \r
-       /**\r
-        * Factory used to create Runnables in the Application context from\r
-        * the <code>RunnableDataNode</code> provided from the source.\r
-        */\r
-       protected RunnableFactory runnableFactory;\r
-       \r
-       /**\r
-        * Bean name of the <code>ExecutionContext</code>.\r
-        * Used to provide the created <code>RunnableCallFlow</code> beans \r
-        * with a <code>RuntimeBeanReference</code> to\r
-        * the <code>ExecutionContext</code>\r
-        */\r
-       private String executionContextBeanName = "executionContext";\r
-       \r
-       /**\r
-        * Bean name of the context values Map.\r
-        * A bean of class HashMap is created with this name, and a \r
-        * <code>RuntimeBeanReference</code> is provided to the created\r
-        * <code>RunnableCallFlow</code> beans.\r
-        */\r
-       private String contextValuesBeanName = "executionFlowGenerator.contextValues";\r
-       \r
-       /**\r
-        * Prefix added to the bean names defined in each \r
-        * <code>RunnableCallFlowDescriptor</code>\r
-        */\r
-       private String flowBeanNamesPrefix = "";\r
-       \r
-       private int order = Ordered.HIGHEST_PRECEDENCE;\r
-               \r
-       public void postProcessBeanFactory(\r
-                       ConfigurableListableBeanFactory beanFactory) throws BeansException {\r
-\r
-               // assert that the beanFactory is a BeanDefinitionRegistry\r
-               if (!(beanFactory instanceof BeanDefinitionRegistry)) {\r
-                       throw new SlcException("Can only work on "\r
-                                       + BeanDefinitionRegistry.class);\r
-               } \r
-               \r
-               // add bean for the Context Values Map\r
-               createAndRegisterContextValuesBean((BeanDefinitionRegistry) beanFactory);\r
-               \r
-               // add beans for each RunnableDataNode\r
-               for(RunnableDataNode node : source.getRunnableDataNodes()) {\r
-                       runnableFactory.createAndRegisterRunnable(node, (BeanDefinitionRegistry) beanFactory);\r
-               }\r
-               \r
-               // add beans for each RunnableCallFlowDescriptor of the source to the application context\r
-               for (RunnableCallFlowDescriptor descriptor : source\r
-                               .getRunnableCallFlowDescriptors()) {\r
-                       createAndRegisterFlowFor(descriptor, (BeanDefinitionRegistry) beanFactory);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Creates a <code>RunnableCallFlow</code> bean\r
-        * for a <code>RunnableCallFlowDescriptor</code> and registers \r
-        * it in the <code>BeanDefinitionRegistry</code>\r
-        * @param flowDescriptor\r
-        * @param registry\r
-        */\r
-       private void createAndRegisterFlowFor(RunnableCallFlowDescriptor flowDescriptor, BeanDefinitionRegistry registry) {\r
-               // create the flow bean\r
-               GenericBeanDefinition flowBean = new GenericBeanDefinition();\r
-               flowBean.setBeanClass(RunnableCallFlow.class);\r
-               \r
-               String beanName = flowBeanNamesPrefix + flowDescriptor.getBeanName();\r
-               \r
-               MutablePropertyValues mpv = new MutablePropertyValues();                \r
-               mpv.addPropertyValue("runnableCalls", flowDescriptor.getRunnableCalls());\r
-               mpv.addPropertyValue("sharedContextValuesMap", new RuntimeBeanReference(contextValuesBeanName));\r
-               \r
-               mpv.addPropertyValue("name", beanName);\r
-               mpv.addPropertyValue("path", flowDescriptor.getPath());\r
-\r
-               mpv.addPropertyValue("executionContext", new RuntimeBeanReference(executionContextBeanName));\r
-               \r
-               flowBean.setPropertyValues(mpv);\r
-               \r
-               // register it\r
-               if(log.isDebugEnabled()) {\r
-                       log.debug("Registering bean definition for RunnableCallFlow " + beanName);\r
-               }\r
-               registry.registerBeanDefinition(beanName, flowBean);\r
-       }\r
-       \r
-       /**\r
-        * Creates the Context Values bean and register it in the\r
-        * <code>BeanDefinitionRegistry</code>\r
-        * @param registry\r
-        */\r
-       private void createAndRegisterContextValuesBean(BeanDefinitionRegistry registry) {\r
-               GenericBeanDefinition contextValuesBean = new GenericBeanDefinition();\r
-               contextValuesBean.setBeanClass(HashMap.class);\r
-               \r
-               BeanDefinitionHolder bdh = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(contextValuesBean, contextValuesBeanName), registry, true);                                                                                                                      \r
-               registry.registerBeanDefinition(contextValuesBeanName, bdh.getBeanDefinition());                \r
-       }\r
-       \r
-       public int getOrder() {\r
-               return order;\r
-       }\r
-\r
-       public void setOrder(int order) {\r
-               this.order = order;\r
-       }\r
-\r
-       public void setSource(ExecutionFlowGeneratorSource source) {\r
-               this.source = source;\r
-       }\r
-\r
-       public void setRunnableFactory(RunnableFactory runnableFactory) {\r
-               this.runnableFactory = runnableFactory;\r
-       }\r
-\r
-       public void setExecutionContextBeanName(String executionContextBeanName) {\r
-               this.executionContextBeanName = executionContextBeanName;\r
-       }\r
-\r
-       public void setContextValuesBeanName(String contextValuesBeanName) {\r
-               this.contextValuesBeanName = contextValuesBeanName;\r
-       }\r
-\r
-       public void setFlowBeanNamesPrefix(String flowBeanNamesPrefix) {\r
-               this.flowBeanNamesPrefix = flowBeanNamesPrefix;\r
-       }\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/ExecutionFlowGeneratorSource.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/ExecutionFlowGeneratorSource.java
deleted file mode 100644 (file)
index 8d699c6..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * Provides 2 types of information required by an <code>ExecutionFlowGenerator</code>: \r
- * a list of <code>RunnableCallFlowDescriptor</code> used to create <code>RunnableCallFlow</code>\r
- * and a list of <code>RunnableDataNode</code> used to create any kind of flow via a factory.\r
- */\r
-public interface ExecutionFlowGeneratorSource {\r
-       \r
-       /**\r
-        * @return a list of <code>RunnableCallFlowDescriptor</code> used \r
-        * by a <code>ExecutionFlowGenerator</code> to create <code>RunnableCallFlow</code>\r
-        */\r
-       public List<RunnableCallFlowDescriptor> getRunnableCallFlowDescriptors();\r
-       \r
-       /**\r
-        * @return a list of <code>RunnableDataNode</code> used \r
-        * by a <code>ExecutionFlowGenerator</code> to create any kind of flow via a factory\r
-        */\r
-       public List<RunnableDataNode> getRunnableDataNodes();\r
-       \r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableCall.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableCall.java
deleted file mode 100644 (file)
index c3fd5f2..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.Map;\r
-\r
-/**\r
- * Storage class for information required to call a flow \r
- * of the Spring execution context: \r
- * bean name of the flow,\r
- * variables to add to the Execution Context before the call \r
- * and variables (context values) to add to a Map \r
- * potentially referenced by the called flow \r
- */\r
-public class RunnableCall {\r
-       \r
-       /**\r
-        * Bean name of the flow to call\r
-        */\r
-       private String beanName;\r
-       \r
-       /**\r
-        * Variables to add to the execution context before the call\r
-        */\r
-       private Map<String, Object> executionVariables;\r
-       \r
-       /**\r
-        * Variables to add to the Map potentially referenced by\r
-        * the called flow\r
-        */\r
-       private Map<String, Object> contextValues;\r
-\r
-       public String getBeanName() {\r
-               return beanName;\r
-       }\r
-\r
-       public void setBeanName(String beanName) {\r
-               this.beanName = beanName;\r
-       }\r
-\r
-       public Map<String, Object> getExecutionVariables() {\r
-               return executionVariables;\r
-       }\r
-\r
-       public void setExecutionVariables(Map<String, Object> executionVariables) {\r
-               this.executionVariables = executionVariables;\r
-       }\r
-\r
-       public Map<String, Object> getContextValues() {\r
-               return contextValues;\r
-       }\r
-\r
-       public void setContextValues(Map<String, Object> contextValues) {\r
-               this.contextValues = contextValues;\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableCallFlow.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableCallFlow.java
deleted file mode 100644 (file)
index 695606c..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.core.execution.DefaultExecutionSpec;\r
-import org.argeo.slc.execution.ExecutionContext;\r
-import org.argeo.slc.execution.ExecutionFlow;\r
-import org.argeo.slc.execution.ExecutionSpec;\r
-import org.springframework.context.ApplicationContext;\r
-import org.springframework.context.ApplicationContextAware;\r
-\r
-/**\r
- * Execution Flow calling a list of <code>Runnable</code> (identified by their\r
- * bean name in the Spring Application Context) after configuring the Execution\r
- * context and a Map potentially shared by the called <code>Runnable</code>\r
- * \r
- */\r
-public class RunnableCallFlow implements ExecutionFlow, ApplicationContextAware {\r
-\r
-       private final static Log log = LogFactory.getLog(RunnableCallFlow.class);\r
-\r
-       /**\r
-        * Key in the execution context for the index of the call (e.g. 0 for the\r
-        * first runnable called, ...)\r
-        */\r
-       public final static String VAR_CALL_INDEX = "slcVar.runnableCallFlow.callIndex";\r
-\r
-       /**\r
-        * Name of the flow. Also bean name\r
-        */\r
-       private String name;\r
-\r
-       /**\r
-        * Path of the flow\r
-        */\r
-       private String path;\r
-\r
-       /**\r
-        * Whether an exception in a <code>Runnable</code> shall stop the execution\r
-        * of the flow\r
-        */\r
-       private Boolean failOnError = true;\r
-\r
-       /**\r
-        * List of <code>Runnable</code> to call, with bean name, execution\r
-        * variables and context values\r
-        */\r
-       private List<RunnableCall> runnableCalls;\r
-\r
-       /**\r
-        * Map potentially referenced by called flows. Updated with the context\r
-        * values of a Runnable before calling it.\r
-        */\r
-       private Map<String, Object> sharedContextValuesMap;\r
-\r
-       /**\r
-        * ExecutionSpec of the flow. Does not contain any attribute.\r
-        */\r
-       private ExecutionSpec executionSpec = new DefaultExecutionSpec();\r
-\r
-       /**\r
-        * Reference to the ExecutionContext\r
-        */\r
-       private ExecutionContext executionContext;\r
-\r
-       /**\r
-        * Reference to the Spring <code>ApplicationContext</code>. Set via\r
-        * <code>setApplicationContext</code>, the class implementing\r
-        * <code>ApplicationContextAware</code>\r
-        */\r
-       private ApplicationContext applicationContext;\r
-\r
-       /**\r
-        * Runs a <code>Runnable</code> after configuring the Execution Context and\r
-        * <code>sharedContextValuesMap</code>\r
-        * \r
-        * @param runnable\r
-        *            the <code>Runnable</code> to call\r
-        * @param executionVariables\r
-        *            the variables to add to the <code>ExecutionContext</code>\r
-        * @param contextValues\r
-        *            the variables to add to <code>sharedContextValuesMap</code>\r
-        * @param callIndex\r
-        *            index of the call (0 for the first called\r
-        *            <code>Runnable</code>) set as variable of the\r
-        *            <code>ExecutionContext</code>\r
-        */\r
-       private void run(Runnable runnable, Map<String, Object> executionVariables,\r
-                       Map<String, Object> contextValues, int callIndex) {\r
-               // add all variables to the Execution Context\r
-               for (Map.Entry<String, Object> entry : executionVariables.entrySet()) {\r
-                       executionContext.setVariable(entry.getKey(), entry.getValue());\r
-               }\r
-\r
-               // add call Index Variable\r
-               executionContext.setVariable(VAR_CALL_INDEX, callIndex);\r
-\r
-               // clear sharedContextValues and add all values of contextValues\r
-               if (sharedContextValuesMap != null) {\r
-                       sharedContextValuesMap.clear();\r
-                       sharedContextValuesMap.putAll(contextValues);\r
-               }\r
-\r
-               // then run the runnable\r
-               doExecuteRunnable(runnable);\r
-       }\r
-\r
-       public void doExecuteRunnable(Runnable runnable) {\r
-               runnable.run();\r
-       }\r
-\r
-       /**\r
-        * Executes the flow. For each <code>RunnableCall</code>, the corresponding\r
-        * flow is retrieved from the Spring Application Context, the\r
-        * <code>ExecutionContext</code> and <code>sharedContextValuesMap</code> are\r
-        * configured and the <code>Runnable</code> is called.\r
-        */\r
-       public void run() {\r
-               if (applicationContext == null) {\r
-                       throw new SlcException("No ApplicationContext defined");\r
-               }\r
-\r
-               try {\r
-                       for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
-                               RunnableCall runnableCall = runnableCalls.get(callIndex);\r
-                               Object bean = applicationContext.getBean(\r
-                                               runnableCall.getBeanName(), Runnable.class);\r
-                               if (log.isDebugEnabled())\r
-                                       log.debug("Running flow '" + runnableCall.getBeanName()\r
-                                                       + "'");\r
-                               run((Runnable) bean, runnableCall.getExecutionVariables(),\r
-                                               runnableCall.getContextValues(), callIndex);\r
-                       }\r
-               } catch (RuntimeException e) {\r
-                       if (failOnError)\r
-                               throw e;\r
-                       else {\r
-                               log.error("Execution flow failed,"\r
-                                               + " but process did not fail"\r
-                                               + " because failOnError property"\r
-                                               + " is set to false: " + e);\r
-                               if (log.isTraceEnabled())\r
-                                       e.printStackTrace();\r
-                       }\r
-               }\r
-       }\r
-\r
-       public Iterator<Runnable> runnables() {\r
-               List<Runnable> runnables = new ArrayList<Runnable>();\r
-               for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
-                       RunnableCall runnableCall = runnableCalls.get(callIndex);\r
-                       Object bean = applicationContext.getBean(\r
-                                       runnableCall.getBeanName(), Runnable.class);\r
-                       runnables.add((Runnable) bean);\r
-               }\r
-               return runnables.iterator();\r
-       }\r
-\r
-       public Runnable getRunnable() {\r
-               if (runnableCalls.size() == 1)\r
-                       return runnables().next();\r
-               else\r
-                       throw new SlcException("There are " + runnableCalls.size()\r
-                                       + " runnables in flow " + getName());\r
-       }\r
-\r
-       @Override\r
-       public String toString() {\r
-               return new StringBuffer("RunnableCallFlow ").append(name).toString();\r
-       }\r
-\r
-       public ExecutionSpec getExecutionSpec() {\r
-               return executionSpec;\r
-       }\r
-\r
-       public String getName() {\r
-               return name;\r
-       }\r
-\r
-       public Object getParameter(String key) {\r
-               throw new SlcException("RunnableCallFlow have no parameters");\r
-       }\r
-\r
-       public String getPath() {\r
-               return path;\r
-       }\r
-\r
-       public Boolean isSetAsParameter(String key) {\r
-               // The ExecutionSpec having no attribute,\r
-               // always return false\r
-               return false;\r
-       }\r
-\r
-       public void setName(String name) {\r
-               this.name = name;\r
-       }\r
-\r
-       public void setPath(String path) {\r
-               this.path = path;\r
-       }\r
-\r
-       public void setExecutionContext(ExecutionContext executionContext) {\r
-               this.executionContext = executionContext;\r
-       }\r
-\r
-       public void setRunnableCalls(List<RunnableCall> runnableCalls) {\r
-               this.runnableCalls = runnableCalls;\r
-       }\r
-\r
-       public void setApplicationContext(ApplicationContext applicationContext) {\r
-               this.applicationContext = applicationContext;\r
-       }\r
-\r
-       public void setSharedContextValuesMap(Map<String, Object> contextValues) {\r
-               this.sharedContextValuesMap = contextValues;\r
-       }\r
-\r
-       public void setFailOnError(Boolean failOnError) {\r
-               this.failOnError = failOnError;\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableCallFlowDescriptor.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableCallFlowDescriptor.java
deleted file mode 100644 (file)
index e0bbbdd..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-/**\r
- * Storage Class for information required to\r
- * instantiate a <code>RunnableCallFlow</code>:\r
- * bean name of the flow, \r
- * path of the flow \r
- * and list of <code>RunnableCall</code>. \r
- *\r
- */\r
-public class RunnableCallFlowDescriptor {\r
-       \r
-       /**\r
-        * Bean name of the flow to instantiate\r
-        */\r
-       private String beanName;\r
-       \r
-       /**\r
-        * Path of the flow to instantiate\r
-        */\r
-       private String path;\r
-       \r
-       /**\r
-        * List of <code>RunnableCall</code> \r
-        */\r
-       private List<RunnableCall> runnableCalls = new ArrayList<RunnableCall>();\r
-\r
-       public String getBeanName() {\r
-               return beanName;\r
-       }\r
-\r
-       public void setBeanName(String beanName) {\r
-               this.beanName = beanName;\r
-       }\r
-\r
-       public String getPath() {\r
-               return path;\r
-       }\r
-\r
-       public void setPath(String path) {\r
-               this.path = path;\r
-       }\r
-\r
-       public List<RunnableCall> getRunnableCalls() {\r
-               return runnableCalls;\r
-       }\r
-\r
-       public void setRunnableCalls(List<RunnableCall> runnableCalls) {\r
-               this.runnableCalls = runnableCalls;\r
-       }\r
-       \r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableDataNode.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableDataNode.java
deleted file mode 100644 (file)
index 51843dc..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-/**\r
- * Stores information relative to a Runnable.\r
- * Allows to structure the information as a tree, each node\r
- * storing data as a Map.\r
- */\r
-public interface RunnableDataNode {\r
-\r
-       /**\r
-        * @return a Map containing the data associated with this node.\r
-        * Data associated with parent nodes are expected\r
-        * to be contained in the returned Map\r
-        */\r
-       public Map<String, Object> getData();   \r
-\r
-       /**\r
-        * @return the name of the bean to create.\r
-        * Can be null if no bean shall be created for the \r
-        * <code>RunnableDataNode</code> (e.g. is is a sub-node)\r
-        */\r
-       public String getBeanName();\r
-       \r
-       /**\r
-        * @return the path of the flow bean to create.\r
-        * Can be null if the bean to created is not an\r
-        * <code>ExecutionFlow</code> or if no bean shall be created for the \r
-        * <code>RunnableDataNode</code> (e.g. is is a sub-node)\r
-        */\r
-       public String getPath();\r
-               \r
-       /**\r
-        * @return whether the <code>RunnableDataNode</code> has\r
-        * children or not.\r
-        * Expected to be equivalent to <code>getChildren().empty()</code>\r
-        */\r
-       public boolean isLeaf();\r
-\r
-       /**\r
-        * @return the list of <code>RunnableDataNode</code> children.\r
-        * Can be empty. Shall not be null.\r
-        */\r
-       public List<RunnableDataNode> getChildren();\r
-       \r
-       /**\r
-        * @return the <code>RunnableDataNode</code> parent.\r
-        * Can be null if no parent is defined (top node).\r
-        */\r
-       public RunnableDataNode getParent();\r
-       \r
-       /**\r
-        * Sets the <code>RunnableDataNode</code> parent\r
-        * @param parent\r
-        */\r
-       public void setParent(RunnableDataNode parent); \r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableFactory.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/generator/RunnableFactory.java
deleted file mode 100644 (file)
index 2b37028..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
-\r
-/**\r
- * Interprets a <code>RunnableDataNode</code> by creating corresponding\r
- * beans and registering them in a <code>BeanDefinitionRegistry</code>\r
- *\r
- */\r
-public interface RunnableFactory {\r
-\r
-       public void createAndRegisterRunnable(RunnableDataNode node,\r
-                       BeanDefinitionRegistry beanDefinitionRegistry);\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/runtime.xml b/org.argeo.slc.core/src/org/argeo/slc/core/execution/runtime.xml
deleted file mode 100644 (file)
index 33542ee..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2007-2012 Argeo GmbH Licensed under the Apache License, 
-       Version 2.0 (the "License"); you may not use this file except in compliance 
-       with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
-       Unless required by applicable law or agreed to in writing, software distributed 
-       under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
-       OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
-       the specific language governing permissions and limitations under the License. -->
-<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under 
-       the Apache License, Version 2.0 (the "License"); you may not use this file 
-       except in compliance with the License. You may obtain a copy of the License 
-       at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
-       law or agreed to in writing, software distributed under the License is distributed 
-       on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
-       express or implied. See the License for the specific language governing permissions 
-       and limitations under the License. -->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
-       <description>Bare minimal runtime configuration. In general you will
-               want to use simple.xml instead.
-       </description>
-
-       <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
-               <property name="scopes">
-                       <map>
-                               <entry key="execution">
-                                       <bean class="org.argeo.slc.core.execution.ExecutionScope" />
-                               </entry>
-                       </map>
-               </property>
-       </bean>
-
-
-       <bean id="executionStack" class="org.argeo.slc.core.execution.DefaultExecutionStack"
-               scope="execution">
-               <aop:scoped-proxy proxy-target-class="false" />
-       </bean>
-
-       <bean id="instantiationManager" class="org.argeo.slc.core.execution.InstantiationManager" />
-
-       <bean class="org.argeo.slc.core.execution.ExecutionParameterPostProcessor">
-               <property name="executionContext" ref="executionContext" />
-               <property name="instantiationManager" ref="instantiationManager" />
-       </bean>
-
-       <!-- <bean class="org.argeo.slc.core.execution.ExecutionAspect"> -->
-       <!-- <property name="executionStack" ref="executionStack" /> -->
-       <!-- <property name="executionContext" ref="executionContext" /> -->
-       <!-- </bean> -->
-
-       <aop:aspectj-autoproxy />
-
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/simple.xml b/org.argeo.slc.core/src/org/argeo/slc/core/execution/simple.xml
deleted file mode 100644 (file)
index ff243ba..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2007-2012 Argeo GmbH Licensed under the Apache License, 
-       Version 2.0 (the "License"); you may not use this file except in compliance 
-       with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
-       Unless required by applicable law or agreed to in writing, software distributed 
-       under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
-       OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
-       the specific language governing permissions and limitations under the License. -->
-<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under 
-       the Apache License, Version 2.0 (the "License"); you may not use this file 
-       except in compliance with the License. You may obtain a copy of the License 
-       at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
-       law or agreed to in writing, software distributed under the License is distributed 
-       on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
-       express or implied. See the License for the specific language governing permissions 
-       and limitations under the License. -->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
-       <description>Default Capabilities</description>
-
-       <import resource="runtime.xml" />
-
-       <bean id="executionContext" class="org.argeo.slc.core.execution.MapExecutionContext"
-               scope="execution">
-               <aop:scoped-proxy proxy-target-class="false" />
-               <property name="executionStack" ref="executionStack" />
-       </bean>
-
-       <bean id="executionFlowDescriptorConverter"
-               class="org.argeo.slc.core.execution.DefaultExecutionFlowDescriptorConverter"></bean>
-
-       <bean
-               class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
-               <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
-               <property name="ignoreUnresolvablePlaceholders" value="true" />
-       </bean>
-
-       <bean id="parameterRef" class="org.argeo.slc.core.execution.ParameterRef"
-               abstract="true">
-               <property name="instantiationManager" ref="instantiationManager" />
-       </bean>
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/specs.xml b/org.argeo.slc.core/src/org/argeo/slc/core/execution/specs.xml
deleted file mode 100644 (file)
index 7cc9604..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (C) 2007-2012 Argeo GmbH
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-            http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
-       xsi:schemaLocation="
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
-
-       <bean id="specAttr.primitive" class="org.argeo.slc.core.execution.PrimitiveSpecAttribute"
-               abstract="true" />
-       <bean id="specAttr.resource" class="org.argeo.slc.core.execution.ResourceSpecAttribute"
-               abstract="true" />
-       <bean id="specAttr.ref" class="org.argeo.slc.core.execution.RefSpecAttribute"
-               abstract="true" />
-
-       <bean id="slcTemplate.simpleFlow" class="org.argeo.slc.core.execution.DefaultExecutionFlow"
-               abstract="true" />
-       <bean id="slcTemplate.simpleSpec" class="org.argeo.slc.core.execution.DefaultExecutionSpec"
-               abstract="true" />
-
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/spring.xml b/org.argeo.slc.core/src/org/argeo/slc/core/execution/spring.xml
deleted file mode 100644 (file)
index de1c06b..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (C) 2007-2012 Argeo GmbH
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-            http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under 
-       the Apache License, Version 2.0 (the "License"); you may not use this file 
-       except in compliance with the License. You may obtain a copy of the License 
-       at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
-       law or agreed to in writing, software distributed under the License is distributed 
-       on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
-       express or implied. See the License for the specific language governing permissions 
-       and limitations under the License. -->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
-       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
-       <description>
-               Simple runtime enriched with defaults and templates used
-               to simplify XML files. These templates have been deprecated by the
-               custom XML namespace and will be removed in SLC 2.x. Use the XML
-               namespace instead.
-       </description>
-
-       <import resource="simple.xml" />
-
-       <import resource="specs.xml" />
-       <import resource="templates.xml" />
-       <import resource="defaults.xml" />
-       <import resource="utils.xml" />
-       <import resource="tasks/core.xml" />
-
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/CloseTestResult.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/CloseTestResult.java
deleted file mode 100644 (file)
index 43b2961..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import org.argeo.slc.test.TestResult;
-
-public class CloseTestResult implements Runnable {
-       private TestResult testResult;
-
-       public void run() {
-               testResult.close();
-       }
-
-       public void setTestResult(TestResult testResult) {
-               this.testResult = testResult;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/Echo.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/Echo.java
deleted file mode 100644 (file)
index d47149b..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.core.io.Resource;
-
-public class Echo implements Runnable {
-       private final static Log defaultLog = LogFactory.getLog(Echo.class);
-       private Resource writeTo = null;
-
-       private Log log;
-       private Object message;
-
-       public void run() {
-               log().info(message);
-
-               if (writeTo != null) {
-                       try {
-                               File file = writeTo.getFile();
-                               if (log().isDebugEnabled())
-                                       log().debug("Write to " + file);
-                               if (message != null)
-                                       FileUtils.writeStringToFile(file, message.toString());
-                       } catch (IOException e) {
-                               throw new SlcException("Could not write to " + writeTo, e);
-                       }
-               }
-       }
-
-       private Log log() {
-               return log != null ? log : defaultLog;
-       }
-
-       public void setMessage(Object message) {
-               this.message = message;
-       }
-
-       public void setWriteTo(Resource writeTo) {
-               this.writeTo = writeTo;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/If.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/If.java
deleted file mode 100644 (file)
index 0d22e43..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import org.argeo.slc.SlcException;
-
-/** Conditional execution */
-public class If implements Runnable {
-       private Boolean is;
-       private Boolean not;
-       private Runnable then;
-       private Runnable els;
-
-       public void run() {
-               if (is == null && not == null)
-                       throw new SlcException("No condition set");
-               if (is != null && not != null)
-                       throw new SlcException("Both is and not cannot be set");
-
-               boolean bool = (is != null ? is : !not);
-               if (bool) {
-                       if (then != null)
-                               then.run();
-               } else {
-                       if (els != null)
-                               els.run();
-               }
-
-       }
-
-       public void setIs(Boolean bool) {
-               this.is = bool;
-       }
-
-       public void setThen(Runnable then) {
-               this.then = then;
-       }
-
-       public void setEls(Runnable els) {
-               this.els = els;
-       }
-
-       public Boolean getNot() {
-               return not;
-       }
-
-       public void setNot(Boolean not) {
-               this.not = not;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/JvmProcess.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/JvmProcess.java
deleted file mode 100644 (file)
index 01f1101..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.core.io.Resource;
-
-/** A Java Virtual Machine process. */
-public class JvmProcess extends SystemCall implements InitializingBean {
-       private Properties systemProperties = new Properties();
-       private List<Resource> classpath = new ArrayList<Resource>();
-       private List<Resource> pBootClasspath = new ArrayList<Resource>();
-       private Resource jvm = null;
-       private String mainClass;
-       private String mainJar;
-       private List<String> jvmArgs = new ArrayList<String>();
-       private List<String> args = new ArrayList<String>();
-
-       private String systemPropertiesFileProperty = null;
-       private String systemPropertiesFileDir = null;
-       private String systemPropertiesFileName = null;
-
-       public void afterPropertiesSet() throws Exception {
-               List<Object> command = new ArrayList<Object>();
-               if (jvm != null)
-                       command.add(asFile(jvm).getPath());
-               else
-                       command.add("java");
-
-               if (pBootClasspath.size() > 0) {
-                       StringBuffer buf = new StringBuffer("-Xbootclasspath/p:");
-                       Boolean first = true;
-                       for (Resource res : pBootClasspath) {
-                               if (first)
-                                       first = false;
-                               else
-                                       buf.append(File.pathSeparatorChar);
-
-                               buf.append(asFile(res));
-                       }
-                       command.add(buf.toString());
-               }
-
-               for (String jvmArg : jvmArgs) {
-                       command.add(jvmArg);
-               }
-
-               if (classpath.size() > 0) {
-                       command.add("-cp");
-                       StringBuffer buf = new StringBuffer("");
-                       for (Resource res : classpath) {
-                               if (buf.length() != 0)
-                                       buf.append(File.pathSeparatorChar);
-                               buf.append(asFile(res));
-                       }
-                       command.add(buf.toString());
-               }
-
-               if (systemPropertiesFileProperty == null) {
-                       // pass system properties as argument
-                       for (Map.Entry<Object, Object> entry : systemProperties.entrySet()) {
-                               command.add("-D" + entry.getKey() + "=" + entry.getValue());
-                       }
-               } else {
-                       // write system properties in a file to work around OS limitations
-                       // with command line (e.g. Win XP)
-                       String dir = systemPropertiesFileDir;
-                       if (dir == null)
-                               dir = getExecDirToUse();
-                       String fileName = systemPropertiesFileName;
-                       if (fileName == null)
-                               fileName = systemPropertiesFileProperty + ".properties";
-
-                       // Write file
-                       FileOutputStream fos = null;
-                       File file = new File(dir + File.separator + fileName);
-                       try {
-
-                               if (!file.getParentFile().exists())
-                                       file.getParentFile().mkdirs();
-                               fos = new FileOutputStream(file);
-                               systemProperties.store(fos, "Automatically generated by "
-                                               + getClass());
-                               command.add("-D" + systemPropertiesFileProperty + "="
-                                               + file.getCanonicalPath());
-                       } catch (IOException e) {
-                               throw new SlcException("Cannot write to system properties to "
-                                               + file, e);
-                       } finally {
-                               IOUtils.closeQuietly(fos);
-                       }
-               }
-
-               // Program
-               if (mainClass != null) {
-                       command.add(mainClass);
-               } else if (mainJar != null) {
-                       command.add("-jar");
-                       command.add(mainJar);
-               } else {
-                       throw new SlcException("No main class or jar defined");
-               }
-
-               for (String arg : args) {
-                       command.add(arg);
-               }
-
-               setCommand(command);
-       }
-
-       protected File asFile(Resource res) {
-               try {
-                       return res.getFile();
-               } catch (FileNotFoundException e) {
-                       return copyToTempFile(res);
-               } catch (IOException e) {
-                       throw new SlcException("Cannot convert resource to file", e);
-               }
-
-       }
-
-       protected File copyToTempFile(Resource res) {
-               File tempFile;
-               FileOutputStream fos;
-               try {
-                       tempFile = File.createTempFile("slcJvmProcess-", res.getFilename());
-                       tempFile.deleteOnExit();
-                       fos = new FileOutputStream(tempFile);
-                       IOUtils.copy(res.getInputStream(), fos);
-               } catch (IOException e) {
-                       throw new SlcException("Cannot copy " + res + " to temp file.", e);
-               }
-               IOUtils.closeQuietly(fos);
-               return tempFile;
-       }
-
-       /** Append the argument (for chaining) */
-       @Override
-       public SystemCall arg(String arg) {
-               args.add(arg);
-               return this;
-       }
-
-       /** Append the argument (for chaining) */
-       @Override
-       public SystemCall arg(String arg, String value) {
-               args.add(arg);
-               args.add(value);
-               return this;
-       }
-
-       public Properties getSystemProperties() {
-               return systemProperties;
-       }
-
-       public void setSystemProperties(Properties systemProperties) {
-               this.systemProperties = systemProperties;
-       }
-
-       public List<Resource> getClasspath() {
-               return classpath;
-       }
-
-       public void setClasspath(List<Resource> classpath) {
-               this.classpath = classpath;
-       }
-
-       public List<Resource> getPBootClasspath() {
-               return pBootClasspath;
-       }
-
-       public void setPBootClasspath(List<Resource> bootClasspath) {
-               pBootClasspath = bootClasspath;
-       }
-
-       public Resource getJvm() {
-               return jvm;
-       }
-
-       public void setJvm(Resource jvm) {
-               this.jvm = jvm;
-       }
-
-       public String getMainClass() {
-               return mainClass;
-       }
-
-       public void setMainClass(String mainClass) {
-               this.mainClass = mainClass;
-       }
-
-       public String getMainJar() {
-               return mainJar;
-       }
-
-       public void setMainJar(String mainJar) {
-               this.mainJar = mainJar;
-       }
-
-       public List<String> getJvmArgs() {
-               return jvmArgs;
-       }
-
-       public void setJvmArgs(List<String> jvmArgs) {
-               this.jvmArgs = jvmArgs;
-       }
-
-       public List<String> getArgs() {
-               return args;
-       }
-
-       public void setArgs(List<String> args) {
-               this.args = args;
-       }
-
-       public void setSystemPropertiesFileProperty(
-                       String systemPropertiesFilePropertyName) {
-               this.systemPropertiesFileProperty = systemPropertiesFilePropertyName;
-       }
-
-       public void setSystemPropertiesFileDir(String systemPropertiesFileDir) {
-               this.systemPropertiesFileDir = systemPropertiesFileDir;
-       }
-
-       public void setSystemPropertiesFileName(String systemPropertiesFileName) {
-               this.systemPropertiesFileName = systemPropertiesFileName;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/MergedLists.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/MergedLists.java
deleted file mode 100644 (file)
index e1740e6..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.springframework.beans.factory.FactoryBean;
-
-/** Merge the provided lists in one single list, in the order provided. */
-public class MergedLists implements FactoryBean<List<Object>> {
-       private List<List<Object>> lists = new ArrayList<List<Object>>();
-
-       public void setLists(List<List<Object>> lists) {
-               this.lists = lists;
-       }
-
-       public List<Object> getObject() throws Exception {
-               List<Object> merged = new ArrayList<Object>();
-               for (List<Object> lst : lists) {
-                       merged.addAll(lst);
-               }
-               return merged;
-       }
-
-       public Class<?> getObjectType() {
-               return List.class;
-       }
-
-       public boolean isSingleton() {
-               return false;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/MethodCall.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/MethodCall.java
deleted file mode 100644 (file)
index e4fa772..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.springframework.util.Assert;
-import org.springframework.util.ReflectionUtils;
-
-public class MethodCall implements Runnable {
-       private Object target;
-       private String method;
-       private List<Object> args = new ArrayList<Object>();
-
-       public void run() {
-               Assert.notNull(target, "target");
-               Assert.notNull(method, "method");
-               Method methodRef = ReflectionUtils
-                               .findMethod(target.getClass(), method);
-               if (args.size() == 0)
-                       ReflectionUtils.invokeMethod(methodRef, target);
-               else
-                       ReflectionUtils.invokeMethod(methodRef, methodRef, args.toArray());
-       }
-
-       public void setTarget(Object target) {
-               this.target = target;
-       }
-
-       public void setMethod(String method) {
-               this.method = method;
-       }
-
-       public void setArgs(List<Object> args) {
-               this.args = args;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/OverrideContextAware.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/OverrideContextAware.java
deleted file mode 100644 (file)
index 9afa846..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.tasks;\r
-\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.core.test.context.SimpleContextAware;\r
-import org.argeo.slc.test.context.ContextAware;\r
-\r
-/**\r
- * Overrides Values and Expected values of a target \r
- * <code>SimpleContextAware</code> with the corresponding\r
- * values and expected values of a source <code>ContextAware</code>\r
- *\r
- */\r
-public class OverrideContextAware implements Runnable {\r
-\r
-       private ContextAware source;\r
-\r
-       private SimpleContextAware target;\r
-       \r
-       /**\r
-        * Whether an exception shall be thrown if a value\r
-        * or expected value of the source is not defined\r
-        * in the target\r
-        */\r
-       private Boolean failIfUndefinedInSource = true;\r
-       \r
-       public void run() {\r
-               // override values\r
-               if(source.getValues() != null)\r
-                       for(String key : source.getValues().keySet()) {\r
-                               if(failIfUndefinedInSource && !target.getValues().containsKey(key)) {\r
-                                       throw new SlcException("No entry in target values for key '" + key + "'");\r
-                               }\r
-                               target.getValues().put(key, source.getValues().get(key));\r
-                       }\r
-               \r
-               // override expected values\r
-               if(source.getExpectedValues() != null)\r
-                       for(String key : source.getExpectedValues().keySet()) {\r
-                               if(failIfUndefinedInSource && !target.getExpectedValues().containsKey(key)) {\r
-                                       throw new SlcException("No entry in target expected values for key '" + key + "'");\r
-                               }\r
-                               target.getExpectedValues().put(key, source.getExpectedValues().get(key));\r
-                       }               \r
-       }       \r
-       \r
-       public void setSource(ContextAware source) {\r
-               this.source = source;\r
-       }\r
-\r
-       public void setTarget(SimpleContextAware target) {\r
-               this.target = target;\r
-       }\r
-\r
-       public void setFailIfUndefinedInSource(Boolean failIfUndefinedInSource) {\r
-               this.failIfUndefinedInSource = failIfUndefinedInSource;\r
-       }       \r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/SystemCall.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/SystemCall.java
deleted file mode 100644 (file)
index 27cc59d..0000000
+++ /dev/null
@@ -1,782 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-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;
-import java.io.OutputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.security.auth.callback.CallbackHandler;
-
-import org.apache.commons.exec.CommandLine;
-import org.apache.commons.exec.DefaultExecutor;
-import org.apache.commons.exec.ExecuteException;
-import org.apache.commons.exec.ExecuteResultHandler;
-import org.apache.commons.exec.ExecuteStreamHandler;
-import org.apache.commons.exec.ExecuteWatchdog;
-import org.apache.commons.exec.Executor;
-import org.apache.commons.exec.LogOutputStream;
-import org.apache.commons.exec.PumpStreamHandler;
-import org.apache.commons.exec.ShutdownHookProcessDestroyer;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-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.test.SimpleResultPart;
-import org.argeo.slc.test.TestResult;
-import org.argeo.slc.test.TestStatus;
-import org.springframework.core.io.Resource;
-
-/** Execute an OS specific system call. */
-public class SystemCall implements Runnable {
-       public final static String LOG_STDOUT = "System.out";
-
-       private final Log log = LogFactory.getLog(getClass());
-
-       private String execDir;
-
-       private String cmd = null;
-       private List<Object> command = null;
-
-       private Executor executor = new DefaultExecutor();
-       private Boolean synchronous = true;
-
-       private String stdErrLogLevel = "ERROR";
-       private String stdOutLogLevel = "INFO";
-
-       private Resource stdOutFile = null;
-       private Resource stdErrFile = null;
-
-       private Resource stdInFile = null;
-       /**
-        * If no {@link #stdInFile} provided, writing to this stream will write to
-        * the stdin of the process.
-        */
-       private OutputStream stdInSink = null;
-
-       private Boolean redirectStdOut = false;
-
-       private List<SystemCallOutputListener> outputListeners = Collections
-                       .synchronizedList(new ArrayList<SystemCallOutputListener>());
-
-       private Map<String, List<Object>> osCommands = new HashMap<String, List<Object>>();
-       private Map<String, String> osCmds = new HashMap<String, String>();
-       private Map<String, String> environmentVariables = new HashMap<String, String>();
-
-       private Boolean logCommand = false;
-       private Boolean redirectStreams = true;
-       private Boolean exceptionOnFailed = true;
-       private Boolean mergeEnvironmentVariables = true;
-
-//     private Authentication authentication;
-
-       private String osConsole = null;
-       private String generateScript = null;
-
-       /** 24 hours */
-       private Long watchdogTimeout = 24 * 60 * 60 * 1000l;
-
-       private TestResult testResult;
-
-       private ExecutionResources executionResources;
-
-       /** Sudo the command, as root if empty or as user if not. */
-       private String sudo = null;
-       // TODO make it more secure and robust, test only once
-       private final String sudoPrompt = UUID.randomUUID().toString();
-       private String askPassProgram = "/usr/libexec/openssh/ssh-askpass";
-       @SuppressWarnings("unused")
-       private boolean firstLine = true;
-       @SuppressWarnings("unused")
-       private CallbackHandler callbackHandler;
-       /** Chroot to the this path (must not be empty) */
-       private String chroot = null;
-
-       // Current
-       /** Current watchdog, null if process is completed */
-       ExecuteWatchdog currentWatchdog = null;
-
-       /** Empty constructor */
-       public SystemCall() {
-
-       }
-
-       /**
-        * Constructor based on the provided command list.
-        * 
-        * @param command
-        *            the command list
-        */
-       public SystemCall(List<Object> command) {
-               this.command = command;
-       }
-
-       /**
-        * Constructor based on the provided command.
-        * 
-        * @param cmd
-        *            the command. If the provided string contains no space a
-        *            command list is initialized with the argument as first
-        *            component (useful for chained construction)
-        */
-       public SystemCall(String cmd) {
-               if (cmd.indexOf(' ') < 0) {
-                       command = new ArrayList<Object>();
-                       command.add(cmd);
-               } else {
-                       this.cmd = cmd;
-               }
-       }
-
-       /** Executes the system call. */
-       public void run() {
-//             authentication = SecurityContextHolder.getContext().getAuthentication();
-
-               // Manage streams
-               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, true);
-               } else {
-                       if (stdOutFile != null && !redirectStdOut)
-                               stdErrWriter = createWriter(stdOutFile, true);
-               }
-
-               try {
-                       if (stdInFile != null)
-                               stdInStream = stdInFile.getInputStream();
-                       else {
-                               stdInStream = new PipedInputStream();
-                               stdInSink = new PipedOutputStream(
-                                               (PipedInputStream) stdInStream);
-                       }
-               } catch (IOException e2) {
-                       throw new SlcException("Cannot open a stream for " + stdInFile, e2);
-               }
-
-               if (log.isTraceEnabled()) {
-                       log.debug("os.name=" + System.getProperty("os.name"));
-                       log.debug("os.arch=" + System.getProperty("os.arch"));
-                       log.debug("os.version=" + System.getProperty("os.version"));
-               }
-
-               // Execution directory
-               File dir = new File(getExecDirToUse());
-               // if (!dir.exists())
-               // dir.mkdirs();
-
-               // Watchdog to check for lost processes
-               Executor executorToUse;
-               if (executor != null)
-                       executorToUse = executor;
-               else
-                       executorToUse = new DefaultExecutor();
-               executorToUse.setWatchdog(createWatchdog());
-
-               if (redirectStreams) {
-                       // Redirect standard streams
-                       executorToUse.setStreamHandler(createExecuteStreamHandler(
-                                       stdOutWriter, stdOutputStream, stdErrWriter, stdInStream));
-               } else {
-                       // Dummy stream handler (otherwise pump is used)
-                       executorToUse.setStreamHandler(new DummyexecuteStreamHandler());
-               }
-
-               executorToUse.setProcessDestroyer(new ShutdownHookProcessDestroyer());
-               executorToUse.setWorkingDirectory(dir);
-
-               // Command line to use
-               final CommandLine commandLine = createCommandLine();
-               if (logCommand)
-                       log.info("Execute command:\n" + commandLine
-                                       + "\n in working directory: \n" + dir + "\n");
-
-               // Env variables
-               Map<String, String> environmentVariablesToUse = null;
-               environmentVariablesToUse = new HashMap<String, String>();
-               if (mergeEnvironmentVariables)
-                       environmentVariablesToUse.putAll(System.getenv());
-               if (environmentVariables.size() > 0)
-                       environmentVariablesToUse.putAll(environmentVariables);
-
-               // Execute
-               ExecuteResultHandler executeResultHandler = createExecuteResultHandler(commandLine);
-
-               //
-               // THE EXECUTION PROPER
-               //
-               try {
-                       if (synchronous)
-                               try {
-                                       int exitValue = executorToUse.execute(commandLine,
-                                                       environmentVariablesToUse);
-                                       executeResultHandler.onProcessComplete(exitValue);
-                               } catch (ExecuteException e1) {
-                                       if (e1.getExitValue() == Executor.INVALID_EXITVALUE) {
-                                               Thread.currentThread().interrupt();
-                                               return;
-                                       }
-                                       // Sleep 1s in order to make sure error logs are flushed
-                                       Thread.sleep(1000);
-                                       executeResultHandler.onProcessFailed(e1);
-                               }
-                       else
-                               executorToUse.execute(commandLine, environmentVariablesToUse,
-                                               executeResultHandler);
-               } catch (SlcException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new SlcException("Could not execute command " + commandLine,
-                                       e);
-               } finally {
-                       IOUtils.closeQuietly(stdOutWriter);
-                       IOUtils.closeQuietly(stdErrWriter);
-                       IOUtils.closeQuietly(stdInStream);
-                       IOUtils.closeQuietly(stdInSink);
-               }
-
-       }
-
-       public synchronized String function() {
-               final StringBuffer buf = new StringBuffer("");
-               SystemCallOutputListener tempOutputListener = new SystemCallOutputListener() {
-                       private Long lineCount = 0l;
-
-                       public void newLine(SystemCall systemCall, String line,
-                                       Boolean isError) {
-                               if (!isError) {
-                                       if (lineCount != 0l)
-                                               buf.append('\n');
-                                       buf.append(line);
-                                       lineCount++;
-                               }
-                       }
-               };
-               addOutputListener(tempOutputListener);
-               run();
-               removeOutputListener(tempOutputListener);
-               return buf.toString();
-       }
-
-       public String asCommand() {
-               return createCommandLine().toString();
-       }
-
-       @Override
-       public String toString() {
-               return asCommand();
-       }
-
-       /**
-        * Build a command line based on the properties. Can be overridden by
-        * specific command wrappers.
-        */
-       protected CommandLine createCommandLine() {
-               // Check if an OS specific command overrides
-               String osName = System.getProperty("os.name");
-               List<Object> commandToUse = null;
-               if (osCommands.containsKey(osName))
-                       commandToUse = osCommands.get(osName);
-               else
-                       commandToUse = command;
-               String cmdToUse = null;
-               if (osCmds.containsKey(osName))
-                       cmdToUse = osCmds.get(osName);
-               else
-                       cmdToUse = cmd;
-
-               CommandLine commandLine = null;
-
-               // Which command definition to use
-               if (commandToUse == null && cmdToUse == null)
-                       throw new SlcException("Please specify a command.");
-               else if (commandToUse != null && cmdToUse != null)
-                       throw new SlcException(
-                                       "Specify the command either as a line or as a list.");
-               else if (cmdToUse != null) {
-                       if (chroot != null && !chroot.trim().equals(""))
-                               cmdToUse = "chroot \"" + chroot + "\" " + cmdToUse;
-                       if (sudo != null) {
-                               environmentVariables.put("SUDO_ASKPASS", askPassProgram);
-                               if (!sudo.trim().equals(""))
-                                       cmdToUse = "sudo -p " + sudoPrompt + " -u " + sudo + " "
-                                                       + cmdToUse;
-                               else
-                                       cmdToUse = "sudo -p " + sudoPrompt + " " + cmdToUse;
-                       }
-
-                       // GENERATE COMMAND LINE
-                       commandLine = CommandLine.parse(cmdToUse);
-               } else if (commandToUse != null) {
-                       if (commandToUse.size() == 0)
-                               throw new SlcException("Command line is empty.");
-
-                       if (chroot != null && sudo != null) {
-                               commandToUse.add(0, "chroot");
-                               commandToUse.add(1, chroot);
-                       }
-
-                       if (sudo != null) {
-                               environmentVariables.put("SUDO_ASKPASS", askPassProgram);
-                               commandToUse.add(0, "sudo");
-                               commandToUse.add(1, "-p");
-                               commandToUse.add(2, sudoPrompt);
-                               if (!sudo.trim().equals("")) {
-                                       commandToUse.add(3, "-u");
-                                       commandToUse.add(4, sudo);
-                               }
-                       }
-
-                       // GENERATE COMMAND LINE
-                       commandLine = new CommandLine(commandToUse.get(0).toString());
-
-                       for (int i = 1; i < commandToUse.size(); i++) {
-                               if (log.isTraceEnabled())
-                                       log.debug(commandToUse.get(i));
-                               commandLine.addArgument(commandToUse.get(i).toString());
-                       }
-               } else {
-                       // all cases covered previously
-                       throw new UnsupportedException();
-               }
-
-               if (generateScript != null) {
-                       File scriptFile = new File(getExecDirToUse() + File.separator
-                                       + generateScript);
-                       try {
-                               FileUtils.writeStringToFile(scriptFile,
-                                               (osConsole != null ? osConsole + " " : "")
-                                                               + commandLine.toString());
-                       } catch (IOException e) {
-                               throw new SlcException("Could not generate script "
-                                               + scriptFile, e);
-                       }
-                       commandLine = new CommandLine(scriptFile);
-               } else {
-                       if (osConsole != null)
-                               commandLine = CommandLine.parse(osConsole + " "
-                                               + commandLine.toString());
-               }
-
-               return commandLine;
-       }
-
-       /**
-        * Creates a {@link PumpStreamHandler} which redirects streams to the custom
-        * logging mechanism.
-        */
-       protected ExecuteStreamHandler createExecuteStreamHandler(
-                       final Writer stdOutWriter, final OutputStream stdOutputStream,
-                       final Writer stdErrWriter, final InputStream stdInStream) {
-
-               // Log writers
-               OutputStream stdout = stdOutputStream != null ? stdOutputStream
-                               : new LogOutputStream() {
-                                       protected void processLine(String line, int level) {
-                                               // if (firstLine) {
-                                               // if (sudo != null && callbackHandler != null
-                                               // && line.startsWith(sudoPrompt)) {
-                                               // try {
-                                               // PasswordCallback pc = new PasswordCallback(
-                                               // "sudo password", false);
-                                               // Callback[] cbs = { pc };
-                                               // callbackHandler.handle(cbs);
-                                               // char[] pwd = pc.getPassword();
-                                               // char[] arr = Arrays.copyOf(pwd,
-                                               // pwd.length + 1);
-                                               // arr[arr.length - 1] = '\n';
-                                               // IOUtils.write(arr, stdInSink);
-                                               // stdInSink.flush();
-                                               // } catch (Exception e) {
-                                               // throw new SlcException(
-                                               // "Cannot retrieve sudo password", e);
-                                               // }
-                                               // }
-                                               // firstLine = false;
-                                               // }
-
-                                               if (line != null && !line.trim().equals(""))
-                                                       logStdOut(line);
-
-                                               if (stdOutWriter != null)
-                                                       appendLineToFile(stdOutWriter, line);
-                                       }
-                               };
-
-               OutputStream stderr = new LogOutputStream() {
-                       protected void processLine(String line, int level) {
-                               if (line != null && !line.trim().equals(""))
-                                       logStdErr(line);
-                               if (stdErrWriter != null)
-                                       appendLineToFile(stdErrWriter, line);
-                       }
-               };
-
-               PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(stdout,
-                               stderr, stdInStream) {
-
-                       @Override
-                       public void stop() throws IOException {
-                               // prevents the method to block when joining stdin
-                               if (stdInSink != null)
-                                       IOUtils.closeQuietly(stdInSink);
-
-                               super.stop();
-                       }
-               };
-               return pumpStreamHandler;
-       }
-
-       /** Creates the default {@link ExecuteResultHandler}. */
-       protected ExecuteResultHandler createExecuteResultHandler(
-                       final CommandLine commandLine) {
-               return new ExecuteResultHandler() {
-
-                       public void onProcessComplete(int exitValue) {
-                               String msg = "System call '" + commandLine
-                                               + "' properly completed.";
-                               if (log.isTraceEnabled())
-                                       log.trace(msg);
-                               if (testResult != null) {
-                                       forwardPath(testResult);
-                                       testResult.addResultPart(new SimpleResultPart(
-                                                       TestStatus.PASSED, msg));
-                               }
-                               releaseWatchdog();
-                       }
-
-                       public void onProcessFailed(ExecuteException e) {
-
-                               String msg = "System call '" + commandLine + "' failed.";
-                               if (testResult != null) {
-                                       forwardPath(testResult);
-                                       testResult.addResultPart(new SimpleResultPart(
-                                                       TestStatus.ERROR, msg, e));
-                               } else {
-                                       if (exceptionOnFailed)
-                                               throw new SlcException(msg, e);
-                                       else
-                                               log.error(msg, e);
-                               }
-                               releaseWatchdog();
-                       }
-               };
-       }
-
-       @Deprecated
-       protected void forwardPath(TestResult testResult) {
-               // TODO: allocate a TreeSPath
-       }
-
-       /**
-        * Shortcut method getting the execDir to use
-        */
-       protected String getExecDirToUse() {
-               try {
-                       if (execDir != null) {
-                               return execDir;
-                       }
-                       return System.getProperty("user.dir");
-               } catch (Exception e) {
-                       throw new SlcException("Cannot find exec dir", e);
-               }
-       }
-
-       protected void logStdOut(String line) {
-               for (SystemCallOutputListener outputListener : outputListeners)
-                       outputListener.newLine(this, line, false);
-               log(stdOutLogLevel, line);
-       }
-
-       protected void logStdErr(String line) {
-               for (SystemCallOutputListener outputListener : outputListeners)
-                       outputListener.newLine(this, line, true);
-               log(stdErrLogLevel, line);
-       }
-
-       /** Log from the underlying streams. */
-       protected void log(String logLevel, String line) {
-               // TODO optimize
-//             if (SecurityContextHolder.getContext().getAuthentication() == null) {
-//                     SecurityContextHolder.getContext()
-//                                     .setAuthentication(authentication);
-//             }
-
-               if ("ERROR".equals(logLevel))
-                       log.error(line);
-               else if ("WARN".equals(logLevel))
-                       log.warn(line);
-               else if ("INFO".equals(logLevel))
-                       log.info(line);
-               else if ("DEBUG".equals(logLevel))
-                       log.debug(line);
-               else if ("TRACE".equals(logLevel))
-                       log.trace(line);
-               else if (LOG_STDOUT.equals(logLevel))
-                       System.out.println(line);
-               else if ("System.err".equals(logLevel))
-                       System.err.println(line);
-               else
-                       throw new SlcException("Unknown log level " + logLevel);
-       }
-
-       /** Append line to a log file. */
-       protected void appendLineToFile(Writer writer, String line) {
-               try {
-                       writer.append(line).append('\n');
-               } catch (IOException e) {
-                       log.error("Cannot write to log file", e);
-               }
-       }
-
-       /** Creates the writer for the output/err files. */
-       protected Writer createWriter(Resource target, Boolean append) {
-               FileWriter writer = null;
-               try {
-
-                       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 get file for " + target, e);
-                       IOUtils.closeQuietly(writer);
-               }
-               return writer;
-       }
-
-       /** Creates an outputstream for the output/err files. */
-       protected OutputStream createOutputStream(Resource target) {
-               FileOutputStream out = null;
-               try {
-
-                       final File file;
-                       if (executionResources != null)
-                               file = new File(executionResources.getAsOsPath(target, true));
-                       else
-                               file = target.getFile();
-                       out = new FileOutputStream(file, false);
-               } catch (IOException e) {
-                       log.error("Cannot get file for " + target, e);
-                       IOUtils.closeQuietly(out);
-               }
-               return out;
-       }
-
-       /** Append the argument (for chaining) */
-       public SystemCall arg(String arg) {
-               if (command == null)
-                       command = new ArrayList<Object>();
-               command.add(arg);
-               return this;
-       }
-
-       /** Append the argument (for chaining) */
-       public SystemCall arg(String arg, String value) {
-               if (command == null)
-                       command = new ArrayList<Object>();
-               command.add(arg);
-               command.add(value);
-               return this;
-       }
-
-       // CONTROL
-       public synchronized Boolean isRunning() {
-               return currentWatchdog != null;
-       }
-
-       private synchronized ExecuteWatchdog createWatchdog() {
-//             if (currentWatchdog != null)
-//                     throw new SlcException("A process is already being monitored");
-               currentWatchdog = new ExecuteWatchdog(watchdogTimeout);
-               return currentWatchdog;
-       }
-
-       private synchronized void releaseWatchdog() {
-               currentWatchdog = null;
-       }
-
-       public synchronized void kill() {
-               if (currentWatchdog != null)
-                       currentWatchdog.destroyProcess();
-       }
-
-       /** */
-       public void setCmd(String command) {
-               this.cmd = command;
-       }
-
-       public void setCommand(List<Object> command) {
-               this.command = command;
-       }
-
-       public void setExecDir(String execdir) {
-               this.execDir = execdir;
-       }
-
-       public void setStdErrLogLevel(String stdErrLogLevel) {
-               this.stdErrLogLevel = stdErrLogLevel;
-       }
-
-       public void setStdOutLogLevel(String stdOutLogLevel) {
-               this.stdOutLogLevel = stdOutLogLevel;
-       }
-
-       public void setSynchronous(Boolean synchronous) {
-               this.synchronous = synchronous;
-       }
-
-       public void setOsCommands(Map<String, List<Object>> osCommands) {
-               this.osCommands = osCommands;
-       }
-
-       public void setOsCmds(Map<String, String> osCmds) {
-               this.osCmds = osCmds;
-       }
-
-       public void setEnvironmentVariables(Map<String, String> environmentVariables) {
-               this.environmentVariables = environmentVariables;
-       }
-
-       public Map<String, String> getEnvironmentVariables() {
-               return environmentVariables;
-       }
-
-       public void setWatchdogTimeout(Long watchdogTimeout) {
-               this.watchdogTimeout = watchdogTimeout;
-       }
-
-       public void setStdOutFile(Resource stdOutFile) {
-               this.stdOutFile = stdOutFile;
-       }
-
-       public void setStdErrFile(Resource stdErrFile) {
-               this.stdErrFile = stdErrFile;
-       }
-
-       public void setStdInFile(Resource stdInFile) {
-               this.stdInFile = stdInFile;
-       }
-
-       public void setTestResult(TestResult testResult) {
-               this.testResult = testResult;
-       }
-
-       public void setLogCommand(Boolean logCommand) {
-               this.logCommand = logCommand;
-       }
-
-       public void setRedirectStreams(Boolean redirectStreams) {
-               this.redirectStreams = redirectStreams;
-       }
-
-       public void setExceptionOnFailed(Boolean exceptionOnFailed) {
-               this.exceptionOnFailed = exceptionOnFailed;
-       }
-
-       public void setMergeEnvironmentVariables(Boolean mergeEnvironmentVariables) {
-               this.mergeEnvironmentVariables = mergeEnvironmentVariables;
-       }
-
-       public void setOsConsole(String osConsole) {
-               this.osConsole = osConsole;
-       }
-
-       public void setGenerateScript(String generateScript) {
-               this.generateScript = generateScript;
-       }
-
-       public void setExecutionResources(ExecutionResources executionResources) {
-               this.executionResources = executionResources;
-       }
-
-       public void setRedirectStdOut(Boolean redirectStdOut) {
-               this.redirectStdOut = redirectStdOut;
-       }
-
-       public void addOutputListener(SystemCallOutputListener outputListener) {
-               outputListeners.add(outputListener);
-       }
-
-       public void removeOutputListener(SystemCallOutputListener outputListener) {
-               outputListeners.remove(outputListener);
-       }
-
-       public void setOutputListeners(
-                       List<SystemCallOutputListener> outputListeners) {
-               this.outputListeners = outputListeners;
-       }
-
-       public void setExecutor(Executor executor) {
-               this.executor = executor;
-       }
-
-       public void setSudo(String sudo) {
-               this.sudo = sudo;
-       }
-
-       public void setCallbackHandler(CallbackHandler callbackHandler) {
-               this.callbackHandler = callbackHandler;
-       }
-
-       public void setChroot(String chroot) {
-               this.chroot = chroot;
-       }
-
-       private class DummyexecuteStreamHandler implements ExecuteStreamHandler {
-
-               public void setProcessErrorStream(InputStream is) throws IOException {
-               }
-
-               public void setProcessInputStream(OutputStream os) throws IOException {
-               }
-
-               public void setProcessOutputStream(InputStream is) throws IOException {
-               }
-
-               public void start() throws IOException {
-               }
-
-               public void stop() {
-               }
-
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/SystemCallOutputListener.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/SystemCallOutputListener.java
deleted file mode 100644 (file)
index b28f1ad..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-public interface SystemCallOutputListener {
-       public void newLine(SystemCall systemCall, String line, Boolean isError);
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/UploadAttachments.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/UploadAttachments.java
deleted file mode 100644 (file)
index 13cc519..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import org.argeo.slc.SlcException;
-import org.argeo.slc.core.attachment.Attachment;
-import org.argeo.slc.core.attachment.AttachmentUploader;
-import org.argeo.slc.core.attachment.AttachmentsEnabled;
-import org.springframework.core.io.Resource;
-
-public class UploadAttachments implements Runnable {
-       private AttachmentUploader attachmentUploader;
-       private Attachment attachment = null;
-       private Resource resource = null;
-       private Map<Attachment, Resource> attachments = new HashMap<Attachment, Resource>();
-       private List<AttachmentsEnabled> attachTo = new ArrayList<AttachmentsEnabled>();
-       private Boolean newUuidPerExecution = true;
-
-       public void run() {
-               if (attachment != null) {
-                       if (resource == null)
-                               throw new SlcException("A resource must be specified.");
-                       uploadAndAdd(attachment, resource);
-               }
-
-               for (Attachment attachmentT : attachments.keySet()) {
-                       Resource resourceT = attachments.get(attachmentT);
-                       uploadAndAdd(attachmentT, resourceT);
-               }
-
-       }
-
-       protected void uploadAndAdd(Attachment attachment, Resource resource) {
-               if (newUuidPerExecution)
-                       attachment.setUuid(UUID.randomUUID().toString());
-               attachmentUploader.upload(attachment, resource);
-               for (AttachmentsEnabled attachmentsEnabled : attachTo) {
-                       attachmentsEnabled.addAttachment(attachment);
-               }
-       }
-
-       public void setAttachmentUploader(AttachmentUploader attachmentUploader) {
-               this.attachmentUploader = attachmentUploader;
-       }
-
-       public void setAttachments(Map<Attachment, Resource> attachments) {
-               this.attachments = attachments;
-       }
-
-       public void setAttachTo(List<AttachmentsEnabled> attachTo) {
-               this.attachTo = attachTo;
-       }
-
-       public void setAttachment(Attachment attachment) {
-               this.attachment = attachment;
-       }
-
-       public void setResource(Resource resource) {
-               this.resource = resource;
-       }
-
-       public void setNewUuidPerExecution(Boolean newUuidPerExecution) {
-               this.newUuidPerExecution = newUuidPerExecution;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/core.xml b/org.argeo.slc.core/src/org/argeo/slc/core/execution/tasks/core.xml
deleted file mode 100644 (file)
index df35944..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (C) 2007-2012 Argeo GmbH
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-            http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
-       xsi:schemaLocation="
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
-
-       <bean id="task.echo" class="org.argeo.slc.core.execution.tasks.Echo"
-               abstract="true" />
-       <bean id="task.systemCall" class="org.argeo.slc.core.execution.tasks.SystemCall"
-               abstract="true" />
-       <bean id="task.closeTestResult" class="org.argeo.slc.core.execution.tasks.CloseTestResult"
-               abstract="true" />
-       <bean id="task.slcManager" class="org.argeo.slc.core.execution.tasks.SlcManager"
-               abstract="true" />
-       <bean id="task.overrideContextAware" class="org.argeo.slc.core.execution.tasks.OverrideContextAware"
-               abstract="true" />
-       <bean id="task.uploadAttachments" class="org.argeo.slc.core.execution.tasks.UploadAttachments"
-               abstract="true" />
-
-       <bean id="taskArg.attachment" class="org.argeo.slc.core.attachment.SimpleAttachment"
-               abstract="true" />
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/templates.xml b/org.argeo.slc.core/src/org/argeo/slc/core/execution/templates.xml
deleted file mode 100644 (file)
index 28b742a..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (C) 2007-2012 Argeo GmbH
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-            http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
-       xsi:schemaLocation="
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
-
-       <bean id="slcTemplate.fileResources" class="org.argeo.slc.core.execution.FileExecutionResources"
-               abstract="true" />
-
-       <bean id="slcTemplate.resourcesFactoryBean" parent="slcTemplate.writableResource"
-               abstract="true" />
-
-       <bean id="slcTemplate.writableResource"
-               class="org.argeo.slc.core.execution.ExecutionResourcesFactoryBean"
-               abstract="true" />
-
-       <bean id="slcTemplate.osFile" class="org.argeo.slc.core.execution.OsFileFactoryBean"
-               abstract="true" />
-
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/utils.xml b/org.argeo.slc.core/src/org/argeo/slc/core/execution/utils.xml
deleted file mode 100644 (file)
index 527e701..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (C) 2007-2012 Argeo GmbH
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-            http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="
-       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
-       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
-       <bean id="mergedLists" class="org.argeo.slc.core.execution.tasks.MergedLists"
-               abstract="true">
-       </bean>
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/AsFlowDecorator.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/AsFlowDecorator.java
deleted file mode 100644 (file)
index dceec1c..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.core.execution.DefaultExecutionFlow;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.springframework.beans.BeanMetadataElement;
-import org.springframework.beans.factory.config.BeanDefinitionHolder;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.ManagedList;
-import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Node;
-
-/** Publishes a {@link Runnable} as an {@link ExecutionFlow} */
-public class AsFlowDecorator implements BeanDefinitionDecorator {
-       private Log log = LogFactory.getLog(AsFlowDecorator.class);
-
-       public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder bean,
-                       ParserContext ctx) {
-               String attrValue = ((Attr) node).getValue();
-               if (attrValue.charAt(attrValue.length() - 1) == '/')
-                       throw new SlcException(attrValue + " cannot end with a path");
-               final String flowBeanName = attrValue;
-
-               if (log.isTraceEnabled())
-                       log.trace("flowBeanName=" + flowBeanName);
-
-               if (ctx.getRegistry().containsBeanDefinition(flowBeanName))
-                       throw new SlcException("A bean named " + flowBeanName
-                                       + " is already defined.");
-               BeanDefinitionBuilder flow = BeanDefinitionBuilder
-                               .rootBeanDefinition(DefaultExecutionFlow.class);
-               ManagedList<BeanMetadataElement> executables = new ManagedList<BeanMetadataElement>(
-                               1);
-
-               String beanName = bean.getBeanName();
-               if (beanName == null)
-                       executables.add(bean.getBeanDefinition());
-               else
-                       executables.add(new RuntimeBeanReference(beanName));
-
-               // if (path != null)
-               // flow.addPropertyValue("path", path);
-               flow.addPropertyValue("executables", executables);
-
-               if (beanName != null)
-                       ctx.getRegistry().registerBeanDefinition(flowBeanName,
-                                       flow.getBeanDefinition());
-               return bean;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/ExecutionScopeDecorator.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/ExecutionScopeDecorator.java
deleted file mode 100644 (file)
index dfca9d5..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.xml;\r
-\r
-import org.springframework.aop.scope.ScopedProxyUtils;\r
-import org.springframework.beans.factory.config.BeanDefinitionHolder;\r
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;\r
-import org.springframework.beans.factory.xml.BeanDefinitionDecorator;\r
-import org.springframework.beans.factory.xml.ParserContext;\r
-import org.w3c.dom.Element;\r
-import org.w3c.dom.Node;\r
-\r
-/**\r
- * Inspired by org.springframework.aop.config.ScopedProxyBeanDefinitionDecorator\r
- */\r
-public class ExecutionScopeDecorator implements BeanDefinitionDecorator {      \r
-       private static final String PROXY_TARGET_CLASS = "proxy-target-class";  \r
-       \r
-       public BeanDefinitionHolder decorate(Node node,\r
-                       BeanDefinitionHolder definition, ParserContext parserContext) {\r
-               \r
-               definition.getBeanDefinition().setScope("execution");\r
-               \r
-               // Default: CGLib not used\r
-               boolean proxyTargetClass = false;\r
-               if (node instanceof Element) {\r
-                       Element ele = (Element) node;\r
-                       if (ele.hasAttribute(PROXY_TARGET_CLASS)) {\r
-                               proxyTargetClass = Boolean.valueOf(ele.getAttribute(PROXY_TARGET_CLASS)).booleanValue();\r
-                       }\r
-               }\r
-               \r
-               // Register the original bean definition as it will be referenced by the scoped proxy and is relevant for tooling (validation, navigation).\r
-               String targetBeanName = ScopedProxyUtils.getTargetBeanName(definition.getBeanName());\r
-               parserContext.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(definition.getBeanDefinition(), targetBeanName));\r
-               \r
-               return ScopedProxyUtils.createScopedProxy(definition, parserContext.getRegistry(), proxyTargetClass);           \r
-       }\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/FlowBeanDefinitionParser.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/FlowBeanDefinitionParser.java
deleted file mode 100644 (file)
index 7d2ab49..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.core.execution.DefaultExecutionFlow;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.springframework.beans.factory.BeanDefinitionStoreException;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.ManagedList;
-import org.springframework.beans.factory.support.ManagedMap;
-import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.util.StringUtils;
-import org.springframework.util.xml.DomUtils;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/** Interprets the <flow:flow> tag */
-public class FlowBeanDefinitionParser extends
-               AbstractSingleBeanDefinitionParser {
-       private Log log = LogFactory.getLog(FlowBeanDefinitionParser.class);
-
-       /** Whether the user has already be warned on path attribute usage. */
-       private Boolean warnedAboutPathAttribute = false;
-
-       @Override
-       protected void doParse(Element element, ParserContext parserContext,
-                       BeanDefinitionBuilder builder) {
-               String path = element.getAttribute("path");
-               if (StringUtils.hasText(path)) {
-                       builder.addPropertyValue("path", path);
-
-                       // warns user only once
-                       if (!warnedAboutPathAttribute)
-                               log.warn("The path=\"\" attribute is deprecated"
-                                               + " and will be removed in a later release."
-                                               + " Use <flow:flow name=\"/my/path/flowName\">.");
-                       warnedAboutPathAttribute = true;
-               }
-
-               String spec = element.getAttribute("spec");
-               if (StringUtils.hasText(spec))
-                       builder.getBeanDefinition().getConstructorArgumentValues()
-                                       .addGenericArgumentValue(new RuntimeBeanReference(spec));
-
-               String abstrac = element.getAttribute("abstract");
-               if (StringUtils.hasText(abstrac))
-                       builder.setAbstract(Boolean.parseBoolean(abstrac));
-
-               String parent = element.getAttribute("parent");
-               if (StringUtils.hasText(parent))
-                       builder.setParentName(parent);
-
-               builder.getBeanDefinition().setDescription(
-                               DomUtils.getChildElementValueByTagName(element, "description"));
-
-               List<Element> argsElems = new ArrayList<Element>();
-               List<Element> execElems = new ArrayList<Element>();
-               List<Element> specElems = new ArrayList<Element>();
-               NodeList nodeList = element.getChildNodes();
-               for (int i = 0; i < nodeList.getLength(); i++) {
-                       Node node = nodeList.item(i);
-                       if (node instanceof Element) {
-                               if (DomUtils.nodeNameEquals(node, "arg"))
-                                       argsElems.add((Element) node);
-                               else if (DomUtils.nodeNameEquals(node, "spec"))
-                                       specElems.add((Element) node);
-                               else if (!DomUtils.nodeNameEquals(node, "description"))
-                                       execElems.add((Element) node);
-                       }
-               }
-
-               // Arguments
-               if (argsElems.size() != 0) {
-                       ManagedMap<String, Object> args = new ManagedMap<String, Object>(
-                                       argsElems.size());
-                       for (Element argElem : argsElems) {
-                               Object value = NamespaceUtils.parseValue(argElem,
-                                               parserContext, builder.getBeanDefinition(), null);
-                               if (value != null)
-                                       args.put(argElem.getAttribute("name"), value);
-                               else
-                                       throw new SlcException("No value defined.");
-                       }
-                       builder.getBeanDefinition().getConstructorArgumentValues()
-                                       .addGenericArgumentValue(args);
-               }
-
-               // Execution specs
-               if (StringUtils.hasText(spec) && specElems.size() != 0)
-                       throw new SlcException("A flow cannot have multiple specs");
-               if (specElems.size() == 1) {
-                       Object specObj = NamespaceUtils.parseBeanOrReference(
-                                       specElems.get(0), parserContext,
-                                       builder.getBeanDefinition());
-                       builder.getBeanDefinition().getConstructorArgumentValues()
-                                       .addGenericArgumentValue(specObj);
-               } else if (specElems.size() > 1)
-                       throw new SlcException("A flow cannot have multiple specs");
-
-               // Executables
-               if (execElems.size() != 0) {
-                       ManagedList<Object> executables = new ManagedList<Object>(
-                                       execElems.size());
-                       for (Element child : execElems) {
-                               // child validity check is performed in xsd
-                               executables.add(NamespaceUtils.parseBeanOrReference(child,
-                                               parserContext, builder.getBeanDefinition()));
-                       }
-                       if (executables.size() > 0)
-                               builder.addPropertyValue("executables", executables);
-               }
-       }
-
-       @SuppressWarnings("unchecked")
-       @Override
-       protected Class<? extends ExecutionFlow> getBeanClass(Element element) {
-               String clss = element.getAttribute("class");
-               if (StringUtils.hasText(clss))
-                       // TODO: check that it actually works
-                       try {
-                               return (Class<? extends ExecutionFlow>) getClass()
-                                               .getClassLoader().loadClass(clss);
-                       } catch (ClassNotFoundException e) {
-                               try {
-                                       return (Class<? extends ExecutionFlow>) Thread
-                                                       .currentThread().getContextClassLoader()
-                                                       .loadClass(clss);
-                               } catch (ClassNotFoundException e1) {
-                                       throw new SlcException("Cannot load class " + clss, e);
-                               }
-                       }
-               else
-                       return DefaultExecutionFlow.class;
-       }
-
-       // parse nested bean definition
-       // private Object parseBeanReference(Element element,
-       // ParserContext parserContext, BeanDefinitionBuilder builder) {
-       // return parserContext.getDelegate().parsePropertySubElement(element,
-       // builder.getBeanDefinition());
-       // }
-
-       @Override
-       protected String resolveId(Element element,
-                       AbstractBeanDefinition definition, ParserContext parserContext)
-                       throws BeanDefinitionStoreException {
-               String name = element.getAttribute("name");
-               if (StringUtils.hasText(name)) {
-                       return name;
-               } else {
-                       return super.resolveId(element, definition, parserContext);
-               }
-       }
-
-       protected boolean shouldGenerateIdAsFallback() {
-               return true;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/FlowNamespaceHandler.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/FlowNamespaceHandler.java
deleted file mode 100644 (file)
index 2deba8b..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
-
-public class FlowNamespaceHandler extends NamespaceHandlerSupport {
-
-       public void init() {
-               registerBeanDefinitionParser("flow", new FlowBeanDefinitionParser());
-               registerBeanDefinitionParser("spec", new SpecBeanDefinitionParser());
-               registerBeanDefinitionDecoratorForAttribute("as-flow",
-                               new AsFlowDecorator());
-               registerBeanDefinitionParser("param", new ParamDecorator());
-                
-               // The objective was to replace
-               // - attribute scope="execution"
-               // - and element "aop:scoped-proxy" 
-               // by a single attribute, using an attribute decorator 
-               // this does not work correctly with other attribute decorators (e.g. 
-               // p namespace) since this decorator needs to be called after all
-               // properties have been set on target bean. 
-               // It works properly with element decorators (called after all attribute
-               // decorators
-               registerBeanDefinitionDecorator("variable", new ExecutionScopeDecorator());
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/NamespaceUtils.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/NamespaceUtils.java
deleted file mode 100644 (file)
index ccf94f1..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.util.xml.DomUtils;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Utilities to simplify common tasks when interpreting a custom namespace and
- * converting it into bean definitions.
- */
-public class NamespaceUtils {
-       // private final static Log log = LogFactory.getLog(NamespaceUtils.class);
-
-       /**
-        * Returns the value defined either: directly by the the 'value' attribute,
-        * as reference by the 'ref' attribute or as a nested bean.
-        */
-       public static Object parseValue(Element element,
-                       ParserContext parserContext,
-                       BeanDefinition containingBeanDefintion, String valueTagName) {
-               Object value = null;
-               if (element.hasAttribute("value")) {
-                       value = element.getAttribute("value");
-               }
-
-               if (element.hasAttribute("ref")) {
-                       if (value != null)
-                               throw new SlcException("Multiple value definition for "
-                                               + element);
-                       value = new RuntimeBeanReference(element.getAttribute("ref"));
-               }
-
-               Element uniqueSubElem = null;
-               if (valueTagName != null) {
-                       Element valueElem = DomUtils.getChildElementByTagName(element,
-                                       valueTagName);
-                       if (valueElem != null) {
-                               uniqueSubElem = findUniqueSubElement(valueElem);
-                               if (uniqueSubElem == null)
-                                       throw new SlcException("No subelement found under "
-                                                       + valueElem);
-                       }
-               } else {// no intermediary tag
-                       uniqueSubElem = findUniqueSubElement(element);
-               }
-
-               if (uniqueSubElem != null) {
-                       if (value != null)
-                               throw new SlcException("Multiple value definition for "
-                                               + element);
-                       value = parseBeanOrReference(uniqueSubElem, parserContext,
-                                       containingBeanDefintion);
-               }
-               return value;
-       }
-
-       public static Element findUniqueSubElement(Element element) {
-               NodeList childNodes = element.getChildNodes();
-
-               Element uniqueSubElem = null;
-               for (int i = 0; i < childNodes.getLength(); i++) {
-                       Node node = childNodes.item(i);
-                       if (node != null && node instanceof Element) {
-                               if (uniqueSubElem == null)
-                                       uniqueSubElem = (Element) node;
-                               else
-                                       throw new SlcException(
-                                                       "There are more than one sub element under "
-                                                                       + element);
-                       }
-               }
-               return uniqueSubElem;
-       }
-
-       public static Object parseBeanOrReference(Element element,
-                       ParserContext parserContext, BeanDefinition beanDefinition) {
-               // return parserContext.getDelegate().parsePropertySubElement(element,
-               // beanDefinition);
-
-               BeanDefinitionParserDelegate deleg = parserContext.getDelegate();
-               // if ("bean".equals(element.getNodeName()))
-               // return deleg.parseBeanDefinitionElement(element, beanDefinition);
-               // else
-               return deleg.parsePropertySubElement(element, beanDefinition);
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/ParamDecorator.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/ParamDecorator.java
deleted file mode 100644 (file)
index 16839c0..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import org.argeo.slc.core.execution.ParameterRef;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.util.StringUtils;
-import org.w3c.dom.Element;
-
-public class ParamDecorator extends AbstractSingleBeanDefinitionParser {
-
-       // public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder
-       // bean,
-       // ParserContext ctx) {
-       // String paramName = ((Element) node).getAttribute("name");
-       // String propertyName = ((Element) node.getParentNode())
-       // .getAttribute("name");
-       // BeanDefinitionBuilder parameterRef = BeanDefinitionBuilder
-       // .genericBeanDefinition(ParameterRef.class);
-       // parameterRef.addPropertyReference("instantiationManager",
-       // "instantiationManager");
-       // parameterRef.addConstructorArgValue(paramName);
-       // bean.getBeanDefinition().getPropertyValues().addPropertyValue(
-       // propertyName, parameterRef.getBeanDefinition());
-       // return bean;
-       // }
-
-       @Override
-       protected void doParse(Element element, ParserContext parserContext,
-                       BeanDefinitionBuilder builder) {
-               String paramName = element.getAttribute("name");
-
-               String instantationManagerRef = element
-                               .getAttribute("instantiationManager");
-               if (!StringUtils.hasText(instantationManagerRef))
-                       instantationManagerRef = "instantiationManager";
-               builder.addPropertyReference("instantiationManager",
-                               instantationManagerRef);
-               builder.addConstructorArgValue(paramName);
-       }
-
-       @Override
-       protected Class<ParameterRef> getBeanClass(Element element) {
-               return ParameterRef.class;
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/SpecBeanDefinitionParser.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/SpecBeanDefinitionParser.java
deleted file mode 100644 (file)
index 761e26d..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.core.execution.DefaultExecutionSpec;
-import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
-import org.argeo.slc.core.execution.RefSpecAttribute;
-import org.argeo.slc.core.execution.RefValueChoice;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.ManagedList;
-import org.springframework.beans.factory.support.ManagedMap;
-import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.util.StringUtils;
-import org.springframework.util.xml.DomUtils;
-import org.w3c.dom.Element;
-
-/** Interprets the <flow:spec> tag */
-public class SpecBeanDefinitionParser extends
-               AbstractSingleBeanDefinitionParser {
-       private Log log = LogFactory.getLog(SpecBeanDefinitionParser.class);
-
-       @Override
-       protected void doParse(Element element, ParserContext parserContext,
-                       BeanDefinitionBuilder builder) {
-               builder.getBeanDefinition().setDescription(
-                               DomUtils.getChildElementValueByTagName(element, "description"));
-
-               ManagedMap<String, BeanDefinition> attributes = new ManagedMap<String, BeanDefinition>();
-
-               // Primitives
-               for (Element child : (List<Element>) DomUtils
-                               .getChildElementsByTagName(element, "primitive")) {
-                       BeanDefinitionBuilder childBuilder = BeanDefinitionBuilder
-                                       .genericBeanDefinition(PrimitiveSpecAttribute.class);
-                       addCommonProperties(child, parserContext, childBuilder);
-
-                       String type = child.getAttribute("type");
-                       if (StringUtils.hasText(type))
-                               childBuilder.addPropertyValue("type", type);
-
-                       putInAttributes(attributes, child,
-                                       childBuilder.getBeanDefinition(), "primitive");
-               }
-
-               // Refs
-               for (Element refAttrElem : (List<Element>) DomUtils
-                               .getChildElementsByTagName(element, "ref")) {
-                       BeanDefinitionBuilder refAttrBuilder = BeanDefinitionBuilder
-                                       .genericBeanDefinition(RefSpecAttribute.class);
-                       addCommonProperties(refAttrElem, parserContext, refAttrBuilder);
-
-                       String targetClassName = refAttrElem.getAttribute("targetClass");
-                       if (StringUtils.hasText(targetClassName))
-                               refAttrBuilder.addPropertyValue("targetClass", targetClassName);
-
-                       // Choices
-                       Element choicesElem = DomUtils.getChildElementByTagName(
-                                       refAttrElem, "choices");
-                       if (choicesElem != null) {
-                               List<Element> choices = DomUtils.getChildElementsByTagName(
-                                               choicesElem, "choice");
-                               ManagedList<BeanDefinition> choiceBeans = new ManagedList<BeanDefinition>(
-                                               choices.size());
-                               for (Element choiceElem : choices) {
-                                       BeanDefinitionBuilder choiceBuilder = BeanDefinitionBuilder
-                                                       .genericBeanDefinition(RefValueChoice.class);
-                                       choiceBuilder.addPropertyValue("name",
-                                                       choiceElem.getAttribute("name"));
-                                       String desc = choiceElem.getAttribute("description");
-                                       if (StringUtils.hasText(desc))
-                                               choiceBuilder.addPropertyValue("description", desc);
-
-                                       choiceBeans.add(choiceBuilder.getBeanDefinition());
-                               }
-                               refAttrBuilder.addPropertyValue("choices", choiceBeans);
-                       }
-
-                       putInAttributes(attributes, refAttrElem,
-                                       refAttrBuilder.getBeanDefinition(), "ref");
-               }
-
-               builder.addPropertyValue("attributes", attributes);
-       }
-
-       protected void addCommonProperties(Element element,
-                       ParserContext parserContext, BeanDefinitionBuilder specAttr) {
-               addBooleanProperty("isImmutable", specAttr, element);
-               addBooleanProperty("isConstant", specAttr, element);
-               addBooleanProperty("isHidden", specAttr, element);
-               addBooleanProperty("isParameter", specAttr, element);
-               addBooleanProperty("isFrozen", specAttr, element);
-
-               Object value = NamespaceUtils.parseValue(element, parserContext,
-                               specAttr.getBeanDefinition(), "value");
-               if (value != null)
-                       specAttr.addPropertyValue("value", value);
-
-       }
-
-       protected void putInAttributes(
-                       ManagedMap<String, BeanDefinition> attributes, Element child,
-                       BeanDefinition beanDefinition, String nature) {
-               String name = child.getAttribute("name");
-               attributes.put(name, beanDefinition);
-               if (log.isTraceEnabled())
-                       log.debug("Added " + nature + " attribute " + name);
-
-       }
-
-       private void addBooleanProperty(String name,
-                       BeanDefinitionBuilder specAttr, Element element) {
-               String bool = element.getAttribute(name);
-               if (StringUtils.hasText(bool))
-                       specAttr.addPropertyValue(name, Boolean.parseBoolean(bool));
-
-       }
-
-       @Override
-       protected Class<DefaultExecutionSpec> getBeanClass(Element element) {
-               return DefaultExecutionSpec.class;
-       }
-
-       protected boolean shouldGenerateIdAsFallback() {
-               return false;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/slc-flow-0.12.xsd b/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/slc-flow-0.12.xsd
deleted file mode 100644 (file)
index 8b31a60..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
-       xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns:beans="http://www.springframework.org/schema/beans"
-       targetNamespace="http://www.argeo.org/schema/slc-flow"
-       elementFormDefault="qualified" attributeFormDefault="unqualified">
-
-       <xsd:import namespace="http://www.springframework.org/schema/beans"
-               schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" />
-
-       <xsd:annotation>
-               <xsd:documentation><![CDATA[
-       SLC Flow Schema, version 0.12
-       Authors: Mathieu Baudier
-       
-       This simplifies the definition of SLC flows and their integration with 
-       regular Spring beans.
-               ]]></xsd:documentation>
-       </xsd:annotation>
-
-       <xsd:element name="flow">
-               <xsd:annotation>
-                       <xsd:documentation><![CDATA[
-       Adds an SLC execution flow, using the default implementation.
-                       ]]></xsd:documentation>
-               </xsd:annotation>
-               <xsd:complexType>
-                       <xsd:complexContent>
-                               <xsd:extension base="beans:identifiedType">
-                                       <xsd:sequence>
-                                               <xsd:element ref="beans:description" minOccurs="0" />
-                                               <xsd:sequence>
-                                                       <xsd:element name="arg" minOccurs="0" maxOccurs="unbounded"
-                                                               type="flow:argType">
-                                                               <xsd:annotation>
-                                                                       <xsd:documentation><![CDATA[
-       Parameter for an execution flow which will override at instantiation the 
-       value of the parameter already defined as default value or in a parent bean.
-                                                                       ]]></xsd:documentation>
-                                                               </xsd:annotation>
-                                                       </xsd:element>
-                                               </xsd:sequence>
-                                               <xsd:sequence>
-                                                       <xsd:choice minOccurs="0" maxOccurs="unbounded">
-                                                               <xsd:element ref="beans:bean" />
-                                                               <xsd:element ref="beans:ref" />
-                                                               <xsd:element ref="flow:flow" />
-                                                       </xsd:choice>
-                                                       <!--
-                                                               <xsd:any namespace="##other" processContents="strict"
-                                                               minOccurs="0" maxOccurs="unbounded" />
-                                                       -->
-                                               </xsd:sequence>
-                                       </xsd:sequence>
-                                       <xsd:attribute name="name" type="xsd:string">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       Name of the flow (alternative to ID).
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                                       <xsd:attribute name="class" type="xsd:string">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       Another implementation of execution flow.
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                                       <xsd:attribute name="path" type="xsd:string">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       The hierarchical path under which to register this flow.
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                                       <xsd:attribute name="spec" type="xsd:string">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       A reference to the related specification bean.
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                                       <xsd:attribute name="parent" type="xsd:string">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       The parent bean definition (in Spring sense).
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                                       <xsd:attribute name="abstract" type="xsd:boolean"
-                                               default="false">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       Whether this flow is abstract (in Spring sense).
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                               </xsd:extension>
-                       </xsd:complexContent>
-               </xsd:complexType>
-       </xsd:element>
-
-       <xsd:element name="spec">
-               <xsd:annotation>
-                       <xsd:documentation><![CDATA[
-       SLC flow specifications, defining the parameters and variables
-       which can be used in related flows, along with their default values and 
-       various constraints.
-                       ]]></xsd:documentation>
-               </xsd:annotation>
-               <xsd:complexType>
-                       <xsd:complexContent>
-                               <xsd:extension base="beans:identifiedType">
-                                       <xsd:sequence>
-                                               <xsd:element ref="beans:description" minOccurs="0" />
-                                               <xsd:choice minOccurs="0" maxOccurs="unbounded">
-                                                       <xsd:element name="primitive" type="flow:primitiveSpecAttributeType"
-                                                               minOccurs="0" maxOccurs="unbounded">
-                                                               <xsd:annotation>
-                                                                       <xsd:documentation><![CDATA[
-       A primitive specification attribute, that is, a plain standard value
-       and not a reference to an object.
-                                                                       ]]></xsd:documentation>
-                                                               </xsd:annotation>
-                                                       </xsd:element>
-                                                       <xsd:element name="ref" type="flow:refSpecAttributeType"
-                                                               minOccurs="0" maxOccurs="unbounded">
-                                                               <xsd:annotation>
-                                                                       <xsd:documentation><![CDATA[
-       A reference specification attribute, that is, a reference to another object.
-                                                                       ]]></xsd:documentation>
-                                                               </xsd:annotation>
-                                                       </xsd:element>
-                                               </xsd:choice>
-                                       </xsd:sequence>
-                               </xsd:extension>
-                       </xsd:complexContent>
-               </xsd:complexType>
-       </xsd:element>
-
-       <xsd:complexType name="specAttributeType">
-               <xsd:choice>
-                       <xsd:element name="value" minOccurs="0" maxOccurs="1">
-                               <xsd:annotation>
-                                       <xsd:documentation><![CDATA[
-       The default value of the attribute as an inner bean.
-                                       ]]></xsd:documentation>
-                               </xsd:annotation>
-                               <xsd:complexType>
-                                       <xsd:choice minOccurs="1" maxOccurs="1">
-                                               <xsd:element ref="beans:bean" />
-                                               <xsd:element ref="beans:ref" />
-                                               <xsd:element ref="beans:list" />
-                                               <xsd:element ref="beans:set" />
-                                               <xsd:element ref="beans:map" />
-                                               <xsd:element ref="beans:props" />
-                                       </xsd:choice>
-                               </xsd:complexType>
-                       </xsd:element>
-               </xsd:choice>
-               <xsd:attribute name="name" use="required" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The name of the attribute, under which in can then be referenced.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="value" use="optional" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The default value of the attribute.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="ref" use="optional" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The default value of the attribute as a reference to another bean.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="isParameter" use="optional" type="xsd:boolean"
-                       default="false">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       Whether the attribute is a parameter, that is, it has to be set at 
-       instantiation but can be modified afterwards for objects of scope execution.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="isFrozen" use="optional" type="xsd:boolean"
-                       default="false">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       Whether the attribute is frozen, that is, it cannot be modified at runtime.
-       A frozen attribute has to be a parameter.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="isHidden" use="optional" type="xsd:boolean"
-                       default="false">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       Whether the attribute is hidden, that is, it should not be displayed in UIs.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-       </xsd:complexType>
-
-       <xsd:complexType name="primitiveSpecAttributeType">
-               <xsd:complexContent>
-                       <xsd:extension base="flow:specAttributeType">
-                               <xsd:attribute name="type" default="string">
-                                       <xsd:annotation>
-                                               <xsd:documentation><![CDATA[
-       The type of the primitive specification attribute.
-                                               ]]></xsd:documentation>
-                                       </xsd:annotation>
-                                       <xsd:simpleType>
-                                               <xsd:restriction base="xsd:string">
-                                                       <xsd:enumeration value="string" />
-                                                       <xsd:enumeration value="integer" />
-                                                       <xsd:enumeration value="long" />
-                                                       <xsd:enumeration value="float" />
-                                                       <xsd:enumeration value="double" />
-                                                       <xsd:enumeration value="boolean" />
-                                               </xsd:restriction>
-                                       </xsd:simpleType>
-                               </xsd:attribute>
-                       </xsd:extension>
-               </xsd:complexContent>
-       </xsd:complexType>
-
-       <xsd:complexType name="refSpecAttributeType">
-               <xsd:complexContent>
-                       <xsd:extension base="flow:specAttributeType">
-                               <xsd:choice>
-                                       <xsd:element name="choices" minOccurs="0" maxOccurs="1">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       Possible values to chose from, if ommitted, all the beans in the 
-       application context which implement the provided targetClass will 
-       be considered.
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                               <xsd:complexType>
-                                                       <xsd:choice>
-                                                               <xsd:element name="choice" minOccurs="0" maxOccurs="unbounded"
-                                                                       type="flow:refChoiceType">
-                                                                       <xsd:annotation>
-                                                                               <xsd:documentation><![CDATA[
-       A choice for a reference specification attribute.
-                                                                               ]]></xsd:documentation>
-                                                                       </xsd:annotation>
-                                                               </xsd:element>
-                                                       </xsd:choice>
-                                               </xsd:complexType>
-                                       </xsd:element>
-                               </xsd:choice>
-                               <xsd:attribute name="targetClass" use="required" type="xsd:string">
-                                       <xsd:annotation>
-                                               <xsd:documentation><![CDATA[
-       The class that has to be implemented by the underlying object.
-                                       ]]></xsd:documentation>
-                                       </xsd:annotation>
-                               </xsd:attribute>
-                       </xsd:extension>
-               </xsd:complexContent>
-       </xsd:complexType>
-
-       <xsd:complexType name="refChoiceType">
-               <xsd:attribute name="name" use="required" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The name of the related bean.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="description" use="optional" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       A human readable description of this choice.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-       </xsd:complexType>
-
-       <xsd:complexType name="argType">
-               <xsd:choice minOccurs="0" maxOccurs="1">
-                       <xsd:element ref="beans:bean" />
-                       <xsd:element ref="beans:ref" />
-                       <xsd:element ref="flow:param" />
-                       <xsd:element ref="beans:list" />
-                       <xsd:element ref="beans:set" />
-                       <xsd:element ref="beans:map" />
-                       <xsd:element ref="beans:props" />
-               </xsd:choice>
-               <xsd:attribute name="name" use="required" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The name of the related parameter.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="value" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The plain value of the related parameter.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="ref" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The value of the related parameter as a reference to a bean.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-       </xsd:complexType>
-
-       <xsd:attribute name="as-flow" type="xsd:string">
-               <xsd:annotation>
-                       <xsd:documentation><![CDATA[
-       If decorating an executable bean, it will generate an implicit SLC 
-       execution flow with the provided value as name.
-                       ]]></xsd:documentation>
-               </xsd:annotation>
-       </xsd:attribute>
-       <!--
-               <xsd:attribute name="var" type="xsd:boolean"> <xsd:annotation>
-               <xsd:documentation><![CDATA[ If true, the decorated bean is set to
-               scope execution and proxied. ]]></xsd:documentation> </xsd:annotation>
-               </xsd:attribute>
-       -->
-
-       <xsd:element name="variable">
-               <xsd:complexType>
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       Marks a bean definition as being variable, i.e. a scoped proxy of scope execution 
-                       ]]></xsd:documentation>
-                       </xsd:annotation>
-                       <xsd:attribute name="proxy-target-class" type="xsd:boolean"
-                               default="true">
-                               <xsd:annotation>
-                                       <xsd:documentation><![CDATA[
-                                               Are class-based (CGLIB) proxies to be created?
-                                               This is the default;
-                                               in order to switch to standard Java
-                                               interface-based proxies, turn this flag to
-                                               "false".
-                                       ]]></xsd:documentation>
-                               </xsd:annotation>
-                       </xsd:attribute>
-               </xsd:complexType>
-       </xsd:element>
-
-       <xsd:element name="param">
-               <xsd:annotation>
-                       <xsd:documentation><![CDATA[
-       If within a property tag of a bean, it will set the value of this property
-        with a reference to a parameter.
-                       ]]></xsd:documentation>
-               </xsd:annotation>
-               <xsd:complexType>
-                       <xsd:attribute name="name" type="xsd:string" use="required">
-                               <xsd:annotation>
-                                       <xsd:documentation><![CDATA[
-       The name of the related parameter.
-                                       ]]></xsd:documentation>
-                               </xsd:annotation>
-                       </xsd:attribute>
-                       <xsd:attribute name="instantiationManager" type="xsd:string"
-                               use="optional" default="instantiationManager">
-                               <xsd:annotation>
-                                       <xsd:documentation><![CDATA[
-       A reference to the instantiation manager to use instead of the default one
-       (expert usage).
-                                       ]]></xsd:documentation>
-                               </xsd:annotation>
-                       </xsd:attribute>
-               </xsd:complexType>
-       </xsd:element>
-
-</xsd:schema>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd b/org.argeo.slc.core/src/org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd
deleted file mode 100644 (file)
index a70798f..0000000
+++ /dev/null
@@ -1,402 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
-       xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns:beans="http://www.springframework.org/schema/beans"
-       targetNamespace="http://www.argeo.org/schema/slc-flow"
-       elementFormDefault="qualified" attributeFormDefault="unqualified">
-
-       <xsd:import namespace="http://www.springframework.org/schema/beans"
-               schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" />
-
-       <xsd:annotation>
-               <xsd:documentation><![CDATA[
-       SLC Flow Schema, version 1.2
-       Authors: Mathieu Baudier
-       
-       This simplifies the definition of SLC flows and their integration with 
-       regular Spring beans.
-               ]]></xsd:documentation>
-       </xsd:annotation>
-
-       <xsd:element name="flow">
-               <xsd:annotation>
-                       <xsd:documentation><![CDATA[
-       Adds an SLC execution flow, using the default implementation.
-                       ]]></xsd:documentation>
-               </xsd:annotation>
-               <xsd:complexType>
-                       <xsd:complexContent>
-                               <xsd:extension base="beans:identifiedType">
-                                       <xsd:sequence>
-                                               <xsd:element ref="beans:description" minOccurs="0" />
-                                               <xsd:sequence>
-                                                       <xsd:element name="arg" minOccurs="0" maxOccurs="unbounded"
-                                                               type="flow:argType">
-                                                               <xsd:annotation>
-                                                                       <xsd:documentation><![CDATA[
-       Parameter for an execution flow which will override at instantiation the 
-       value of the parameter already defined as default value or in a parent bean.
-                                                                       ]]></xsd:documentation>
-                                                               </xsd:annotation>
-                                                       </xsd:element>
-                                               </xsd:sequence>
-                                               <xsd:sequence>
-                                                       <xsd:choice minOccurs="0" maxOccurs="unbounded">
-                                                               <xsd:element ref="beans:bean" />
-                                                               <xsd:element ref="beans:ref" />
-                                                               <xsd:element ref="flow:flow" />
-                                                               <xsd:element ref="flow:spec" />
-                                                       </xsd:choice>
-                                                       <!-- <xsd:any namespace="##other" processContents="strict" minOccurs="0" 
-                                                               maxOccurs="unbounded" /> -->
-                                               </xsd:sequence>
-                                       </xsd:sequence>
-                                       <xsd:attribute name="name" type="xsd:string">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       Name of the flow (alternative to ID).
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                                       <xsd:attribute name="class" type="xsd:string">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       Another implementation of execution flow.
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                                       <xsd:attribute name="path" type="xsd:string">
-                                               <!-- DEPRECATED: not used anymore -->
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       The hierarchical path under which to register this flow.
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                                       <xsd:attribute name="spec" type="xsd:string">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       A reference to the related specification bean.
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                                       <xsd:attribute name="parent" type="xsd:string">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       The parent bean definition (in Spring sense).
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                                       <xsd:attribute name="abstract" type="xsd:boolean"
-                                               default="false">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       Whether this flow is abstract (in Spring sense).
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                       </xsd:attribute>
-                               </xsd:extension>
-                       </xsd:complexContent>
-               </xsd:complexType>
-       </xsd:element>
-
-       <xsd:element name="spec">
-               <xsd:annotation>
-                       <xsd:documentation><![CDATA[
-       SLC flow specifications, defining the parameters and variables
-       which can be used in related flows, along with their default values and 
-       various constraints.
-                       ]]></xsd:documentation>
-               </xsd:annotation>
-               <xsd:complexType>
-                       <xsd:complexContent>
-                               <xsd:extension base="beans:identifiedType">
-                                       <xsd:sequence>
-                                               <xsd:element ref="beans:description" minOccurs="0" />
-                                               <xsd:choice minOccurs="0" maxOccurs="unbounded">
-                                                       <xsd:element name="primitive" type="flow:primitiveSpecAttributeType"
-                                                               minOccurs="0" maxOccurs="unbounded">
-                                                               <xsd:annotation>
-                                                                       <xsd:documentation><![CDATA[
-       A primitive specification attribute, that is, a plain standard value
-       and not a reference to an object.
-                                                                       ]]></xsd:documentation>
-                                                               </xsd:annotation>
-                                                       </xsd:element>
-                                                       <xsd:element name="ref" type="flow:refSpecAttributeType"
-                                                               minOccurs="0" maxOccurs="unbounded">
-                                                               <xsd:annotation>
-                                                                       <xsd:documentation><![CDATA[
-       A reference specification attribute, that is, a reference to another object.
-                                                                       ]]></xsd:documentation>
-                                                               </xsd:annotation>
-                                                       </xsd:element>
-                                               </xsd:choice>
-                                       </xsd:sequence>
-                               </xsd:extension>
-                       </xsd:complexContent>
-               </xsd:complexType>
-       </xsd:element>
-
-       <xsd:complexType name="specAttributeType">
-               <xsd:choice>
-                       <xsd:element name="value" minOccurs="0" maxOccurs="1">
-                               <xsd:annotation>
-                                       <xsd:documentation><![CDATA[
-       The default value of the attribute as an inner bean.
-                                       ]]></xsd:documentation>
-                               </xsd:annotation>
-                               <xsd:complexType>
-                                       <xsd:choice minOccurs="1" maxOccurs="1">
-                                               <xsd:element ref="beans:bean" />
-                                               <xsd:element ref="beans:ref" />
-                                               <xsd:element ref="beans:list" />
-                                               <xsd:element ref="beans:set" />
-                                               <xsd:element ref="beans:map" />
-                                               <xsd:element ref="beans:props" />
-                                       </xsd:choice>
-                               </xsd:complexType>
-                       </xsd:element>
-               </xsd:choice>
-               <xsd:attribute name="name" use="required" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The name of the attribute, under which in can then be referenced.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="value" use="optional" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The default value of the attribute.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="ref" use="optional" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The default value of the attribute as a reference to another bean.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="isImmutable" use="optional" type="xsd:boolean"
-                       default="false">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       Whether the attribute is a parameter, that is, it has to be set at 
-       instantiation but can be modified afterwards for objects of scope execution.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="isParameter" use="optional" type="xsd:boolean"
-                       default="false">
-                       <!-- DEPRECATED: old name of isImmutable -->
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       Whether the attribute is a parameter, that is, it has to be set at 
-       instantiation but can be modified afterwards for objects of scope execution.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="isConstant" use="optional" type="xsd:boolean"
-                       default="false">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       Whether the attribute is frozen, that is, it cannot be modified at runtime.
-       A frozen attribute has to be a parameter.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="isFrozen" use="optional" type="xsd:boolean"
-                       default="false">
-                       <!-- DEPRECATED: old name of isConstant -->
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       Whether the attribute is frozen, that is, it cannot be modified at runtime.
-       A frozen attribute has to be a parameter.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="isHidden" use="optional" type="xsd:boolean"
-                       default="false">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       Whether the attribute is hidden, that is, it should not be displayed in UIs.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-       </xsd:complexType>
-
-       <xsd:complexType name="primitiveSpecAttributeType">
-               <xsd:complexContent>
-                       <xsd:extension base="flow:specAttributeType">
-                               <xsd:attribute name="type" default="string">
-                                       <xsd:annotation>
-                                               <xsd:documentation><![CDATA[
-       The type of the primitive specification attribute.
-                                               ]]></xsd:documentation>
-                                       </xsd:annotation>
-                                       <xsd:simpleType>
-                                               <xsd:restriction base="xsd:string">
-                                                       <xsd:enumeration value="string" />
-                                                       <xsd:enumeration value="password" />
-                                                       <xsd:enumeration value="integer" />
-                                                       <xsd:enumeration value="long" />
-                                                       <xsd:enumeration value="float" />
-                                                       <xsd:enumeration value="double" />
-                                                       <xsd:enumeration value="boolean" />
-                                               </xsd:restriction>
-                                       </xsd:simpleType>
-                               </xsd:attribute>
-                       </xsd:extension>
-               </xsd:complexContent>
-       </xsd:complexType>
-
-       <xsd:complexType name="refSpecAttributeType">
-               <xsd:complexContent>
-                       <xsd:extension base="flow:specAttributeType">
-                               <xsd:choice>
-                                       <xsd:element name="choices" minOccurs="0" maxOccurs="1">
-                                               <xsd:annotation>
-                                                       <xsd:documentation><![CDATA[
-       Possible values to chose from, if ommitted, all the beans in the 
-       application context which implement the provided targetClass will 
-       be considered.
-                                                       ]]></xsd:documentation>
-                                               </xsd:annotation>
-                                               <xsd:complexType>
-                                                       <xsd:choice>
-                                                               <xsd:element name="choice" minOccurs="0" maxOccurs="unbounded"
-                                                                       type="flow:refChoiceType">
-                                                                       <xsd:annotation>
-                                                                               <xsd:documentation><![CDATA[
-       A choice for a reference specification attribute.
-                                                                               ]]></xsd:documentation>
-                                                                       </xsd:annotation>
-                                                               </xsd:element>
-                                                       </xsd:choice>
-                                               </xsd:complexType>
-                                       </xsd:element>
-                               </xsd:choice>
-                               <xsd:attribute name="targetClass" use="required" type="xsd:string">
-                                       <xsd:annotation>
-                                               <xsd:documentation><![CDATA[
-       The class that has to be implemented by the underlying object.
-                                       ]]></xsd:documentation>
-                                       </xsd:annotation>
-                               </xsd:attribute>
-                       </xsd:extension>
-               </xsd:complexContent>
-       </xsd:complexType>
-
-       <xsd:complexType name="refChoiceType">
-               <xsd:attribute name="name" use="required" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The name of the related bean.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="description" use="optional" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       A human readable description of this choice.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-       </xsd:complexType>
-
-       <xsd:complexType name="argType">
-               <xsd:choice minOccurs="0" maxOccurs="1">
-                       <xsd:element ref="beans:bean" />
-                       <xsd:element ref="beans:ref" />
-                       <xsd:element ref="flow:param" />
-                       <xsd:element ref="beans:list" />
-                       <xsd:element ref="beans:set" />
-                       <xsd:element ref="beans:map" />
-                       <xsd:element ref="beans:props" />
-               </xsd:choice>
-               <xsd:attribute name="name" use="required" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The name of the related parameter.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="value" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The plain value of the related parameter.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-               <xsd:attribute name="ref" type="xsd:string">
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       The value of the related parameter as a reference to a bean.
-                               ]]></xsd:documentation>
-                       </xsd:annotation>
-               </xsd:attribute>
-       </xsd:complexType>
-
-       <xsd:attribute name="as-flow" type="xsd:string">
-               <xsd:annotation>
-                       <xsd:documentation><![CDATA[
-       If decorating an executable bean, it will generate an implicit SLC 
-       execution flow with the provided value as name.
-                       ]]></xsd:documentation>
-               </xsd:annotation>
-       </xsd:attribute>
-       <!-- <xsd:attribute name="var" type="xsd:boolean"> <xsd:annotation> <xsd:documentation><![CDATA[ 
-               If true, the decorated bean is set to scope execution and proxied. ]]></xsd:documentation> 
-               </xsd:annotation> </xsd:attribute> -->
-
-       <xsd:element name="variable">
-               <xsd:complexType>
-                       <xsd:annotation>
-                               <xsd:documentation><![CDATA[
-       Marks a bean definition as being variable, i.e. a scoped proxy of scope execution 
-                       ]]></xsd:documentation>
-                       </xsd:annotation>
-                       <xsd:attribute name="proxy-target-class" type="xsd:boolean"
-                               default="true">
-                               <xsd:annotation>
-                                       <xsd:documentation><![CDATA[
-                                               Are class-based (CGLIB) proxies to be created?
-                                               This is the default;
-                                               in order to switch to standard Java
-                                               interface-based proxies, turn this flag to
-                                               "false".
-                                       ]]></xsd:documentation>
-                               </xsd:annotation>
-                       </xsd:attribute>
-               </xsd:complexType>
-       </xsd:element>
-
-       <xsd:element name="param">
-               <xsd:annotation>
-                       <xsd:documentation><![CDATA[
-       If within a property tag of a bean, it will set the value of this property
-        with a reference to a parameter.
-                       ]]></xsd:documentation>
-               </xsd:annotation>
-               <xsd:complexType>
-                       <xsd:attribute name="name" type="xsd:string" use="required">
-                               <xsd:annotation>
-                                       <xsd:documentation><![CDATA[
-       The name of the related parameter.
-                                       ]]></xsd:documentation>
-                               </xsd:annotation>
-                       </xsd:attribute>
-                       <xsd:attribute name="instantiationManager" type="xsd:string"
-                               use="optional" default="instantiationManager">
-                               <xsd:annotation>
-                                       <xsd:documentation><![CDATA[
-       A reference to the instantiation manager to use instead of the default one
-       (expert usage).
-                                       ]]></xsd:documentation>
-                               </xsd:annotation>
-                       </xsd:attribute>
-               </xsd:complexType>
-       </xsd:element>
-
-</xsd:schema>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/BasicTestData.java b/org.argeo.slc.core/src/org/argeo/slc/core/test/BasicTestData.java
deleted file mode 100644 (file)
index 39a97f2..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import org.argeo.slc.test.TestData;\r
-\r
-public class BasicTestData implements TestData {\r
-       private Object expected;\r
-       private Object reached;\r
-\r
-       public Object getExpected() {\r
-               return expected;\r
-       }\r
-\r
-       public void setExpected(Object expected) {\r
-               this.expected = expected;\r
-       }\r
-\r
-       public Object getReached() {\r
-               return reached;\r
-       }\r
-\r
-       public void setReached(Object reached) {\r
-               this.reached = reached;\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/BasicTestDefinition.java b/org.argeo.slc.core/src/org/argeo/slc/core/test/BasicTestDefinition.java
deleted file mode 100644 (file)
index 6b92135..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.core.test.context.ContextUtils;\r
-import org.argeo.slc.test.IncompatibleTestDataException;\r
-import org.argeo.slc.test.TestData;\r
-import org.argeo.slc.test.TestDefinition;\r
-import org.argeo.slc.test.TestResult;\r
-import org.argeo.slc.test.TestRun;\r
-import org.argeo.slc.test.TestStatus;\r
-import org.argeo.slc.test.context.ContextAware;\r
-\r
-/** Understands basic test data and context aware test data. */\r
-public class BasicTestDefinition implements TestDefinition {\r
-\r
-       public void execute(TestRun testRun) {\r
-               if (testRun.<TestData> getTestData() instanceof BasicTestData) {\r
-                       BasicTestData testData = testRun.getTestData();\r
-                       TestResult result = testRun.getTestResult();\r
-\r
-                       if (result == null)\r
-                               throw new SlcException("No test result defined.");\r
-\r
-                       try {\r
-                               if (testData.getExpected().equals(testData.getReached())) {\r
-                                       result.addResultPart(new SimpleResultPart(\r
-                                                       TestStatus.PASSED, "Reached and expected equals"));\r
-                               } else {\r
-                                       result.addResultPart(new SimpleResultPart(\r
-                                                       TestStatus.FAILED, "Expected "\r
-                                                                       + testData.getExpected() + " but reached "\r
-                                                                       + testData.getReached()));\r
-                               }\r
-                       } catch (Exception e) {\r
-                               result.addResultPart(new SimpleResultPart(TestStatus.ERROR,\r
-                                               "Could not compare", e));\r
-                       }\r
-               } else if (testRun.<TestData> getTestData() instanceof ContextAware) {\r
-                       TestData testData = testRun.getTestData();\r
-                       ContextUtils.compareReachedExpected((ContextAware) testData,\r
-                                       testRun.getTestResult());\r
-               } else {\r
-                       throw new IncompatibleTestDataException(testRun);\r
-               }\r
-       }\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/SimpleResultPart.java b/org.argeo.slc.core/src/org/argeo/slc/core/test/SimpleResultPart.java
deleted file mode 100644 (file)
index 8ad81af..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import java.io.Serializable;\r
-\r
-import org.argeo.slc.test.TestResultPart;\r
-import org.argeo.slc.test.TestRun;\r
-import org.argeo.slc.test.TestRunAware;\r
-import org.argeo.slc.test.TestStatus;\r
-\r
-/**\r
- * <p>\r
- * Basic implementation of a result part, implementing the standard three status\r
- * approach for test results.\r
- * </p>\r
- * \r
- * @see TestStatus\r
- */\r
-public class SimpleResultPart implements TestResultPart, TestStatus,\r
-               TestRunAware, Serializable {\r
-       private static final long serialVersionUID = 6669675957685071901L;\r
-\r
-       private Long tid;\r
-\r
-       private String testRunUuid;\r
-\r
-       /** The status. Default to ERROR since it should always be explicitely set. */\r
-       private Integer status = ERROR;\r
-       private String message;\r
-       private String exceptionMessage;\r
-\r
-       public SimpleResultPart() {\r
-       }\r
-\r
-       public SimpleResultPart(Integer status, String message) {\r
-               this(status, message, null);\r
-       }\r
-\r
-       public SimpleResultPart(Integer status, String message, Exception exception) {\r
-               this.status = status;\r
-               this.message = message;\r
-               setException(exception);\r
-       }\r
-\r
-       public String getMessage() {\r
-               return message;\r
-       }\r
-\r
-       public void setMessage(String message) {\r
-               this.message = message;\r
-       }\r
-\r
-       public void setStatus(Integer status) {\r
-               this.status = status;\r
-       }\r
-\r
-       public Integer getStatus() {\r
-               return status;\r
-       }\r
-\r
-       public String getExceptionMessage() {\r
-               return exceptionMessage;\r
-       }\r
-\r
-       public void setException(Exception exception) {\r
-               if (exception == null)\r
-                       return;\r
-\r
-               StringBuffer buf = new StringBuffer("");\r
-               buf.append(exception.toString());\r
-               buf.append('\n');\r
-               for (StackTraceElement elem : exception.getStackTrace()) {\r
-                       buf.append('\t').append(elem.toString()).append('\n');\r
-               }\r
-\r
-               if (exception.getCause() != null)\r
-                       addRootCause(buf, exception.getCause());\r
-\r
-               this.exceptionMessage = buf.toString();\r
-       }\r
-\r
-       protected void addRootCause(StringBuffer buf, Throwable cause) {\r
-               if (cause == null)\r
-                       return;\r
-\r
-               buf.append("Caused by: " + cause.getMessage());\r
-               for (StackTraceElement elem : cause.getStackTrace()) {\r
-                       buf.append('\t').append(elem.toString()).append('\n');\r
-               }\r
-\r
-               if (cause.getCause() != null) {\r
-                       addRootCause(buf, cause.getCause());\r
-               }\r
-       }\r
-\r
-       @Override\r
-       public String toString() {\r
-               StringBuffer buf = new StringBuffer("");\r
-               buf.append(SlcTestUtils.statusToString(status));\r
-               if (status == PASSED || status == FAILED) {\r
-                       buf.append(' ');\r
-               } else if (status == ERROR) {\r
-                       buf.append("  ");\r
-               }\r
-               buf.append(message);\r
-               return buf.toString();\r
-       }\r
-\r
-       /** @deprecated */\r
-       Long getTid() {\r
-               return tid;\r
-       }\r
-\r
-       /** @deprecated */\r
-       void setTid(Long tid) {\r
-               this.tid = tid;\r
-       }\r
-\r
-       public String getTestRunUuid() {\r
-               return testRunUuid;\r
-       }\r
-\r
-       /** For ORM */\r
-       public void setTestRunUuid(String testRunUuid) {\r
-               this.testRunUuid = testRunUuid;\r
-       }\r
-\r
-       public void notifyTestRun(TestRun testRun) {\r
-               testRunUuid = testRun.getUuid();\r
-       }\r
-\r
-       public void setExceptionMessage(String exceptionMessage) {\r
-               this.exceptionMessage = exceptionMessage;\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/SimpleTestResult.java b/org.argeo.slc.core/src/org/argeo/slc/core/test/SimpleTestResult.java
deleted file mode 100644 (file)
index 93306a5..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import java.util.Date;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.TreeMap;\r
-import java.util.UUID;\r
-import java.util.Vector;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.test.TestResult;\r
-import org.argeo.slc.test.TestResultPart;\r
-import org.argeo.slc.test.TestRun;\r
-\r
-/**\r
- * Basic implementation of a test result containing only a list of result parts.\r
- */\r
-public class SimpleTestResult implements TestResult {\r
-       private static Log log = LogFactory.getLog(SimpleTestResult.class);\r
-\r
-       private String uuid;\r
-       private String currentTestRunUuid;\r
-\r
-       private Boolean throwError = true;\r
-\r
-       private Date closeDate;\r
-       private List<TestResultPart> parts = new Vector<TestResultPart>();\r
-\r
-       private Map<String, String> attributes = new TreeMap<String, String>();\r
-\r
-       public void addResultPart(TestResultPart part) {\r
-               if (throwError && part.getStatus() == ERROR) {\r
-                       throw new SlcException(\r
-                                       "There was an error in the underlying test: "\r
-                                                       + part.getExceptionMessage());\r
-               }\r
-               parts.add(part);\r
-               if (log.isDebugEnabled())\r
-                       log.debug(part);\r
-       }\r
-\r
-       public void close() {\r
-               parts.clear();\r
-               closeDate = new Date();\r
-       }\r
-\r
-       public List<TestResultPart> getParts() {\r
-               return parts;\r
-       }\r
-\r
-       public Date getCloseDate() {\r
-               return closeDate;\r
-       }\r
-\r
-       public void setThrowError(Boolean throwError) {\r
-               this.throwError = throwError;\r
-       }\r
-\r
-       public void notifyTestRun(TestRun testRun) {\r
-               currentTestRunUuid = testRun.getUuid();\r
-       }\r
-\r
-       public String getUuid() {\r
-               if (uuid == null) {\r
-                       uuid = UUID.randomUUID().toString();\r
-               }\r
-               return uuid;\r
-       }\r
-\r
-       public void setUuid(String uuid) {\r
-               this.uuid = uuid;\r
-       }\r
-\r
-       public String getCurrentTestRunUuid() {\r
-               return currentTestRunUuid;\r
-       }\r
-\r
-       public Map<String, String> getAttributes() {\r
-               return attributes;\r
-       }\r
-\r
-       public void setAttributes(Map<String, String> attributes) {\r
-               this.attributes = attributes;\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/SimpleTestRun.java b/org.argeo.slc.core/src/org/argeo/slc/core/test/SimpleTestRun.java
deleted file mode 100644 (file)
index 4f6a12f..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import java.util.UUID;\r
-\r
-import org.argeo.slc.deploy.DeployedSystem;\r
-import org.argeo.slc.test.ExecutableTestRun;\r
-import org.argeo.slc.test.TestData;\r
-import org.argeo.slc.test.TestDefinition;\r
-import org.argeo.slc.test.TestResult;\r
-import org.argeo.slc.test.WritableTestRun;\r
-\r
-/**\r
- * A basic bean implementation of a <code>WritableTestRun</code>, holding\r
- * references to the various parts of a test run.\r
- */\r
-public class SimpleTestRun implements WritableTestRun, ExecutableTestRun {\r
-       private String uuid;\r
-\r
-       // private String slcExecutionUuid;\r
-       // private String slcExecutionStepUuid;\r
-\r
-       private DeployedSystem deployedSystem;\r
-       private TestData testData;\r
-       private TestDefinition testDefinition;\r
-       private TestResult testResult;\r
-\r
-       /** Executes the underlying test definition. */\r
-       public void run() {\r
-               uuid = UUID.randomUUID().toString();\r
-               if (testResult != null)\r
-                       testResult.notifyTestRun(this);\r
-\r
-               testDefinition.execute(this);\r
-       }\r
-\r
-       @SuppressWarnings("unchecked")\r
-       public <T extends DeployedSystem> T getDeployedSystem() {\r
-               return (T) deployedSystem;\r
-       }\r
-\r
-       public void setDeployedSystem(DeployedSystem deployedSystem) {\r
-               this.deployedSystem = deployedSystem;\r
-       }\r
-\r
-       @SuppressWarnings("unchecked")\r
-       public <T extends TestData> T getTestData() {\r
-               return (T) testData;\r
-       }\r
-\r
-       public void setTestData(TestData testData) {\r
-               this.testData = testData;\r
-       }\r
-\r
-       @SuppressWarnings("unchecked")\r
-       public <T extends TestDefinition> T getTestDefinition() {\r
-               return (T) testDefinition;\r
-       }\r
-\r
-       public void setTestDefinition(TestDefinition testDefinition) {\r
-               this.testDefinition = testDefinition;\r
-       }\r
-\r
-       @SuppressWarnings("unchecked")\r
-       public <T extends TestResult> T getTestResult() {\r
-               return (T) testResult;\r
-       }\r
-\r
-       public void setTestResult(TestResult testResult) {\r
-               this.testResult = testResult;\r
-       }\r
-\r
-       public String getUuid() {\r
-               return uuid;\r
-       }\r
-\r
-       public void setUuid(String uuid) {\r
-               this.uuid = uuid;\r
-       }\r
-\r
-       // public String getSlcExecutionUuid() {\r
-       // return slcExecutionUuid;\r
-       // }\r
-       //\r
-       // public void setSlcExecutionUuid(String slcExecutionUuid) {\r
-       // this.slcExecutionUuid = slcExecutionUuid;\r
-       // }\r
-       //\r
-       // public String getSlcExecutionStepUuid() {\r
-       // return slcExecutionStepUuid;\r
-       // }\r
-       //\r
-       // public void setSlcExecutionStepUuid(String slcExecutionStepUuid) {\r
-       // this.slcExecutionStepUuid = slcExecutionStepUuid;\r
-       // }\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/SlcTestUtils.java b/org.argeo.slc.core/src/org/argeo/slc/core/test/SlcTestUtils.java
deleted file mode 100644 (file)
index c926a69..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.test;
-
-import org.argeo.slc.SlcException;
-import org.argeo.slc.test.TestStatus;
-
-public abstract class SlcTestUtils {
-       public static String statusToString(Integer status) {
-               if (status.equals(TestStatus.PASSED)) {
-                       return TestStatus.STATUSSTR_PASSED;
-               } else if (status.equals(TestStatus.FAILED)) {
-                       return TestStatus.STATUSSTR_FAILED;
-               } else if (status.equals(TestStatus.ERROR)) {
-                       return TestStatus.STATUSSTR_ERROR;
-               } else {
-                       throw new SlcException("Unrecognized status " + status);
-               }
-       }
-
-       public static Integer stringToStatus(String statusStr) {
-               if (statusStr.equals(TestStatus.STATUSSTR_PASSED)) {
-                       return TestStatus.PASSED;
-               } else if (statusStr.equals(TestStatus.STATUSSTR_FAILED)) {
-                       return TestStatus.FAILED;
-               } else if (statusStr.equals(TestStatus.STATUSSTR_ERROR)) {
-                       return TestStatus.ERROR;
-               } else {
-                       throw new SlcException("Unrecognized status string " + statusStr);
-               }
-       }
-
-       private SlcTestUtils() {
-
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/TestDataUtils.java b/org.argeo.slc.core/src/org/argeo/slc/core/test/TestDataUtils.java
deleted file mode 100644 (file)
index b32da38..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import org.argeo.slc.UnsupportedException;\r
-import org.argeo.slc.test.TestData;\r
-import org.argeo.slc.test.TestDataProvider;\r
-\r
-/** Utilities for dealing with test datas. */\r
-public class TestDataUtils {\r
-       /** Extracts the test data from the given provider. */\r
-       public static <T extends TestData> T getFromProvider(Object obj,\r
-                       Class<T> clss, String key) {\r
-               if (obj instanceof TestDataProvider) {\r
-                       TestDataProvider testDataProvider = (TestDataProvider) obj;\r
-                       return testDataProvider.getTestData(clss, key);\r
-               } else {\r
-                       throw new UnsupportedException("test data provider", obj);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Extracts the test data from the given provider using <code>null</code>\r
-        * as key.\r
-        */\r
-       public static <T extends TestData> T getFromProvider(Object obj,\r
-                       Class<T> clss) {\r
-               return getFromProvider(obj, clss, null);\r
-       }\r
-\r
-       /**\r
-        * Returns it self after making the proper checks. Used for test data being\r
-        * their own data providers.\r
-        */\r
-       @SuppressWarnings("unchecked")\r
-       public static <T extends TestData> T getItSelf(Class<T> clss,\r
-                       TestData testDataObject) {\r
-               if (clss.isAssignableFrom(testDataObject.getClass())) {\r
-                       return (T) testDataObject;\r
-               } else {\r
-                       throw new UnsupportedException("test data", testDataObject);\r
-               }\r
-\r
-       }\r
-\r
-       /** Makes sure this is an utility class. */\r
-       private TestDataUtils() {\r
-\r
-       }\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/context/ContextUtils.java b/org.argeo.slc.core/src/org/argeo/slc/core/test/context/ContextUtils.java
deleted file mode 100644 (file)
index f62fb5c..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import java.util.Map;\r
-import java.util.TreeMap;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.core.test.SimpleResultPart;\r
-import org.argeo.slc.test.TestResult;\r
-import org.argeo.slc.test.TestStatus;\r
-import org.argeo.slc.test.context.ContextAware;\r
-import org.argeo.slc.test.context.ParentContextAware;\r
-\r
-/** Utilities for comparing and synchronising contexts. */\r
-public class ContextUtils {\r
-       private final static Log log = LogFactory.getLog(ContextUtils.class);\r
-\r
-       public static void compareReachedExpected(ContextAware contextAware,\r
-                       TestResult testResult) {\r
-               for (String key : contextAware.getExpectedValues().keySet()) {\r
-\r
-                       // Compare expected values with reached ones\r
-                       Object expectedValue = contextAware.getExpectedValues().get(key);\r
-\r
-                       if (expectedValue.toString().equals(\r
-                                       contextAware.getContextSkipFlag())) {\r
-                               if (log.isDebugEnabled())\r
-                                       log.debug("Skipped check for key '" + key + "'");\r
-                               continue;\r
-                       }\r
-\r
-                       if (contextAware.getValues().containsKey(key)) {\r
-                               Object reachedValue = contextAware.getValues().get(key);\r
-\r
-                               if (expectedValue.equals(contextAware.getContextAnyFlag())) {\r
-                                       testResult.addResultPart(new SimpleResultPart(\r
-                                                       TestStatus.PASSED, "Expected any value for key '"\r
-                                                                       + key + "'"));\r
-                               } else if (expectedValue.equals(reachedValue)) {\r
-                                       testResult.addResultPart(new SimpleResultPart(\r
-                                                       TestStatus.PASSED, "Values matched for key '" + key\r
-                                                                       + "'"));\r
-                               } else {\r
-                                       testResult.addResultPart(new SimpleResultPart(\r
-                                                       TestStatus.FAILED, "Mismatch for key '" + key\r
-                                                                       + "': expected '" + expectedValue\r
-                                                                       + "' but reached '" + reachedValue + "'"));\r
-                               }\r
-                       } else {\r
-                               testResult.addResultPart(new SimpleResultPart(\r
-                                               TestStatus.FAILED, "No value reached for key '" + key\r
-                                                               + "'"));\r
-                       }\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Makes sure that all children and sub-children of parent share the same\r
-        * maps for values and expected values.\r
-        */\r
-       public static void synchronize(ParentContextAware parent) {\r
-               Map<String, Object> expectedValuesCommon = new TreeMap<String, Object>(\r
-                               parent.getExpectedValues());\r
-               synchronize(parent, expectedValuesCommon);\r
-               if (log.isDebugEnabled())\r
-                       log.debug("Synchronized context " + parent);\r
-\r
-       }\r
-\r
-       private static void synchronize(ParentContextAware parent,\r
-                       Map<String, Object> expectedValuesCommon) {\r
-               for (ContextAware child : parent.getChildContexts()) {\r
-                       // Values\r
-                       putNotContained(parent.getValues(), child.getValues());\r
-                       child.setValues(parent.getValues());\r
-\r
-                       // Expected Values\r
-                       // Expected values reference is not overridden: each child has its\r
-                       // own expected values map.\r
-                       overrideContained(expectedValuesCommon, child.getExpectedValues());\r
-\r
-                       // Creates a new Map in order not to disturb other context using the\r
-                       // same keys\r
-                       Map<String, Object> expectedValuesCommonChild = new TreeMap<String, Object>(\r
-                                       expectedValuesCommon);\r
-                       putNotContained(expectedValuesCommonChild,\r
-                                       child.getExpectedValues());\r
-\r
-                       if (child instanceof ParentContextAware) {\r
-                               // Recursive sync\r
-                               synchronize((ParentContextAware) child,\r
-                                               expectedValuesCommonChild);\r
-                       }\r
-               }\r
-\r
-       }\r
-\r
-       /**\r
-        * Put into common map the values from child map which are not already\r
-        * defined in common map.\r
-        */\r
-       public static void putNotContained(Map<String, Object> commonMap,\r
-                       Map<String, Object> childMap) {\r
-               for (String key : childMap.keySet()) {\r
-                       if (!commonMap.containsKey(key)) {\r
-                               commonMap.put(key, childMap.get(key));\r
-                       }\r
-               }\r
-       }\r
-\r
-       /** Overrides child map values with the values already set in common map */\r
-       public static void overrideContained(Map<String, Object> commonMap,\r
-                       Map<String, Object> childMap) {\r
-               for (String key : childMap.keySet()) {\r
-                       if (commonMap.containsKey(key)) {\r
-                               childMap.put(key, commonMap.get(key));\r
-                       }\r
-               }\r
-       }\r
-\r
-       /** Makes sure this cannot be instantiated. */\r
-       private ContextUtils() {\r
-\r
-       }\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/context/DefaultContextTestData.java b/org.argeo.slc.core/src/org/argeo/slc/core/test/context/DefaultContextTestData.java
deleted file mode 100644 (file)
index ca0bf5f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import org.argeo.slc.core.test.TestDataUtils;\r
-import org.argeo.slc.test.TestData;\r
-import org.argeo.slc.test.TestDataProvider;\r
-\r
-public class DefaultContextTestData extends SimpleContextAware implements\r
-               TestData, TestDataProvider {\r
-\r
-       public <T extends TestData> T getTestData(Class<T> clss, String key) {\r
-               return TestDataUtils.getItSelf(clss, this);\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/context/SimpleContextAware.java b/org.argeo.slc.core/src/org/argeo/slc/core/test/context/SimpleContextAware.java
deleted file mode 100644 (file)
index f10be56..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import java.util.Map;\r
-import java.util.TreeMap;\r
-\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.test.context.ContextAware;\r
-import org.argeo.slc.test.context.ParentContextAware;\r
-import org.springframework.beans.factory.InitializingBean;\r
-\r
-public class SimpleContextAware implements ContextAware, InitializingBean {\r
-       private ParentContextAware parentContext;\r
-\r
-       private Map<String, Object> values = new TreeMap<String, Object>();\r
-       private Map<String, Object> expectedValues = new TreeMap<String, Object>();\r
-\r
-       private String contextSkipFlag = DEFAULT_SKIP_FLAG;\r
-       private String contextAnyFlag = DEFAULT_ANY_FLAG;\r
-\r
-       public Map<String, Object> getValues() {\r
-               return values;\r
-       }\r
-\r
-       public void setValues(Map<String, Object> values) {\r
-               this.values = values;\r
-       }\r
-\r
-       public Map<String, Object> getExpectedValues() {\r
-               return expectedValues;\r
-       }\r
-\r
-       public void setExpectedValues(Map<String, Object> expectedValues) {\r
-               this.expectedValues = expectedValues;\r
-       }\r
-\r
-       /** Used to add this context as a child by setting a property. */\r
-       public void setParentContext(ParentContextAware parentContextAware) {\r
-               if (parentContext != null)\r
-                       throw new SlcException("Parent context already set");\r
-               this.parentContext = parentContextAware;\r
-               this.parentContext.addChildContext(this);\r
-       }\r
-\r
-       protected ParentContextAware getParentContext() {\r
-               return parentContext;\r
-       }\r
-\r
-       public void afterPropertiesSet() throws Exception {\r
-               if (parentContext != null) {\r
-                       ContextUtils.synchronize(parentContext);\r
-               }\r
-       }\r
-\r
-       public String getContextSkipFlag() {\r
-               return contextSkipFlag;\r
-       }\r
-\r
-       public void setContextSkipFlag(String contextSkipFlag) {\r
-               this.contextSkipFlag = contextSkipFlag;\r
-       }\r
-\r
-       public String getContextAnyFlag() {\r
-               return contextAnyFlag;\r
-       }\r
-\r
-       public void setContextAnyFlag(String contextAnyFlag) {\r
-               this.contextAnyFlag = contextAnyFlag;\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/context/SimpleParentContextAware.java b/org.argeo.slc.core/src/org/argeo/slc/core/test/context/SimpleParentContextAware.java
deleted file mode 100644 (file)
index b8abf7f..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import java.util.Collection;\r
-import java.util.List;\r
-import java.util.Vector;\r
-\r
-import org.argeo.slc.test.context.ContextAware;\r
-import org.argeo.slc.test.context.ParentContextAware;\r
-import org.springframework.beans.factory.InitializingBean;\r
-\r
-public class SimpleParentContextAware extends SimpleContextAware implements\r
-               ParentContextAware, InitializingBean {\r
-       private List<ContextAware> children = new Vector<ContextAware>();\r
-\r
-       public Collection<ContextAware> getChildContexts() {\r
-               return children;\r
-       }\r
-\r
-       public void addChildContext(ContextAware contextAware) {\r
-               children.add(contextAware);\r
-       }\r
-\r
-       @Override\r
-       public void afterPropertiesSet() throws Exception {\r
-               if (getParentContext() != null) {\r
-                       // If has a parent, sync it.\r
-                       super.afterPropertiesSet();\r
-               } else {\r
-                       if (children.size() > 0) {\r
-                               // No need to synchronize if no children\r
-                               ContextUtils.synchronize(this);\r
-                       }\r
-               }\r
-       }\r
-}\r
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/context/package.html b/org.argeo.slc.core/src/org/argeo/slc/core/test/context/package.html
deleted file mode 100644 (file)
index cd08d63..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<html>\r
-<head></head>\r
-<body>\r
-Context variables to be passed between parts of tests.\r
-</body>\r
-</html>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/package.html b/org.argeo.slc.core/src/org/argeo/slc/core/test/package.html
deleted file mode 100644 (file)
index c70d2d1..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<html>\r
-<head></head>\r
-<body>\r
-SLC Test: test of software systems.\r
-</body>\r
-</html>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/test/spring.xml b/org.argeo.slc.core/src/org/argeo/slc/core/test/spring.xml
deleted file mode 100644 (file)
index 31cf671..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (C) 2007-2012 Argeo GmbH
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-            http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
-    default-lazy-init="true">
-
-    <bean name="slcDefault.test.testRun"
-        class="org.argeo.slc.core.test.SimpleTestRun"
-        scope="prototype">
-    </bean>
-
-    <bean name="slcDefault.test.uuid" class="java.util.UUID"
-        factory-method="randomUUID" scope="prototype">
-    </bean>
-
-    <bean id="slcDefault.test.basicSimpleTestResult"
-        class="org.argeo.slc.core.test.SimpleTestResult"
-        abstract="true">
-        <property name="uuid">
-            <bean factory-bean="slcDefault.test.uuid"
-                factory-method="toString">
-            </bean>
-        </property>
-    </bean>
-
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/JcrMetadataWriter.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/JcrMetadataWriter.java
deleted file mode 100644 (file)
index c4922d3..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.jcr;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.SlcNames;
-
-/**
- * Writes arbitrary metadata into a child node of a given node (or the node
- * itself if metadata node name is set to null)
- */
-public class JcrMetadataWriter implements Runnable {
-       private final static Log log = LogFactory.getLog(JcrMetadataWriter.class);
-
-       private Node baseNode;
-       private String metadataNodeName = SlcNames.SLC_METADATA;
-
-       private Map<String, String> metadata = new HashMap<String, String>();
-
-       public void run() {
-               try {
-                       Node metadataNode;
-                       if (metadataNodeName != null)
-                               metadataNode = baseNode.hasNode(metadataNodeName) ? baseNode
-                                               .getNode(metadataNodeName) : baseNode
-                                               .addNode(metadataNodeName);
-                       else
-                               metadataNode = baseNode;
-
-                       for (String key : metadata.keySet())
-                               metadataNode.setProperty(key, metadata.get(key));
-
-                       baseNode.getSession().save();
-
-                       if (log.isDebugEnabled())
-                               log.debug("Wrote " + metadata.size() + " metadata entries to "
-                                               + metadataNode);
-               } catch (RepositoryException e) {
-                       throw new SlcException("Cannot write metadata to " + baseNode, e);
-               } finally {
-                       JcrUtils.discardUnderlyingSessionQuietly(baseNode);
-               }
-
-       }
-
-       public void setBaseNode(Node baseNode) {
-               this.baseNode = baseNode;
-       }
-
-       public void setMetadataNodeName(String metadataNodeName) {
-               this.metadataNodeName = metadataNodeName;
-       }
-
-       public void setMetadata(Map<String, String> metadata) {
-               this.metadata = metadata;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/JcrTestResult.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/JcrTestResult.java
deleted file mode 100644 (file)
index c9ec874..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.jcr;
-
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.jcr.Credentials;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.Repository;
-import javax.jcr.Session;
-import javax.jcr.query.Query;
-import javax.jcr.query.QueryManager;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.SlcNames;
-import org.argeo.slc.SlcTypes;
-import org.argeo.slc.core.attachment.Attachment;
-import org.argeo.slc.core.attachment.AttachmentsEnabled;
-import org.argeo.slc.test.TestResult;
-import org.argeo.slc.test.TestResultPart;
-import org.argeo.slc.test.TestRun;
-import org.argeo.slc.test.TestStatus;
-
-/**
- * {@link TestResult} wrapping a JCR node of type
- * {@link SlcTypes#SLC_TEST_RESULT}.
- */
-public class JcrTestResult implements TestResult, SlcNames, AttachmentsEnabled {
-       private final static Log log = LogFactory.getLog(JcrTestResult.class);
-
-       /** Should only be set for an already existing result. */
-       private String uuid;
-       private Repository repository;
-       private Session session;
-       /**
-        * For testing purposes, best practice is to not set them explicitely but
-        * via other mechanisms such as JAAS or SPring Security.
-        */
-       private Credentials credentials = null;
-       private String resultType = SlcTypes.SLC_TEST_RESULT;
-
-       /** cached for performance purposes */
-       private String nodeIdentifier = null;
-
-       private Map<String, String> attributes = new HashMap<String, String>();
-
-       public void init() {
-               try {
-                       session = repository.login(credentials);
-                       if (uuid == null) {
-                               // create new result
-                               uuid = UUID.randomUUID().toString();
-                               String path = SlcJcrUtils.createResultPath(session, uuid);
-                               Node resultNode = JcrUtils.mkdirs(session, path, resultType);
-                               resultNode.setProperty(SLC_UUID, uuid);
-                               for (String attr : attributes.keySet()) {
-                                       String property = attr;
-                                       // compatibility with legacy applications
-                                       if ("testCase".equals(attr))
-                                               property = SLC_TEST_CASE;
-                                       else if ("testCaseType".equals(attr))
-                                               property = SLC_TEST_CASE_TYPE;
-                                       resultNode.setProperty(property, attributes.get(attr));
-                               }
-                               session.save();
-                               if (log.isDebugEnabled())
-                                       log.debug("Created test result " + uuid);
-                       }
-               } catch (Exception e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new SlcException("Cannot initialize JCR result", e);
-               }
-       }
-
-       public void destroy() {
-               JcrUtils.logoutQuietly(session);
-               if (log.isTraceEnabled())
-                       log.trace("Logged out session for result " + uuid);
-       }
-
-       public Node getNode() {
-               try {
-                       Node resultNode;
-                       if (nodeIdentifier != null) {
-                               return session.getNodeByIdentifier(nodeIdentifier);
-                       } else {
-                               QueryManager qm = session.getWorkspace().getQueryManager();
-                               Query q = qm.createQuery("select * from ["
-                                               + SlcTypes.SLC_TEST_RESULT + "] where [slc:uuid]='"
-                                               + uuid + "'", Query.JCR_SQL2);
-                               resultNode = JcrUtils.querySingleNode(q);
-                               if (resultNode != null)
-                                       nodeIdentifier = resultNode.getIdentifier();
-                       }
-                       return resultNode;
-               } catch (Exception e) {
-                       throw new SlcException("Cannot get result node", e);
-               }
-       }
-
-       public void notifyTestRun(TestRun testRun) {
-               // TODO store meta data about the test running
-               // if (log.isDebugEnabled())
-               // log.debug("Running test "
-               // + testRun.getTestDefinition().getClass().getName() + "...");
-       }
-
-       public void addResultPart(TestResultPart testResultPart) {
-               Node node = getNode();
-
-               try {
-                       // error : revert all unsaved changes on the resultNode to be sure
-                       // it is in a consistant state
-                       if (testResultPart.getExceptionMessage() != null)
-                               JcrUtils.discardQuietly(node.getSession());
-                       node.getSession().save();
-
-                       // add the new result part, retrieving status information
-                       Node resultPartNode = node.addNode(SlcNames.SLC_RESULT_PART,
-                                       SlcTypes.SLC_CHECK);
-                       resultPartNode.setProperty(SLC_SUCCESS, testResultPart.getStatus()
-                                       .equals(TestStatus.PASSED));
-                       if (testResultPart.getMessage() != null)
-                               resultPartNode.setProperty(SLC_MESSAGE,
-                                               testResultPart.getMessage());
-                       if (testResultPart.getStatus().equals(TestStatus.ERROR)) {
-                               resultPartNode.setProperty(SLC_ERROR_MESSAGE,
-                                               (testResultPart.getExceptionMessage() == null) ? ""
-                                                               : testResultPart.getExceptionMessage());
-                       }
-
-                       // helper update aggregate status node
-                       Node mainStatus;
-                       if (!node.hasNode(SLC_AGGREGATED_STATUS)) {
-
-                               mainStatus = node.addNode(SLC_AGGREGATED_STATUS,
-                                               SlcTypes.SLC_CHECK);
-                               mainStatus.setProperty(SLC_SUCCESS,
-                                               resultPartNode.getProperty(SLC_SUCCESS).getBoolean());
-                               if (resultPartNode.hasProperty(SLC_MESSAGE))
-                                       mainStatus.setProperty(SLC_MESSAGE, resultPartNode
-                                                       .getProperty(SLC_MESSAGE).getString());
-                               if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE))
-                                       mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode
-                                                       .getProperty(SLC_ERROR_MESSAGE).getString());
-                       } else {
-                               mainStatus = node.getNode(SLC_AGGREGATED_STATUS);
-                               if (mainStatus.hasProperty(SLC_ERROR_MESSAGE)) {
-                                       // main status already in error we do nothing
-                               } else if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE)) {
-                                       // main status was not in error and new result part is in
-                                       // error; we update main status
-                                       mainStatus.setProperty(SLC_SUCCESS, false);
-                                       mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode
-                                                       .getProperty(SLC_ERROR_MESSAGE).getString());
-                                       if (resultPartNode.hasProperty(SLC_MESSAGE))
-                                               mainStatus.setProperty(SLC_MESSAGE, resultPartNode
-                                                               .getProperty(SLC_MESSAGE).getString());
-                                       else
-                                               // remove old message to remain consistent
-                                               mainStatus.setProperty(SLC_MESSAGE, "");
-                               } else if (!mainStatus.getProperty(SLC_SUCCESS).getBoolean()) {
-                                       // main status was already failed and new result part is not
-                                       // in error, we do nothing
-                               } else if (!resultPartNode.getProperty(SLC_SUCCESS)
-                                               .getBoolean()) {
-                                       // new resultPart that is failed
-                                       mainStatus.setProperty(SLC_SUCCESS, false);
-                                       if (resultPartNode.hasProperty(SLC_MESSAGE))
-                                               mainStatus.setProperty(SLC_MESSAGE, resultPartNode
-                                                               .getProperty(SLC_MESSAGE).getString());
-                                       else
-                                               // remove old message to remain consistent
-                                               mainStatus.setProperty(SLC_MESSAGE, "");
-                               } else if (resultPartNode.hasProperty(SLC_MESSAGE)
-                                               && (!mainStatus.hasProperty(SLC_MESSAGE) || (""
-                                                               .equals(mainStatus.getProperty(SLC_MESSAGE)
-                                                                               .getString().trim())))) {
-                                       mainStatus.setProperty(SLC_MESSAGE, resultPartNode
-                                                       .getProperty(SLC_MESSAGE).getString());
-                               }
-                       }
-                       JcrUtils.updateLastModified(node);
-                       node.getSession().save();
-               } catch (Exception e) {
-                       JcrUtils.discardUnderlyingSessionQuietly(node);
-                       throw new SlcException("Cannot add ResultPart to node " + node, e);
-               }
-       }
-
-       public String getUuid() {
-               Node node = getNode();
-               try {
-                       return node.getProperty(SLC_UUID).getString();
-               } catch (Exception e) {
-                       throw new SlcException("Cannot get UUID from " + node, e);
-               }
-       }
-
-       /** JCR session is NOT logged out */
-       public void close() {
-               Node node = getNode();
-               try {
-                       if (node.hasNode(SLC_COMPLETED))
-                               return;
-                       node.setProperty(SLC_COMPLETED, new GregorianCalendar());
-                       JcrUtils.updateLastModified(node);
-                       node.getSession().save();
-               } catch (Exception e) {
-                       JcrUtils.discardUnderlyingSessionQuietly(node);
-                       throw new SlcException("Cannot get close date from " + node, e);
-               }
-       }
-
-       public Date getCloseDate() {
-               Node node = getNode();
-               try {
-                       if (!node.hasNode(SLC_COMPLETED))
-                               return null;
-                       return node.getProperty(SLC_COMPLETED).getDate().getTime();
-               } catch (Exception e) {
-                       throw new SlcException("Cannot get close date from " + node, e);
-               }
-       }
-
-       public Map<String, String> getAttributes() {
-               Node node = getNode();
-               try {
-                       Map<String, String> map = new HashMap<String, String>();
-                       PropertyIterator pit = node.getProperties();
-                       while (pit.hasNext()) {
-                               Property p = pit.nextProperty();
-                               if (!p.isMultiple())
-                                       map.put(p.getName(), p.getValue().getString());
-                       }
-                       return map;
-               } catch (Exception e) {
-                       throw new SlcException("Cannot get close date from " + node, e);
-               }
-       }
-
-       public void addAttachment(Attachment attachment) {
-               // TODO implement it
-       }
-
-       public void setUuid(String uuid) {
-               this.uuid = uuid;
-       }
-
-       public void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-       public void setResultType(String resultType) {
-               this.resultType = resultType;
-       }
-
-       public void setAttributes(Map<String, String> attributes) {
-               if (uuid != null)
-                       throw new SlcException(
-                                       "Attributes cannot be set on an already initialized test result."
-                                                       + " Update the related JCR node directly instead.");
-               this.attributes = attributes;
-       }
-
-       public void setCredentials(Credentials credentials) {
-               this.credentials = credentials;
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrConstants.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrConstants.java
deleted file mode 100644 (file)
index 3190c85..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.jcr;
-
-import org.argeo.slc.SlcNames;
-
-/** JCR related constants used across SLC */
-public interface SlcJcrConstants {
-       public final static String PROPERTY_PATH = "argeo.slc.jcr.path";
-
-       public final static String SLC_BASE_PATH = "/" + SlcNames.SLC_SYSTEM;
-       public final static String AGENTS_BASE_PATH = SLC_BASE_PATH + "/"
-                       + SlcNames.SLC_AGENTS;
-       public final static String VM_AGENT_FACTORY_PATH = AGENTS_BASE_PATH + "/"
-                       + SlcNames.SLC_VM;
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrResultUtils.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrResultUtils.java
deleted file mode 100644 (file)
index 6353804..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.jcr;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.jcr.JcrUtils;
-import org.argeo.node.NodeUtils;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.SlcNames;
-import org.argeo.slc.SlcTypes;
-
-/**
- * Utilities around the SLC JCR Result model. Note that it relies on fixed base
- * paths (convention over configuration) for optimization purposes.
- */
-public class SlcJcrResultUtils {
-
-       /**
-        * Returns the path to the current slc:result node
-        */
-       public static String getSlcResultsBasePath(Session session) {
-               try {
-                       Node userHome = NodeUtils.getUserHome(session);
-                       if (userHome == null)
-                               throw new SlcException("No user home available for "
-                                               + session.getUserID());
-                       return userHome.getPath() + '/' + SlcNames.SLC_SYSTEM + '/'
-                                       + SlcNames.SLC_RESULTS;
-               } catch (RepositoryException re) {
-                       throw new SlcException(
-                                       "Unexpected error while getting Slc Results Base Path.", re);
-               }
-       }
-
-       /**
-        * Returns the base node to store SlcResults. If it does not exists, it is
-        * created. If a node already exists at the given path with the wrong type,
-        * it throws an exception.
-        * 
-        * @param session
-        * @return
-        */
-       public static Node getSlcResultsParentNode(Session session) {
-               try {
-                       String absPath = getSlcResultsBasePath(session);
-                       if (session.nodeExists(absPath)) {
-                               Node currNode = session.getNode(absPath);
-                               if (currNode.isNodeType(NodeType.NT_UNSTRUCTURED))
-                                       return currNode;
-                               else
-                                       throw new SlcException(
-                                                       "A node already exists at this path : " + absPath
-                                                                       + " that has the wrong type. ");
-                       } else {
-                               Node slcResParNode = JcrUtils.mkdirs(session, absPath);
-                               slcResParNode.setPrimaryType(NodeType.NT_UNSTRUCTURED);
-                               session.save();
-                               return slcResParNode;
-                       }
-               } catch (RepositoryException re) {
-                       throw new SlcException(
-                                       "Unexpected error while creating slcResult root parent node.",
-                                       re);
-               }
-       }
-
-       /**
-        * Returns the path to the current Result UI specific node, depending the
-        * current user
-        */
-       public static String getMyResultsBasePath(Session session) {
-               try {
-                       Node userHome = NodeUtils.getUserHome(session);
-                       if (userHome == null)
-                               throw new SlcException("No user home available for "
-                                               + session.getUserID());
-                       return userHome.getPath() + '/' + SlcNames.SLC_SYSTEM + '/'
-                                       + SlcNames.SLC_MY_RESULTS;
-               } catch (RepositoryException re) {
-                       throw new SlcException(
-                                       "Unexpected error while getting Slc Results Base Path.", re);
-               }
-       }
-
-       /**
-        * Creates a new node with type SlcTypes.SLC_MY_RESULT_ROOT_FOLDER at the
-        * given absolute path. If a node already exists at the given path, returns
-        * that node if it has the correct type and throws an exception otherwise.
-        * 
-        * @param session
-        * @return
-        */
-       public static Node getMyResultParentNode(Session session) {
-               try {
-                       String absPath = getMyResultsBasePath(session);
-                       if (session.nodeExists(absPath)) {
-                               Node currNode = session.getNode(absPath);
-                               if (currNode.isNodeType(SlcTypes.SLC_MY_RESULT_ROOT_FOLDER))
-                                       return currNode;
-                               else
-                                       throw new SlcException(
-                                                       "A node already exists at this path : " + absPath
-                                                                       + " that has the wrong type. ");
-                       } else {
-                               Node myResParNode = JcrUtils.mkdirs(session, absPath);
-                               myResParNode.setPrimaryType(SlcTypes.SLC_MY_RESULT_ROOT_FOLDER);
-                               session.save();
-                               return myResParNode;
-                       }
-               } catch (RepositoryException re) {
-                       throw new SlcException(
-                                       "Unexpected error while creating user MyResult base node.",
-                                       re);
-               }
-       }
-
-       /**
-        * Creates a new node with type SlcTypes.SLC_RESULT_FOLDER at the given
-        * absolute path. If a node already exists at the given path, returns that
-        * node if it has the correct type and throws an exception otherwise.
-        * 
-        * @param session
-        * @param absPath
-        * @return
-        */
-       public static synchronized Node createResultFolderNode(Session session,
-                       String absPath) {
-               try {
-                       if (session.nodeExists(absPath)) {
-                               // Sanity check
-                               Node currNode = session.getNode(absPath);
-                               if (currNode.isNodeType(SlcTypes.SLC_RESULT_FOLDER))
-                                       return currNode;
-                               else
-                                       throw new SlcException(
-                                                       "A node already exists at this path : " + absPath
-                                                                       + " that has the wrong type. ");
-                       }
-                       Node rfNode = JcrUtils.mkdirs(session, absPath);
-                       rfNode.setPrimaryType(SlcTypes.SLC_RESULT_FOLDER);
-                       Node statusNode = rfNode.addNode(SlcNames.SLC_AGGREGATED_STATUS,
-                                       SlcTypes.SLC_CHECK);
-                       statusNode.setProperty(SlcNames.SLC_SUCCESS, true);
-                       session.save();
-                       return rfNode;
-               } catch (RepositoryException re) {
-                       throw new SlcException(
-                                       "Unexpected error while creating Result Folder node.", re);
-               }
-       }
-}
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrUtils.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrUtils.java
deleted file mode 100644 (file)
index 137e298..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.jcr;
-
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.jcr.JcrUtils;
-import org.argeo.node.NodeUtils;
-import org.argeo.slc.DefaultNameVersion;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.SlcNames;
-import org.argeo.slc.SlcTypes;
-import org.argeo.slc.core.execution.PrimitiveAccessor;
-import org.argeo.slc.core.execution.PrimitiveUtils;
-import org.argeo.slc.deploy.ModuleDescriptor;
-import org.argeo.slc.test.TestStatus;
-
-/**
- * Utilities around the SLC JCR model. Note that it relies on fixed base paths
- * (convention over configuration) for optimization purposes.
- */
-public class SlcJcrUtils implements SlcNames {
-       public final static Integer AGENT_FACTORY_DEPTH = 3;
-
-       /** Extracts the path of a flow relative to its execution module */
-       public static String flowRelativePath(String fullFlowPath) {
-               String[] tokens = fullFlowPath.split("/");
-               StringBuffer buf = new StringBuffer(fullFlowPath.length());
-               for (int i = AGENT_FACTORY_DEPTH + 3; i < tokens.length; i++) {
-                       buf.append('/').append(tokens[i]);
-               }
-               return buf.toString();
-       }
-
-       /** Extracts the path to the related execution module */
-       public static String modulePath(String fullFlowPath) {
-               String[] tokens = fullFlowPath.split("/");
-               StringBuffer buf = new StringBuffer(fullFlowPath.length());
-               for (int i = 0; i < AGENT_FACTORY_DEPTH + 3; i++) {
-                       if (!tokens[i].equals(""))
-                               buf.append('/').append(tokens[i]);
-               }
-               return buf.toString();
-       }
-
-       /** Extracts the module name from a flow path */
-       public static String moduleName(String fullFlowPath) {
-               String[] tokens = fullFlowPath.split("/");
-               String moduleName = tokens[AGENT_FACTORY_DEPTH + 2];
-               moduleName = moduleName.substring(0, moduleName.indexOf('_'));
-               return moduleName;
-       }
-
-       /** Extracts the module name and version from a flow path */
-       public static NameVersion moduleNameVersion(String fullFlowPath) {
-               String[] tokens = fullFlowPath.split("/");
-               String module = tokens[AGENT_FACTORY_DEPTH + 2];
-               String moduleName = module.substring(0, module.indexOf('_'));
-               String moduleVersion = module.substring(module.indexOf('_') + 1);
-               return new DefaultNameVersion(moduleName, moduleVersion);
-       }
-
-       /** Module node name based on module name and version */
-       public static String getModuleNodeName(ModuleDescriptor moduleDescriptor) {
-               return moduleDescriptor.getName() + "_" + moduleDescriptor.getVersion();
-       }
-
-       /** Extracts the agent factory of a flow */
-       public static String flowAgentFactoryPath(String fullFlowPath) {
-               String[] tokens = fullFlowPath.split("/");
-               StringBuffer buf = new StringBuffer(fullFlowPath.length());
-               // first token is always empty
-               for (int i = 1; i < AGENT_FACTORY_DEPTH + 1; i++) {
-                       buf.append('/').append(tokens[i]);
-               }
-               return buf.toString();
-       }
-
-       /** Create a new execution process path based on the current time */
-       public static String createExecutionProcessPath(Session session, String uuid) {
-               Calendar now = new GregorianCalendar();
-               return getSlcProcessesBasePath(session) + '/'
-                               + JcrUtils.dateAsPath(now, true) + uuid;
-       }
-
-       /** Get the base for the user processi. */
-       public static String getSlcProcessesBasePath(Session session) {
-               try {
-                       Node userHome = NodeUtils.getUserHome(session);
-                       if (userHome == null)
-                               throw new SlcException("No user home available for "
-                                               + session.getUserID());
-                       return userHome.getPath() + '/' + SlcNames.SLC_SYSTEM + '/'
-                                       + SlcNames.SLC_PROCESSES;
-               } catch (RepositoryException re) {
-                       throw new SlcException(
-                                       "Unexpected error while getting Slc Results Base Path.", re);
-               }
-       }
-
-       /**
-        * Create a new execution result path in the user home based on the current
-        * time
-        */
-       public static String createResultPath(Session session, String uuid)
-                       throws RepositoryException {
-               Calendar now = new GregorianCalendar();
-               StringBuffer absPath = new StringBuffer(
-                               SlcJcrResultUtils.getSlcResultsBasePath(session) + '/');
-               // Remove hours and add title property to the result process path on
-               // request of O. Capillon
-               // return getSlcProcessesBasePath(session) + '/'
-               // + JcrUtils.dateAsPath(now, true) + uuid;
-               String relPath = JcrUtils.dateAsPath(now, false);
-               List<String> names = JcrUtils.tokenize(relPath);
-               for (String name : names) {
-                       absPath.append(name + "/");
-                       Node node = JcrUtils.mkdirs(session, absPath.toString());
-                       try {
-                               node.addMixin(NodeType.MIX_TITLE);
-                               node.setProperty(Property.JCR_TITLE, name.substring(1));
-                       } catch (RepositoryException e) {
-                               throw new SlcException(
-                                               "unable to create execution process path", e);
-                       }
-               }
-               return absPath.toString() + uuid;
-       }
-
-       /**
-        * Set the value of the primitive accessor as a JCR property. Does nothing
-        * if the value is null.
-        */
-       public static void setPrimitiveAsProperty(Node node, String propertyName,
-                       PrimitiveAccessor primitiveAccessor) {
-               String type = primitiveAccessor.getType();
-               Object value = primitiveAccessor.getValue();
-               setPrimitiveAsProperty(node, propertyName, type, value);
-       }
-
-       /** Map a primitive value to JCR property value. */
-       public static void setPrimitiveAsProperty(Node node, String propertyName,
-                       String type, Object value) {
-               if (value == null)
-                       return;
-               if (value instanceof CharSequence)
-                       value = PrimitiveUtils.convert(type,
-                                       ((CharSequence) value).toString());
-               if (value instanceof char[])
-                       value = new String((char[]) value);
-
-               try {
-                       if (type.equals(PrimitiveAccessor.TYPE_STRING))
-                               node.setProperty(propertyName, value.toString());
-                       else if (type.equals(PrimitiveAccessor.TYPE_PASSWORD))
-                               node.setProperty(propertyName, value.toString());
-                       else if (type.equals(PrimitiveAccessor.TYPE_INTEGER))
-                               node.setProperty(propertyName, (long) ((Integer) value));
-                       else if (type.equals(PrimitiveAccessor.TYPE_LONG))
-                               node.setProperty(propertyName, ((Long) value));
-                       else if (type.equals(PrimitiveAccessor.TYPE_FLOAT))
-                               node.setProperty(propertyName, (double) ((Float) value));
-                       else if (type.equals(PrimitiveAccessor.TYPE_DOUBLE))
-                               node.setProperty(propertyName, ((Double) value));
-                       else if (type.equals(PrimitiveAccessor.TYPE_BOOLEAN))
-                               node.setProperty(propertyName, ((Boolean) value));
-                       else
-                               throw new SlcException("Unsupported type " + type);
-               } catch (RepositoryException e) {
-                       throw new SlcException("Cannot set primitive of " + type
-                                       + " as property " + propertyName + " on " + node, e);
-               }
-       }
-
-       /** Aggregates the {@link TestStatus} of this sub-tree. */
-       public static Integer aggregateTestStatus(Node node) {
-               try {
-                       Integer status = TestStatus.PASSED;
-                       if (node.isNodeType(SlcTypes.SLC_CHECK))
-                               if (node.getProperty(SLC_SUCCESS).getBoolean())
-                                       status = TestStatus.PASSED;
-                               else if (node.hasProperty(SLC_ERROR_MESSAGE))
-                                       status = TestStatus.ERROR;
-                               else
-                                       status = TestStatus.FAILED;
-
-                       NodeIterator it = node.getNodes();
-                       while (it.hasNext()) {
-                               Node curr = it.nextNode();
-
-                               // Manually skip aggregated status
-                               if (!SlcNames.SLC_AGGREGATED_STATUS.equals(curr.getName())) {
-                                       Integer childStatus = aggregateTestStatus(curr);
-                                       if (childStatus > status)
-                                               status = childStatus;
-                               }
-                       }
-                       return status;
-               } catch (Exception e) {
-                       throw new SlcException("Could not aggregate test status from "
-                                       + node, e);
-               }
-       }
-
-       /**
-        * Aggregates the {@link TestStatus} of this sub-tree.
-        * 
-        * @return the same {@link StringBuffer}, for convenience (typically calling
-        *         toString() on it)
-        */
-       public static StringBuffer aggregateTestMessages(Node node,
-                       StringBuffer messages) {
-               try {
-                       if (node.isNodeType(SlcTypes.SLC_CHECK)) {
-                               if (node.hasProperty(SLC_MESSAGE)) {
-                                       if (messages.length() > 0)
-                                               messages.append('\n');
-                                       messages.append(node.getProperty(SLC_MESSAGE).getString());
-                               }
-                               if (node.hasProperty(SLC_ERROR_MESSAGE)) {
-                                       if (messages.length() > 0)
-                                               messages.append('\n');
-                                       messages.append(node.getProperty(SLC_ERROR_MESSAGE)
-                                                       .getString());
-                               }
-                       }
-                       NodeIterator it = node.getNodes();
-                       while (it.hasNext()) {
-                               Node child = it.nextNode();
-                               // Manually skip aggregated status
-                               if (!SlcNames.SLC_AGGREGATED_STATUS.equals(child.getName())) {
-                                       aggregateTestMessages(child, messages);
-                               }
-                       }
-                       return messages;
-               } catch (Exception e) {
-                       throw new SlcException("Could not aggregate test messages from "
-                                       + node, e);
-               }
-       }
-
-       /** Prevents instantiation */
-       private SlcJcrUtils() {
-       }
-}
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrAgent.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrAgent.java
deleted file mode 100644 (file)
index 89b4530..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.jcr.execution;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.UUID;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.security.Privilege;
-
-import org.argeo.jcr.JcrUtils;
-import org.argeo.slc.SlcConstants;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.SlcNames;
-import org.argeo.slc.SlcTypes;
-import org.argeo.slc.core.execution.DefaultAgent;
-import org.argeo.slc.core.execution.ProcessThread;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.ExecutionProcess;
-import org.argeo.slc.jcr.SlcJcrConstants;
-
-/** SLC VM agent synchronizing with a JCR repository. */
-public class JcrAgent extends DefaultAgent implements SlcNames {
-       // final static String ROLE_REMOTE = "ROLE_REMOTE";
-       final static String NODE_REPO_URI = "argeo.node.repo.uri";
-
-       private Repository repository;
-
-       private String agentNodeName = "default";
-
-       /*
-        * LIFECYCLE
-        */
-       protected String initAgentUuid() {
-               Session session = null;
-               try {
-                       session = repository.login();
-
-                       String agentFactoryPath = getAgentFactoryPath();
-                       Node vmAgentFactoryNode = JcrUtils.mkdirsSafe(session, agentFactoryPath, SlcTypes.SLC_AGENT_FACTORY);
-                       JcrUtils.addPrivilege(session, SlcJcrConstants.SLC_BASE_PATH, SlcConstants.ROLE_SLC, Privilege.JCR_ALL);
-                       if (!vmAgentFactoryNode.hasNode(agentNodeName)) {
-                               String uuid = UUID.randomUUID().toString();
-                               Node agentNode = vmAgentFactoryNode.addNode(agentNodeName, SlcTypes.SLC_AGENT);
-                               agentNode.setProperty(SLC_UUID, uuid);
-                       }
-                       session.save();
-                       return vmAgentFactoryNode.getNode(agentNodeName).getProperty(SLC_UUID).getString();
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new SlcException("Cannot find JCR agent UUID", e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-       }
-
-       @Override
-       public void destroy() {
-               super.destroy();
-       }
-
-       /*
-        * SLC AGENT
-        */
-       @Override
-       protected ProcessThread createProcessThread(ThreadGroup processesThreadGroup,
-                       ExecutionModulesManager modulesManager, ExecutionProcess process) {
-               if (process instanceof JcrExecutionProcess)
-                       return new JcrProcessThread(processesThreadGroup, modulesManager, (JcrExecutionProcess) process);
-               else
-                       return super.createProcessThread(processesThreadGroup, modulesManager, process);
-       }
-
-       /*
-        * UTILITIES
-        */
-       public String getNodePath() {
-               return getAgentFactoryPath() + '/' + getAgentNodeName();
-       }
-
-       public String getAgentFactoryPath() {
-               try {
-                       Boolean isRemote = System.getProperty(NODE_REPO_URI) != null;
-                       String agentFactoryPath;
-                       if (isRemote) {
-                               InetAddress localhost = InetAddress.getLocalHost();
-                               agentFactoryPath = SlcJcrConstants.AGENTS_BASE_PATH + "/" + localhost.getCanonicalHostName();
-
-                               if (agentFactoryPath.equals(SlcJcrConstants.VM_AGENT_FACTORY_PATH))
-                                       throw new SlcException("Unsupported hostname " + localhost.getCanonicalHostName());
-                       } else {// local
-                               agentFactoryPath = SlcJcrConstants.VM_AGENT_FACTORY_PATH;
-                       }
-                       return agentFactoryPath;
-               } catch (UnknownHostException e) {
-                       throw new SlcException("Cannot find agent factory base path", e);
-               }
-       }
-
-       /*
-        * BEAN
-        */
-       public String getAgentNodeName() {
-               return agentNodeName;
-       }
-
-       public void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-       public void setAgentNodeName(String agentNodeName) {
-               this.agentNodeName = agentNodeName;
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrAttachmentUploader.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrAttachmentUploader.java
deleted file mode 100644 (file)
index 105d549..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.jcr.execution;
-
-import javax.jcr.Session;
-
-import org.argeo.slc.core.attachment.Attachment;
-import org.argeo.slc.core.attachment.AttachmentUploader;
-import org.springframework.core.io.Resource;
-
-/** JCR based attachment uploader */
-public class JcrAttachmentUploader implements AttachmentUploader {
-       private Session session;
-
-       public void upload(Attachment attachment, Resource resource) {
-               session.toString();
-               // not yet implemented, need to review the interface
-       }
-
-       public void setSession(Session session) {
-               this.session = session;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java
deleted file mode 100644 (file)
index 1a2576e..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.jcr.execution;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.SlcNames;
-import org.argeo.slc.SlcTypes;
-import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
-import org.argeo.slc.core.execution.PrimitiveValue;
-import org.argeo.slc.core.execution.RefSpecAttribute;
-import org.argeo.slc.core.execution.RefValueChoice;
-import org.argeo.slc.deploy.ModuleDescriptor;
-import org.argeo.slc.execution.ExecutionFlowDescriptor;
-import org.argeo.slc.execution.ExecutionModuleDescriptor;
-import org.argeo.slc.execution.ExecutionModulesListener;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.argeo.slc.jcr.SlcJcrUtils;
-
-/**
- * Synchronizes the local execution runtime with a JCR repository. For the time
- * being the state is completely reset from one start to another.
- */
-public class JcrExecutionModulesListener implements ExecutionModulesListener,
-               SlcNames {
-       private final static String SLC_EXECUTION_MODULES_PROPERTY = "slc.executionModules";
-
-       private final static Log log = LogFactory
-                       .getLog(JcrExecutionModulesListener.class);
-       private JcrAgent agent;
-
-       private ExecutionModulesManager modulesManager;
-
-       private Repository repository;
-       /**
-        * We don't use a thread bound session because many different threads will
-        * call this critical component and we don't want to login each time. We
-        * therefore rather protect access to this session via synchronized.
-        */
-       private Session session;
-
-       /*
-        * LIFECYCLE
-        */
-       public void init() {
-               try {
-                       session = repository.login();
-                       clearAgent();
-                       if (modulesManager != null) {
-                               Node agentNode = session.getNode(agent.getNodePath());
-
-                               List<ModuleDescriptor> moduleDescriptors = modulesManager
-                                               .listModules();
-
-                               // scan SLC-ExecutionModule metadata
-                               for (ModuleDescriptor md : moduleDescriptors) {
-                                       if (md.getMetadata().containsKey(
-                                                       ExecutionModuleDescriptor.SLC_EXECUTION_MODULE)) {
-                                               String moduleNodeName = SlcJcrUtils
-                                                               .getModuleNodeName(md);
-                                               Node moduleNode = agentNode.hasNode(moduleNodeName) ? agentNode
-                                                               .getNode(moduleNodeName) : agentNode
-                                                               .addNode(moduleNodeName);
-                                               moduleNode.addMixin(SlcTypes.SLC_EXECUTION_MODULE);
-                                               moduleNode.setProperty(SLC_NAME, md.getName());
-                                               moduleNode.setProperty(SLC_VERSION, md.getVersion());
-                                               moduleNode.setProperty(Property.JCR_TITLE,
-                                                               md.getTitle());
-                                               moduleNode.setProperty(Property.JCR_DESCRIPTION,
-                                                               md.getDescription());
-                                               moduleNode.setProperty(SLC_STARTED, md.getStarted());
-                                       }
-                               }
-
-                               // scan execution modules property
-                               String executionModules = System
-                                               .getProperty(SLC_EXECUTION_MODULES_PROPERTY);
-                               if (executionModules != null) {
-                                       for (String executionModule : executionModules.split(",")) {
-                                               allModules: for (ModuleDescriptor md : moduleDescriptors) {
-                                                       String moduleNodeName = SlcJcrUtils
-                                                                       .getModuleNodeName(md);
-                                                       if (md.getName().equals(executionModule)) {
-                                                               Node moduleNode = agentNode
-                                                                               .hasNode(moduleNodeName) ? agentNode
-                                                                               .getNode(moduleNodeName) : agentNode
-                                                                               .addNode(moduleNodeName);
-                                                               moduleNode
-                                                                               .addMixin(SlcTypes.SLC_EXECUTION_MODULE);
-                                                               moduleNode.setProperty(SLC_NAME, md.getName());
-                                                               moduleNode.setProperty(SLC_VERSION,
-                                                                               md.getVersion());
-                                                               moduleNode.setProperty(Property.JCR_TITLE,
-                                                                               md.getTitle());
-                                                               moduleNode.setProperty(
-                                                                               Property.JCR_DESCRIPTION,
-                                                                               md.getDescription());
-                                                               moduleNode.setProperty(SLC_STARTED,
-                                                                               md.getStarted());
-                                                               break allModules;
-                                                       }
-                                               }
-                                       }
-
-                                       // save if needed
-                                       if (session.hasPendingChanges())
-                                               session.save();
-                               }
-                       }
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(session);
-                       JcrUtils.logoutQuietly(session);
-                       throw new SlcException("Cannot initialize modules", e);
-               }
-       }
-
-       public void destroy() {
-               clearAgent();
-               JcrUtils.logoutQuietly(session);
-       }
-
-       protected synchronized void clearAgent() {
-               try {
-                       Node agentNode = session.getNode(agent.getNodePath());
-                       for (NodeIterator nit = agentNode.getNodes(); nit.hasNext();)
-                               nit.nextNode().remove();
-                       session.save();
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new SlcException("Cannot clear agent " + agent, e);
-               }
-       }
-
-       /*
-        * EXECUTION MODULES LISTENER
-        */
-
-       public synchronized void executionModuleAdded(
-                       ModuleDescriptor moduleDescriptor) {
-               syncExecutionModule(moduleDescriptor);
-       }
-
-       protected void syncExecutionModule(ModuleDescriptor moduleDescriptor) {
-               try {
-                       Node agentNode = session.getNode(agent.getNodePath());
-                       String moduleNodeName = SlcJcrUtils
-                                       .getModuleNodeName(moduleDescriptor);
-                       Node moduleNode = agentNode.hasNode(moduleNodeName) ? agentNode
-                                       .getNode(moduleNodeName) : agentNode
-                                       .addNode(moduleNodeName);
-                       moduleNode.addMixin(SlcTypes.SLC_EXECUTION_MODULE);
-                       moduleNode.setProperty(SLC_NAME, moduleDescriptor.getName());
-                       moduleNode.setProperty(SLC_VERSION, moduleDescriptor.getVersion());
-                       moduleNode.setProperty(Property.JCR_TITLE,
-                                       moduleDescriptor.getTitle());
-                       moduleNode.setProperty(Property.JCR_DESCRIPTION,
-                                       moduleDescriptor.getDescription());
-                       moduleNode.setProperty(SLC_STARTED, moduleDescriptor.getStarted());
-                       session.save();
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new SlcException("Cannot sync module " + moduleDescriptor, e);
-               }
-       }
-
-       public synchronized void executionModuleRemoved(
-                       ModuleDescriptor moduleDescriptor) {
-               try {
-                       String moduleName = SlcJcrUtils.getModuleNodeName(moduleDescriptor);
-                       Node agentNode = session.getNode(agent.getNodePath());
-                       if (agentNode.hasNode(moduleName)) {
-                               Node moduleNode = agentNode.getNode(moduleName);
-                               for (NodeIterator nit = moduleNode.getNodes(); nit.hasNext();) {
-                                       nit.nextNode().remove();
-                               }
-                               moduleNode.setProperty(SLC_STARTED, false);
-                       }
-                       session.save();
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new SlcException("Cannot remove module " + moduleDescriptor,
-                                       e);
-               }
-       }
-
-       public synchronized void executionFlowAdded(ModuleDescriptor module,
-                       ExecutionFlowDescriptor efd) {
-               try {
-                       Node agentNode = session.getNode(agent.getNodePath());
-                       Node moduleNode = agentNode.getNode(SlcJcrUtils
-                                       .getModuleNodeName(module));
-                       String relativePath = getExecutionFlowRelativePath(efd);
-                       @SuppressWarnings("unused")
-                       Node flowNode = null;
-                       if (!moduleNode.hasNode(relativePath)) {
-                               flowNode = createExecutionFlowNode(moduleNode, relativePath,
-                                               efd);
-                               session.save();
-                       } else {
-                               flowNode = moduleNode.getNode(relativePath);
-                       }
-
-                       if (log.isTraceEnabled())
-                               log.trace("Flow " + efd + " added to JCR");
-               } catch (RepositoryException e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new SlcException("Cannot add flow " + efd + " from module "
-                                       + module, e);
-               }
-
-       }
-
-       protected Node createExecutionFlowNode(Node moduleNode,
-                       String relativePath, ExecutionFlowDescriptor efd)
-                       throws RepositoryException {
-               Node flowNode = null;
-               List<String> pathTokens = Arrays.asList(relativePath.split("/"));
-
-               Iterator<String> names = pathTokens.iterator();
-               // create intermediary paths
-               Node currNode = moduleNode;
-               while (names.hasNext()) {
-                       String name = names.next();
-                       if (currNode.hasNode(name))
-                               currNode = currNode.getNode(name);
-                       else {
-                               if (names.hasNext())
-                                       currNode = currNode.addNode(name);
-                               else
-                                       flowNode = currNode.addNode(name,
-                                                       SlcTypes.SLC_EXECUTION_FLOW);
-                       }
-               }
-
-               // name, description
-               flowNode.setProperty(SLC_NAME, efd.getName());
-               String endName = pathTokens.get(pathTokens.size() - 1);
-               flowNode.setProperty(Property.JCR_TITLE, endName);
-               if (efd.getDescription() != null
-                               && !efd.getDescription().trim().equals("")) {
-                       flowNode.setProperty(Property.JCR_DESCRIPTION, efd.getDescription());
-               } else {
-                       flowNode.setProperty(Property.JCR_DESCRIPTION, endName);
-               }
-
-               // execution spec
-               ExecutionSpec executionSpec = efd.getExecutionSpec();
-               String esName = executionSpec.getName();
-               if (esName == null || esName.equals(ExecutionSpec.INTERNAL_NAME)
-                               || esName.contains("#")/* automatically generated bean name */) {
-                       // internal spec node
-                       mapExecutionSpec(flowNode, executionSpec);
-               } else {
-                       // reference spec node
-                       Node executionSpecsNode = moduleNode.hasNode(SLC_EXECUTION_SPECS) ? moduleNode
-                                       .getNode(SLC_EXECUTION_SPECS) : moduleNode
-                                       .addNode(SLC_EXECUTION_SPECS);
-                       Node executionSpecNode = executionSpecsNode.addNode(esName,
-                                       SlcTypes.SLC_EXECUTION_SPEC);
-                       executionSpecNode.setProperty(SLC_NAME, esName);
-                       executionSpecNode.setProperty(Property.JCR_TITLE, esName);
-                       if (executionSpec.getDescription() != null
-                                       && !executionSpec.getDescription().trim().equals(""))
-                               executionSpecNode.setProperty(Property.JCR_DESCRIPTION,
-                                               executionSpec.getDescription());
-                       mapExecutionSpec(executionSpecNode, executionSpec);
-                       flowNode.setProperty(SLC_SPEC, executionSpecNode);
-               }
-
-               // flow values
-               for (String attr : efd.getValues().keySet()) {
-                       ExecutionSpecAttribute esa = executionSpec.getAttributes()
-                                       .get(attr);
-                       if (esa instanceof PrimitiveSpecAttribute) {
-                               PrimitiveSpecAttribute psa = (PrimitiveSpecAttribute) esa;
-                               // if spec reference there will be no node at this stage
-                               Node valueNode = JcrUtils.getOrAdd(flowNode, attr);
-                               valueNode.setProperty(SLC_TYPE, psa.getType());
-                               SlcJcrUtils.setPrimitiveAsProperty(valueNode, SLC_VALUE,
-                                               (PrimitiveValue) efd.getValues().get(attr));
-                       }
-               }
-
-               return flowNode;
-       }
-
-       /**
-        * Base can be either an execution spec node, or an execution flow node (in
-        * case the execution spec is internal)
-        */
-       protected void mapExecutionSpec(Node baseNode, ExecutionSpec executionSpec)
-                       throws RepositoryException {
-               for (String attrName : executionSpec.getAttributes().keySet()) {
-                       ExecutionSpecAttribute esa = executionSpec.getAttributes().get(
-                                       attrName);
-                       Node attrNode = baseNode.addNode(attrName);
-                       // booleans
-                       attrNode.addMixin(SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE);
-                       attrNode.setProperty(SLC_IS_IMMUTABLE, esa.getIsImmutable());
-                       attrNode.setProperty(SLC_IS_CONSTANT, esa.getIsConstant());
-                       attrNode.setProperty(SLC_IS_HIDDEN, esa.getIsHidden());
-
-                       if (esa instanceof PrimitiveSpecAttribute) {
-                               attrNode.addMixin(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE);
-                               PrimitiveSpecAttribute psa = (PrimitiveSpecAttribute) esa;
-                               SlcJcrUtils.setPrimitiveAsProperty(attrNode, SLC_VALUE, psa);
-                               attrNode.setProperty(SLC_TYPE, psa.getType());
-                       } else if (esa instanceof RefSpecAttribute) {
-                               attrNode.addMixin(SlcTypes.SLC_REF_SPEC_ATTRIBUTE);
-                               RefSpecAttribute rsa = (RefSpecAttribute) esa;
-                               attrNode.setProperty(SLC_TYPE, rsa.getTargetClassName());
-                               Object value = rsa.getValue();
-                               if (rsa.getChoices() != null) {
-                                       Integer index = null;
-                                       int count = 0;
-                                       for (RefValueChoice choice : rsa.getChoices()) {
-                                               String name = choice.getName();
-                                               if (value != null && name.equals(value.toString()))
-                                                       index = count;
-                                               Node choiceNode = attrNode.addNode(choice.getName());
-                                               choiceNode.addMixin(NodeType.MIX_TITLE);
-                                               choiceNode.setProperty(Property.JCR_TITLE,
-                                                               choice.getName());
-                                               if (choice.getDescription() != null
-                                                               && !choice.getDescription().trim().equals(""))
-                                                       choiceNode.setProperty(Property.JCR_DESCRIPTION,
-                                                                       choice.getDescription());
-                                               count++;
-                                       }
-
-                                       if (index != null)
-                                               attrNode.setProperty(SLC_VALUE, index);
-                               }
-                       }
-               }
-       }
-
-       public synchronized void executionFlowRemoved(ModuleDescriptor module,
-                       ExecutionFlowDescriptor executionFlow) {
-               try {
-                       Node agentNode = session.getNode(agent.getNodePath());
-                       Node moduleNode = agentNode.getNode(SlcJcrUtils
-                                       .getModuleNodeName(module));
-                       String relativePath = getExecutionFlowRelativePath(executionFlow);
-                       if (moduleNode.hasNode(relativePath))
-                               moduleNode.getNode(relativePath).remove();
-                       agentNode.getSession().save();
-               } catch (RepositoryException e) {
-                       throw new SlcException("Cannot remove flow " + executionFlow
-                                       + " from module " + module, e);
-               }
-       }
-
-       /*
-        * UTILITIES
-        */
-       /** @return the relative path, never starts with '/' */
-       @SuppressWarnings("deprecation")
-       protected String getExecutionFlowRelativePath(
-                       ExecutionFlowDescriptor executionFlow) {
-               String relativePath = executionFlow.getPath() == null ? executionFlow
-                               .getName() : executionFlow.getPath() + '/'
-                               + executionFlow.getName();
-               // we assume that it is more than one char long
-               if (relativePath.charAt(0) == '/')
-                       relativePath = relativePath.substring(1);
-               // FIXME quick hack to avoid duplicate '/'
-               relativePath = relativePath.replaceAll("//", "/");
-               return relativePath;
-       }
-
-       /*
-        * BEAN
-        */
-       public void setAgent(JcrAgent agent) {
-               this.agent = agent;
-       }
-
-       public void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-       public void setModulesManager(ExecutionModulesManager modulesManager) {
-               this.modulesManager = modulesManager;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrExecutionProcess.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrExecutionProcess.java
deleted file mode 100644 (file)
index e1ad69e..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.jcr.execution;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.SlcNames;
-import org.argeo.slc.SlcTypes;
-import org.argeo.slc.core.execution.ProcessThread;
-import org.argeo.slc.execution.ExecutionProcess;
-import org.argeo.slc.execution.ExecutionStep;
-import org.argeo.slc.execution.RealizedFlow;
-import org.argeo.slc.jcr.SlcJcrUtils;
-
-/** Execution process implementation based on a JCR node. */
-public class JcrExecutionProcess implements ExecutionProcess, SlcNames {
-       private final static Log log = LogFactory.getLog(JcrExecutionProcess.class);
-       private final Node node;
-
-       private Long nextLogLine = 1l;
-
-       public JcrExecutionProcess(Node node) {
-               this.node = node;
-       }
-
-       public synchronized String getUuid() {
-               try {
-                       return node.getProperty(SLC_UUID).getString();
-               } catch (RepositoryException e) {
-                       throw new SlcException("Cannot get uuid for " + node, e);
-               }
-       }
-
-       public synchronized String getStatus() {
-               try {
-                       return node.getProperty(SLC_STATUS).getString();
-               } catch (RepositoryException e) {
-                       log.error("Cannot get status: " + e);
-                       // we should re-throw exception because this information can
-                       // probably used for monitoring in case there are already unexpected
-                       // exceptions
-                       return UNKOWN;
-               }
-       }
-
-       public synchronized void setStatus(String status) {
-               try {
-                       node.setProperty(SLC_STATUS, status);
-                       // last modified properties needs to be manually updated
-                       // see https://issues.apache.org/jira/browse/JCR-2233
-                       JcrUtils.updateLastModified(node);
-                       node.getSession().save();
-               } catch (RepositoryException e) {
-                       JcrUtils.discardUnderlyingSessionQuietly(node);
-                       // we should re-throw exception because this information can
-                       // probably used for monitoring in case there are already unexpected
-                       // exceptions
-                       log.error("Cannot set status " + status + ": " + e);
-               }
-       }
-
-       /**
-        * Synchronized in order to make sure that there is no concurrent
-        * modification of {@link #nextLogLine}.
-        */
-       public synchronized void addSteps(List<ExecutionStep> steps) {
-               try {
-                       steps: for (ExecutionStep step : steps) {
-                               String type;
-                               if (step.getType().equals(ExecutionStep.TRACE))
-                                       type = SlcTypes.SLC_LOG_TRACE;
-                               else if (step.getType().equals(ExecutionStep.DEBUG))
-                                       type = SlcTypes.SLC_LOG_DEBUG;
-                               else if (step.getType().equals(ExecutionStep.INFO))
-                                       type = SlcTypes.SLC_LOG_INFO;
-                               else if (step.getType().equals(ExecutionStep.WARNING))
-                                       type = SlcTypes.SLC_LOG_WARNING;
-                               else if (step.getType().equals(ExecutionStep.ERROR))
-                                       type = SlcTypes.SLC_LOG_ERROR;
-                               else
-                                       // skip
-                                       continue steps;
-
-                               String relPath = SLC_LOG + '/'
-                                               + step.getThread().replace('/', '_') + '/'
-                                               + step.getLocation().replace('.', '/');
-                               String path = node.getPath() + '/' + relPath;
-                               // clean special character
-                               // TODO factorize in JcrUtils
-                               path = path.replace('@', '_');
-
-                               Node location = JcrUtils.mkdirs(node.getSession(), path);
-                               Node logEntry = location.addNode(Long.toString(nextLogLine),
-                                               type);
-                               logEntry.setProperty(SLC_MESSAGE, step.getLog());
-                               Calendar calendar = new GregorianCalendar();
-                               calendar.setTime(step.getTimestamp());
-                               logEntry.setProperty(SLC_TIMESTAMP, calendar);
-
-                               // System.out.println("Logged " + logEntry.getPath());
-
-                               nextLogLine++;
-                       }
-
-                       // last modified properties needs to be manually updated
-                       // see https://issues.apache.org/jira/browse/JCR-2233
-                       JcrUtils.updateLastModified(node);
-
-                       node.getSession().save();
-               } catch (Exception e) {
-                       JcrUtils.discardUnderlyingSessionQuietly(node);
-                       e.printStackTrace();
-               }
-       }
-
-       // public Node getNode() {
-       // return node;
-       // }
-
-       public List<RealizedFlow> getRealizedFlows() {
-               try {
-                       List<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();
-                       Node rootRealizedFlowNode = node.getNode(SLC_FLOW);
-                       // we just manage one level for the time being
-                       NodeIterator nit = rootRealizedFlowNode.getNodes(SLC_FLOW);
-                       while (nit.hasNext()) {
-                               Node realizedFlowNode = nit.nextNode();
-
-                               if (realizedFlowNode.hasNode(SLC_ADDRESS)) {
-                                       String flowPath = realizedFlowNode.getNode(SLC_ADDRESS)
-                                                       .getProperty(Property.JCR_PATH).getString();
-                                       NameVersion moduleNameVersion = SlcJcrUtils
-                                                       .moduleNameVersion(flowPath);
-                                       ((ProcessThread) Thread.currentThread())
-                                                       .getExecutionModulesManager().start(
-                                                                       moduleNameVersion);
-                               }
-
-                               RealizedFlow realizedFlow = new JcrRealizedFlow(
-                                               realizedFlowNode);
-                               if (realizedFlow != null)
-                                       realizedFlows.add(realizedFlow);
-                       }
-                       return realizedFlows;
-               } catch (RepositoryException e) {
-                       throw new SlcException("Cannot get realized flows", e);
-               }
-       }
-
-       public String getNodePath() {
-               try {
-                       return node.getPath();
-               } catch (RepositoryException e) {
-                       throw new SlcException("Cannot get process node path for " + node,
-                                       e);
-               }
-       }
-
-       public Repository getRepository() {
-               try {
-                       return node.getSession().getRepository();
-               } catch (RepositoryException e) {
-                       throw new SlcException("Cannot get process JCR repository for "
-                                       + node, e);
-               }
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrProcessThread.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrProcessThread.java
deleted file mode 100644 (file)
index a73e1a9..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.jcr.execution;
-
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.jcr.JcrUtils;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.SlcNames;
-import org.argeo.slc.core.execution.ProcessThread;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.ExecutionProcess;
-import org.argeo.slc.execution.RealizedFlow;
-
-/** Where the actual execution takes place */
-public class JcrProcessThread extends ProcessThread implements SlcNames {
-
-       public JcrProcessThread(ThreadGroup processesThreadGroup,
-                       ExecutionModulesManager executionModulesManager,
-                       JcrExecutionProcess process) {
-               super(processesThreadGroup, executionModulesManager, process);
-       }
-
-       /** Overridden in order to set progress status on realized flow nodes. */
-       @Override
-       protected void process() throws InterruptedException {
-               Session session = null;
-               if (getProcess() instanceof JcrExecutionProcess)
-                       try {
-                               session = ((JcrExecutionProcess) getProcess()).getRepository()
-                                               .login();
-
-                               List<RealizedFlow> realizedFlows = getProcess()
-                                               .getRealizedFlows();
-                               for (RealizedFlow realizedFlow : realizedFlows) {
-                                       Node realizedFlowNode = session
-                                                       .getNode(((JcrRealizedFlow) realizedFlow).getPath());
-                                       setFlowStatus(realizedFlowNode, ExecutionProcess.RUNNING);
-
-                                       try {
-                                               //
-                                               // EXECUTE THE FLOW
-                                               //
-                                               execute(realizedFlow, true);
-
-                                               setFlowStatus(realizedFlowNode,
-                                                               ExecutionProcess.COMPLETED);
-                                       } catch (RepositoryException e) {
-                                               throw e;
-                                       } catch (InterruptedException e) {
-                                               setFlowStatus(realizedFlowNode, ExecutionProcess.KILLED);
-                                               throw e;
-                                       } catch (RuntimeException e) {
-                                               setFlowStatus(realizedFlowNode, ExecutionProcess.ERROR);
-                                               throw e;
-                                       }
-                               }
-                       } catch (RepositoryException e) {
-                               throw new SlcException("Cannot process "
-                                               + getJcrExecutionProcess().getNodePath(), e);
-                       } finally {
-                               JcrUtils.logoutQuietly(session);
-                       }
-               else
-                       super.process();
-       }
-
-       protected void setFlowStatus(Node realizedFlowNode, String status)
-                       throws RepositoryException {
-               realizedFlowNode.setProperty(SLC_STATUS, status);
-               realizedFlowNode.getSession().save();
-       }
-
-       protected JcrExecutionProcess getJcrExecutionProcess() {
-               return (JcrExecutionProcess) getProcess();
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrRealizedFlow.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrRealizedFlow.java
deleted file mode 100644 (file)
index c371b11..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-package org.argeo.slc.jcr.execution;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-
-import org.argeo.slc.SlcException;
-import org.argeo.slc.SlcNames;
-import org.argeo.slc.SlcTypes;
-import org.argeo.slc.core.execution.DefaultExecutionSpec;
-import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
-import org.argeo.slc.core.execution.PrimitiveUtils;
-import org.argeo.slc.core.execution.RefSpecAttribute;
-import org.argeo.slc.execution.ExecutionFlowDescriptor;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.argeo.slc.execution.RealizedFlow;
-import org.argeo.slc.jcr.SlcJcrUtils;
-
-public class JcrRealizedFlow extends RealizedFlow implements SlcNames {
-       private static final long serialVersionUID = -3709453850260712001L;
-       private String path;
-
-       public JcrRealizedFlow(Node node) {
-               try {
-                       this.path = node.getPath();
-                       loadFromNode(node);
-               } catch (RepositoryException e) {
-                       throw new SlcException("Cannot initialize from " + node, e);
-               }
-       }
-
-       protected void loadFromNode(Node realizedFlowNode)
-                       throws RepositoryException {
-               if (realizedFlowNode.hasNode(SLC_ADDRESS)) {
-                       String flowPath = realizedFlowNode.getNode(SLC_ADDRESS)
-                                       .getProperty(Property.JCR_PATH).getString();
-                       // TODO: convert to local path if remote
-                       // FIXME start related module
-                       Node flowNode = realizedFlowNode.getSession().getNode(flowPath);
-                       String flowName = flowNode.getProperty(SLC_NAME).getString();
-                       String description = null;
-                       if (flowNode.hasProperty(Property.JCR_DESCRIPTION))
-                               description = flowNode.getProperty(Property.JCR_DESCRIPTION)
-                                               .getString();
-
-                       Node executionModuleNode = flowNode.getSession().getNode(
-                                       SlcJcrUtils.modulePath(flowPath));
-                       String executionModuleName = executionModuleNode.getProperty(
-                                       SLC_NAME).getString();
-                       String executionModuleVersion = executionModuleNode.getProperty(
-                                       SLC_VERSION).getString();
-
-                       RealizedFlow realizedFlow = this;
-                       realizedFlow.setModuleName(executionModuleName);
-                       realizedFlow.setModuleVersion(executionModuleVersion);
-
-                       // retrieve execution spec
-                       DefaultExecutionSpec executionSpec = new DefaultExecutionSpec();
-                       Map<String, ExecutionSpecAttribute> attrs = readExecutionSpecAttributes(realizedFlowNode);
-                       executionSpec.setAttributes(attrs);
-
-                       // set execution spec name
-                       if (flowNode.hasProperty(SlcNames.SLC_SPEC)) {
-                               Node executionSpecNode = flowNode.getProperty(SLC_SPEC)
-                                               .getNode();
-                               executionSpec.setBeanName(executionSpecNode.getProperty(
-                                               SLC_NAME).getString());
-                       }
-
-                       // explicitly retrieve values
-                       Map<String, Object> values = new HashMap<String, Object>();
-                       for (String attrName : attrs.keySet()) {
-                               ExecutionSpecAttribute attr = attrs.get(attrName);
-                               Object value = attr.getValue();
-                               values.put(attrName, value);
-                       }
-
-                       ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(flowName,
-                                       description, values, executionSpec);
-                       realizedFlow.setFlowDescriptor(efd);
-               } else {
-                       throw new SlcException("Unsupported realized flow "
-                                       + realizedFlowNode);
-               }
-       }
-
-       protected Map<String, ExecutionSpecAttribute> readExecutionSpecAttributes(
-                       Node node) {
-               try {
-                       Map<String, ExecutionSpecAttribute> attrs = new HashMap<String, ExecutionSpecAttribute>();
-                       for (NodeIterator nit = node.getNodes(); nit.hasNext();) {
-                               Node specAttrNode = nit.nextNode();
-                               if (specAttrNode
-                                               .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) {
-                                       String type = specAttrNode.getProperty(SLC_TYPE)
-                                                       .getString();
-                                       Object value = null;
-                                       if (specAttrNode.hasProperty(SLC_VALUE)) {
-                                               String valueStr = specAttrNode.getProperty(SLC_VALUE)
-                                                               .getString();
-                                               value = PrimitiveUtils.convert(type, valueStr);
-                                       }
-                                       PrimitiveSpecAttribute specAttr = new PrimitiveSpecAttribute(
-                                                       type, value);
-                                       attrs.put(specAttrNode.getName(), specAttr);
-                               } else if (specAttrNode
-                                               .isNodeType(SlcTypes.SLC_REF_SPEC_ATTRIBUTE)) {
-                                       if (!specAttrNode.hasProperty(SLC_VALUE)) {
-                                               continue;
-                                       }
-                                       Integer value = (int) specAttrNode.getProperty(SLC_VALUE)
-                                                       .getLong();
-                                       RefSpecAttribute specAttr = new RefSpecAttribute();
-                                       NodeIterator children = specAttrNode.getNodes();
-                                       int index = 0;
-                                       String id = null;
-                                       while (children.hasNext()) {
-                                               Node child = children.nextNode();
-                                               if (index == value)
-                                                       id = child.getName();
-                                               index++;
-                                       }
-                                       specAttr.setValue(id);
-                                       attrs.put(specAttrNode.getName(), specAttr);
-                               }
-                               // throw new SlcException("Unsupported spec attribute "
-                               // + specAttrNode);
-                       }
-                       return attrs;
-               } catch (RepositoryException e) {
-                       throw new SlcException("Cannot read spec attributes from " + node,
-                                       e);
-               }
-       }
-
-       public String getPath() {
-               return path;
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/BundleRegister.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/BundleRegister.java
deleted file mode 100644 (file)
index 747785f..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi;
-
-/** <b>Experimental</b> A structured set of OSGi bundles. */
-public interface BundleRegister {
-       /**
-        * @param pkg
-        *            the Java package
-        * @param version
-        *            the version, can be only major.minor or null
-        * @return the bundle providing this package or null if none was found
-        */
-       public String bundleProvidingPackage(String pkg, String version);
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/BundlesManager.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/BundlesManager.java
deleted file mode 100644 (file)
index 9877c31..0000000
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi;
-
-import java.util.Collection;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.eclipse.gemini.blueprint.context.BundleContextAware;
-import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEvent;
-import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextListener;
-import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextClosedEvent;
-import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextFailedEvent;
-import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextRefreshedEvent;
-import org.eclipse.gemini.blueprint.util.OsgiBundleUtils;
-import org.eclipse.gemini.blueprint.util.OsgiFilterUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.FrameworkEvent;
-import org.osgi.framework.FrameworkListener;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.packageadmin.PackageAdmin;
-import org.osgi.util.tracker.ServiceTracker;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.context.ApplicationContext;
-import org.springframework.util.Assert;
-
-/** Wraps low-level access to a {@link BundleContext} */
-@SuppressWarnings("deprecation")
-public class BundlesManager implements BundleContextAware, FrameworkListener,
-               InitializingBean, DisposableBean,
-               OsgiBundleApplicationContextListener<OsgiBundleApplicationContextEvent> {
-       private final static Log log = LogFactory.getLog(BundlesManager.class);
-
-       private BundleContext bundleContext;
-
-       private Long defaultTimeout = 60 * 1000l;
-       private Long pollingPeriod = 200l;
-
-       // Refresh sync objects
-       private final Object refreshedPackageSem = new Object();
-       private Boolean packagesRefreshed = false;
-
-       public BundlesManager() {
-       }
-
-       public BundlesManager(BundleContext bundleContext) {
-               this.bundleContext = bundleContext;
-       }
-
-       /**
-        * Stop the module, update it, refresh it and restart it. All synchronously.
-        */
-       public void upgradeSynchronous(OsgiBundle osgiBundle) {
-               try {
-                       Bundle bundle = findRelatedBundle(osgiBundle);
-
-                       long begin = System.currentTimeMillis();
-
-                       long bStop = begin;
-                       stopSynchronous(bundle);
-
-                       long bUpdate = System.currentTimeMillis();
-                       updateSynchronous(bundle);
-
-                       // Refresh in case there are fragments
-                       long bRefresh = System.currentTimeMillis();
-                       refreshSynchronous(bundle);
-
-                       long bStart = System.currentTimeMillis();
-                       startSynchronous(bundle);
-
-                       long aStart = System.currentTimeMillis();
-                       if (log.isTraceEnabled()) {
-                               log.debug("OSGi upgrade performed in " + (aStart - begin)
-                                               + "ms for bundle " + osgiBundle);
-                               log.debug(" stop \t: " + (bUpdate - bStop) + "ms");
-                               log.debug(" update\t: " + (bRefresh - bUpdate) + "ms");
-                               log.debug(" refresh\t: " + (bStart - bRefresh) + "ms");
-                               log.debug(" start\t: " + (aStart - bStart) + "ms");
-                               log.debug(" TOTAL\t: " + (aStart - begin) + "ms");
-                       }
-
-                       long bAppContext = System.currentTimeMillis();
-                       String filter = "(Bundle-SymbolicName=" + bundle.getSymbolicName()
-                                       + ")";
-                       // Wait for application context to be ready
-                       // TODO: use service tracker
-                       Collection<ServiceReference<ApplicationContext>> srs = getServiceRefSynchronous(
-                                       ApplicationContext.class, filter);
-                       ServiceReference<ApplicationContext> sr = srs.iterator().next();
-                       long aAppContext = System.currentTimeMillis();
-                       long end = aAppContext;
-
-                       if (log.isTraceEnabled()) {
-                               log.debug("Application context refresh performed in "
-                                               + (aAppContext - bAppContext) + "ms for bundle "
-                                               + osgiBundle);
-                       }
-
-                       if (log.isDebugEnabled())
-                               log.debug("Bundle '" + bundle.getSymbolicName()
-                                               + "' upgraded and ready " + " (upgrade performed in "
-                                               + (end - begin) + "ms).");
-
-                       if (log.isTraceEnabled()) {
-                               ApplicationContext applicationContext = (ApplicationContext) bundleContext
-                                               .getService(sr);
-                               int beanDefCount = applicationContext.getBeanDefinitionCount();
-                               log.debug(" " + beanDefCount + " beans in app context of "
-                                               + bundle.getSymbolicName()
-                                               + ", average init time per bean=" + (end - begin)
-                                               / beanDefCount + "ms");
-                       }
-
-                       bundleContext.ungetService(sr);
-
-               } catch (Exception e) {
-                       throw new SlcException("Cannot update bundle " + osgiBundle, e);
-               }
-       }
-
-       /** Updates bundle synchronously. */
-       protected void updateSynchronous(Bundle bundle) throws BundleException {
-               bundle.update();
-               boolean waiting = true;
-
-               long begin = System.currentTimeMillis();
-               do {
-                       int state = bundle.getState();
-                       if (state == Bundle.INSTALLED || state == Bundle.ACTIVE
-                                       || state == Bundle.RESOLVED)
-                               waiting = false;
-
-                       sleepWhenPolling();
-                       checkTimeout(begin, "Update of bundle " + bundle.getSymbolicName()
-                                       + " timed out. Bundle state = " + bundle.getState());
-               } while (waiting);
-
-               if (log.isTraceEnabled())
-                       log.debug("Bundle " + bundle.getSymbolicName() + " updated.");
-       }
-
-       /** Starts bundle synchronously. Does nothing if already started. */
-       protected void startSynchronous(Bundle bundle) throws BundleException {
-               int originalState = bundle.getState();
-               if (originalState == Bundle.ACTIVE)
-                       return;
-
-               bundle.start();
-               boolean waiting = true;
-
-               long begin = System.currentTimeMillis();
-               do {
-                       if (bundle.getState() == Bundle.ACTIVE)
-                               waiting = false;
-
-                       sleepWhenPolling();
-                       checkTimeout(begin, "Start of bundle " + bundle.getSymbolicName()
-                                       + " timed out. Bundle state = " + bundle.getState());
-               } while (waiting);
-
-               if (log.isTraceEnabled())
-                       log.debug("Bundle " + bundle.getSymbolicName() + " started.");
-       }
-
-       /** Stops bundle synchronously. Does nothing if already started. */
-       protected void stopSynchronous(Bundle bundle) throws BundleException {
-               int originalState = bundle.getState();
-               if (originalState != Bundle.ACTIVE)
-                       return;
-
-               bundle.stop();
-               boolean waiting = true;
-
-               long begin = System.currentTimeMillis();
-               do {
-                       if (bundle.getState() != Bundle.ACTIVE
-                                       && bundle.getState() != Bundle.STOPPING)
-                               waiting = false;
-
-                       sleepWhenPolling();
-                       checkTimeout(begin, "Stop of bundle " + bundle.getSymbolicName()
-                                       + " timed out. Bundle state = " + bundle.getState());
-               } while (waiting);
-
-               if (log.isTraceEnabled())
-                       log.debug("Bundle " + bundle.getSymbolicName() + " stopped.");
-       }
-
-       /** Refresh bundle synchronously. Does nothing if already started. */
-       protected void refreshSynchronous(Bundle bundle) throws BundleException {
-               ServiceReference<PackageAdmin> packageAdminRef = bundleContext
-                               .getServiceReference(PackageAdmin.class);
-               PackageAdmin packageAdmin = (PackageAdmin) bundleContext
-                               .getService(packageAdminRef);
-               Bundle[] bundles = { bundle };
-
-               long begin = System.currentTimeMillis();
-               synchronized (refreshedPackageSem) {
-                       packagesRefreshed = false;
-                       packageAdmin.refreshPackages(bundles);
-                       try {
-                               refreshedPackageSem.wait(defaultTimeout);
-                       } catch (InterruptedException e) {
-                               // silent
-                       }
-                       if (!packagesRefreshed) {
-                               long now = System.currentTimeMillis();
-                               throw new SlcException("Packages not refreshed after "
-                                               + (now - begin) + "ms");
-                       } else {
-                               packagesRefreshed = false;
-                       }
-               }
-
-               if (log.isTraceEnabled())
-                       log.debug("Bundle " + bundle.getSymbolicName() + " refreshed.");
-       }
-
-       public void frameworkEvent(FrameworkEvent event) {
-               if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
-                       synchronized (refreshedPackageSem) {
-                               packagesRefreshed = true;
-                               refreshedPackageSem.notifyAll();
-                       }
-               }
-       }
-
-       public <S> Collection<ServiceReference<S>> getServiceRefSynchronous(
-                       Class<S> clss, String filter) throws InvalidSyntaxException {
-               if (log.isTraceEnabled())
-                       log.debug("Filter: '" + filter + "'");
-               Collection<ServiceReference<S>> sfs = null;
-               boolean waiting = true;
-               long begin = System.currentTimeMillis();
-               do {
-                       sfs = bundleContext.getServiceReferences(clss, filter);
-
-                       if (sfs != null)
-                               waiting = false;
-
-                       sleepWhenPolling();
-                       checkTimeout(begin, "Search of services " + clss + " with filter "
-                                       + filter + " timed out.");
-               } while (waiting);
-
-               return sfs;
-       }
-
-       protected void checkTimeout(long begin, String msg) {
-               long now = System.currentTimeMillis();
-               if (now - begin > defaultTimeout)
-                       throw new SlcException(msg + " (timeout after " + (now - begin)
-                                       + "ms)");
-
-       }
-
-       protected void sleepWhenPolling() {
-               try {
-                       Thread.sleep(pollingPeriod);
-               } catch (InterruptedException e) {
-                       throw new SlcException("Polling interrupted");
-               }
-       }
-
-       /** Creates and open a new service tracker. */
-       public <S> ServiceTracker<S, S> newTracker(Class<S> clss) {
-               ServiceTracker<S, S> st = new ServiceTracker<S, S>(bundleContext, clss,
-                               null);
-               st.open();
-               return st;
-       }
-
-       public <T> T getSingleService(Class<T> clss, String filter,
-                       Boolean synchronous) {
-               if (filter != null)
-                       Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter");
-               Collection<ServiceReference<T>> sfs;
-               try {
-                       if (synchronous)
-                               sfs = getServiceRefSynchronous(clss, filter);
-                       else
-                               sfs = bundleContext.getServiceReferences(clss, filter);
-               } catch (InvalidSyntaxException e) {
-                       throw new SlcException("Cannot retrieve service reference for "
-                                       + filter, e);
-               }
-
-               if (sfs == null || sfs.size() == 0)
-                       return null;
-               else if (sfs.size() > 1)
-                       throw new SlcException("More than one execution flow found for "
-                                       + filter);
-               return (T) bundleContext.getService(sfs.iterator().next());
-       }
-
-       public <T> T getSingleServiceStrict(Class<T> clss, String filter,
-                       Boolean synchronous) {
-               T service = getSingleService(clss, filter, synchronous);
-               if (service == null)
-                       throw new SlcException("No execution flow found for " + filter);
-               else
-                       return service;
-       }
-
-       public OsgiBundle findRelatedBundle(String moduleName, String moduleVersion) {
-               OsgiBundle osgiBundle = new OsgiBundle(moduleName, moduleVersion);
-               if (osgiBundle.getVersion() == null) {
-                       Bundle bundle = findRelatedBundle(osgiBundle);
-                       osgiBundle = new OsgiBundle(bundle);
-               }
-               return osgiBundle;
-       }
-
-       /**
-        * @param osgiBundle
-        *            cannot be null
-        * @return the related bundle or null if not found
-        * @throws SlcException
-        *             if osgiBundle argument is null
-        */
-       public Bundle findRelatedBundle(OsgiBundle osgiBundle) {
-               if (osgiBundle == null)
-                       throw new SlcException("OSGi bundle cannot be null");
-
-               Bundle bundle = null;
-               if (osgiBundle.getInternalBundleId() != null) {
-                       bundle = bundleContext.getBundle(osgiBundle.getInternalBundleId());
-                       Assert.isTrue(
-                                       osgiBundle.getName().equals(bundle.getSymbolicName()),
-                                       "symbolic name consistent");
-                       if (osgiBundle.getVersion() != null)
-                               Assert.isTrue(
-                                               osgiBundle.getVersion().equals(
-                                                               bundle.getHeaders().get(
-                                                                               Constants.BUNDLE_VERSION)),
-                                               "version consistent");
-               } else if (osgiBundle.getVersion() == null
-                               || osgiBundle.getVersion().equals("0.0.0")) {
-                       bundle = OsgiBundleUtils.findBundleBySymbolicName(bundleContext,
-                                       osgiBundle.getName());
-               } else {// scan all bundles
-                       bundles: for (Bundle b : bundleContext.getBundles()) {
-                               if (b.getSymbolicName() == null) {
-                                       log.warn("Bundle " + b + " has no symbolic name defined.");
-                                       continue bundles;
-                               }
-
-                               if (b.getSymbolicName().equals(osgiBundle.getName())) {
-                                       if (osgiBundle.getVersion() == null) {
-                                               bundle = b;
-                                               break bundles;
-                                       }
-
-                                       if (b.getHeaders().get(Constants.BUNDLE_VERSION)
-                                                       .equals(osgiBundle.getVersion())) {
-                                               bundle = b;
-                                               osgiBundle.setInternalBundleId(b.getBundleId());
-                                               break bundles;
-                                       }
-                               }
-                       }
-               }
-               return bundle;
-       }
-
-       /** Find a single bundle based on a symbolic name pattern. */
-       public OsgiBundle findFromPattern(String pattern) {
-               OsgiBundle osgiBundle = null;
-               for (Bundle b : bundleContext.getBundles()) {
-                       if (b.getSymbolicName().contains(pattern)) {
-                               osgiBundle = new OsgiBundle(b);
-                               break;
-                       }
-               }
-               return osgiBundle;
-       }
-
-       public OsgiBundle getBundle(Long bundleId) {
-               Bundle bundle = bundleContext.getBundle(bundleId);
-               return new OsgiBundle(bundle);
-       }
-
-       public void setBundleContext(BundleContext bundleContext) {
-               this.bundleContext = bundleContext;
-       }
-
-       public void afterPropertiesSet() throws Exception {
-               bundleContext.addFrameworkListener(this);
-       }
-
-       public void destroy() throws Exception {
-               bundleContext.removeFrameworkListener(this);
-       }
-
-       public void setDefaultTimeout(Long defaultTimeout) {
-               this.defaultTimeout = defaultTimeout;
-       }
-
-       /**
-        * Use with caution since it may interfer with some cached information
-        * within this object
-        */
-       public BundleContext getBundleContext() {
-               return bundleContext;
-       }
-
-       public void setPollingPeriod(Long pollingPeriod) {
-               this.pollingPeriod = pollingPeriod;
-       }
-
-       public void onOsgiApplicationEvent(OsgiBundleApplicationContextEvent event) {
-               if (event instanceof OsgiBundleContextRefreshedEvent) {
-                       log.debug("App context refreshed: " + event);
-               } else if (event instanceof OsgiBundleContextFailedEvent) {
-                       log.debug("App context failed: " + event);
-               }
-               if (event instanceof OsgiBundleContextClosedEvent) {
-                       log.debug("App context closed: " + event);
-               }
-
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/FileSystemBundleRegister.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/FileSystemBundleRegister.java
deleted file mode 100644 (file)
index 03f21c5..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi;
-
-import java.io.File;
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.osgi.framework.Constants;
-
-/** <b>Experimental</b> */
-public class FileSystemBundleRegister implements BundleRegister {
-       private final static Log log = LogFactory
-                       .getLog(FileSystemBundleRegister.class);
-       private Properties packagesBundles = null;
-
-       public String bundleProvidingPackage(String pkg, String version) {
-               if (packagesBundles == null)
-                       return null;
-               return packagesBundles.getProperty(pkg);
-       }
-
-       protected void scan(File baseDirectory) {
-               long begin = System.currentTimeMillis();
-               int bundleCount = 0;
-               int packageCount = 0;
-
-               packagesBundles = new Properties();
-
-               File[] files = baseDirectory.listFiles();
-               for (File file : files) {
-                       if (file.isDirectory()) {
-
-                       } else {
-                               JarFile jarFile = null;
-                               try {
-                                       jarFile = new JarFile(file);
-                                       Manifest manifest = jarFile.getManifest();
-                                       String symbolicName = manifest.getMainAttributes()
-                                                       .getValue(Constants.BUNDLE_SYMBOLICNAME);
-                                       String exportPackage = manifest.getMainAttributes()
-                                                       .getValue(Constants.EXPORT_PACKAGE);
-
-                                       // List exported packages
-                                       Set<String> exportedPackages = exportPackageToPackageNames(exportPackage);
-
-                                       for (String exportedPackage : exportedPackages) {
-                                               packagesBundles.put(exportedPackage, symbolicName);
-                                               packageCount++;
-                                               if (log.isTraceEnabled())
-                                                       log.trace("Register " + exportedPackage + "="
-                                                                       + symbolicName);
-                                       }
-                                       bundleCount++;
-                               } catch (Exception e) {
-                                       log.warn("Cannot scan " + file, e);
-                                       if (log.isTraceEnabled())
-                                               e.printStackTrace();
-                               } finally {
-                                       IOUtils.closeQuietly(jarFile);
-                               }
-                       }
-               }
-               if (log.isDebugEnabled())
-                       log.debug("Scanned " + bundleCount + " bundles with "
-                                       + packageCount + " packages in "
-                                       + (System.currentTimeMillis() - begin) + " ms");
-       }
-
-       protected Set<String> exportPackageToPackageNames(String exportPackage) {
-               Set<String> exportedPackages = new HashSet<String>();
-               if (exportPackage == null)
-                       return exportedPackages;
-               char[] arr = exportPackage.toCharArray();
-
-               StringBuffer currentPkg = new StringBuffer("");
-               boolean skip = false;
-               boolean inQuote = false;
-               for (char c : arr) {
-                       if (c == ' ' || c == '\n') {
-                               // ignore
-                       } else if (c == ';') {
-                               if (!skip)
-                                       skip = true;
-                       } else if (c == ',') {
-                               if (skip && !inQuote) {
-                                       skip = false;
-                                       // add new package
-                                       exportedPackages.add(currentPkg.toString());
-                                       currentPkg = new StringBuffer("");
-                               }
-                       } else if (c == '\"') {
-                               inQuote = inQuote ? false : true;
-                       } else {
-                               if (!skip)
-                                       currentPkg.append(c);
-                       }
-               }
-
-               return exportedPackages;
-       }
-
-       public static void main(String[] args) {
-               FileSystemBundleRegister fsbr = new FileSystemBundleRegister();
-               fsbr.scan(new File(
-                               "/home/mbaudier/dev/src/slc/dist/org.argeo.slc.sdk/target/lib"));
-
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java
deleted file mode 100644 (file)
index 2d8b031..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationEvent;
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.event.ContextRefreshedEvent;
-import org.springframework.core.Ordered;
-
-/** Publishes beans of the application context as OSGi services. */
-@SuppressWarnings(value = { "unchecked", "rawtypes" })
-public class MultipleServiceExporterPostProcessor implements
-               ApplicationListener, Ordered {
-       private final static Log log = LogFactory
-                       .getLog(MultipleServiceExporterPostProcessor.class);
-
-       private List<Class> interfaces = new ArrayList<Class>();
-
-       private int order = Ordered.LOWEST_PRECEDENCE;
-
-       private BundleContext bundleContext = null;
-
-       // private Class osgiServiceFactoryClass = OsgiServiceFactoryBean.class;
-       // private Boolean useServiceProviderContextClassLoader = false;
-
-       public void onApplicationEvent(ApplicationEvent event) {
-               Map<String, Object> beans = new HashMap<String, Object>();
-               if (event instanceof ContextRefreshedEvent) {
-                       if (bundleContext != null) {
-                               for (Class clss : interfaces) {
-                                       ApplicationContext ac = ((ContextRefreshedEvent) event)
-                                                       .getApplicationContext();
-                                       beans.putAll(ac.getBeansOfType(clss, false, false));
-                               }
-
-                               int count = 0;
-                               for (String beanName : beans.keySet()) {
-                                       Object bean = beans.get(beanName);
-                                       List<String> classes = new ArrayList<String>();
-                                       for (Class clss : interfaces) {
-                                               if (clss.isAssignableFrom(bean.getClass())) {
-                                                       classes.add(clss.getName());
-                                               }
-                                       }
-                                       Properties props = new Properties();
-                                       Bundle bundle = bundleContext.getBundle();
-                                       props.put(Constants.BUNDLE_SYMBOLICNAME,
-                                                       bundle.getSymbolicName());
-                                       props.put(Constants.BUNDLE_VERSION, bundle.getVersion());
-                                       // retrocompatibility with pre-1.0:
-                                       props.put("org.eclipse.gemini.blueprint.bean.name", beanName);
-                                       bundleContext.registerService(
-                                                       classes.toArray(new String[classes.size()]), bean,
-                                                       new Hashtable(props));
-                                       count++;
-                               }
-                               if (log.isTraceEnabled())
-                                       log.trace("Published " + count + " " + interfaces
-                                                       + " as OSGi services from bundle "
-                                                       + bundleContext.getBundle().getSymbolicName() + " "
-                                                       + bundleContext.getBundle().getVersion());
-                               // note: the services will be automatically unregistered when
-                               // the bundle will be stopped
-                       }
-               }
-       }
-
-       // public void postProcessBeanFactory(
-       // ConfigurableListableBeanFactory beanFactory) throws BeansException {
-       // if (!(beanFactory instanceof BeanDefinitionRegistry)) {
-       // throw new SlcException("Can only work on "
-       // + BeanDefinitionRegistry.class);
-       // }
-       //
-       // long begin = System.currentTimeMillis();
-       //
-       // // Merge all beans implementing these interfaces
-       // Set<String> beanNames = new HashSet<String>();
-       // for (Class clss : interfaces) {
-       // String[] strs = beanFactory.getBeanNamesForType(clss, true, false);
-       // beanNames.addAll(Arrays.asList(strs));
-       // }
-       //
-       // // Register service factory beans for them
-       // for (String beanName : beanNames) {
-       // MutablePropertyValues mpv = new MutablePropertyValues();
-       // mpv.addPropertyValue("interfaces", interfaces.toArray());
-       // mpv.addPropertyValue("targetBeanName", beanName);
-       // if (useServiceProviderContextClassLoader)
-       // mpv.addPropertyValue("contextClassLoader",
-       // ExportContextClassLoader.SERVICE_PROVIDER);
-       // RootBeanDefinition bd = new RootBeanDefinition(
-       // osgiServiceFactoryClass, mpv);
-       //
-       // String exporterBeanName = "osgiService." + beanName;
-       // if (log.isTraceEnabled())
-       // log.debug("Registering OSGi service exporter "
-       // + exporterBeanName);
-       // ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(
-       // exporterBeanName, bd);
-       // }
-       //
-       // long end = System.currentTimeMillis();
-       // if (log.isTraceEnabled())
-       // log.debug("Multiple services exported in " + (end - begin)
-       // + " ms in bundle.");
-       //
-       // }
-
-       public void setInterfaces(List<Class> interfaces) {
-               this.interfaces = interfaces;
-       }
-
-       // public void setOsgiServiceFactoryClass(Class osgiServiceFactoryClass) {
-       // this.osgiServiceFactoryClass = osgiServiceFactoryClass;
-       // }
-
-       public int getOrder() {
-               return order;
-       }
-
-       public void setOrder(int order) {
-               this.order = order;
-       }
-
-       // public void setUseServiceProviderContextClassLoader(
-       // Boolean useServiceProviderContextClassLoader) {
-       // this.useServiceProviderContextClassLoader =
-       // useServiceProviderContextClassLoader;
-       // }
-
-       public void setBundleContext(BundleContext bundleContext) {
-               this.bundleContext = bundleContext;
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiBundle.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiBundle.java
deleted file mode 100644 (file)
index cb11615..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi;
-
-import org.argeo.slc.DefaultNameVersion;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.build.Distribution;
-import org.argeo.slc.core.build.ResourceDistribution;
-import org.argeo.slc.deploy.DeploymentData;
-import org.argeo.slc.deploy.Module;
-import org.argeo.slc.deploy.ModuleDescriptor;
-import org.argeo.slc.deploy.TargetData;
-import org.argeo.slc.execution.RealizedFlow;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.springframework.core.io.Resource;
-
-/** A deployed OSGi bundle. */
-public class OsgiBundle extends DefaultNameVersion implements Module {
-       private ResourceDistribution distribution;
-
-       private Long internalBundleId;
-
-       private String title;
-       private String description;
-
-       public OsgiBundle() {
-
-       }
-
-       public OsgiBundle(String name, String version) {
-               super(name, version);
-       }
-
-       public OsgiBundle(NameVersion nameVersion) {
-               super(nameVersion);
-       }
-
-       public OsgiBundle(Bundle bundle) {
-               super(bundle.getSymbolicName(), getVersionSafe(bundle));
-               internalBundleId = bundle.getBundleId();
-       }
-
-       /**
-        * Initialize from a {@link RealizedFlow}.
-        * 
-        * @deprecated introduce an unnecessary dependency. TODO: create a separate
-        *             helper.
-        */
-       public OsgiBundle(RealizedFlow realizedFlow) {
-               super(realizedFlow.getModuleName(), realizedFlow.getModuleVersion());
-       }
-
-       /** Utility to avoid NPE. */
-       private static String getVersionSafe(Bundle bundle) {
-               Object versionObj = bundle.getHeaders().get(Constants.BUNDLE_VERSION);
-               if (versionObj != null)
-                       return versionObj.toString();
-               else
-                       return null;
-       }
-
-       /** Unique deployed system id. TODO: use internal bundle id when available? */
-       public String getDeployedSystemId() {
-               return getName() + ":" + getVersion();
-       }
-
-       /**
-        * OSGi bundle are self-contained and do not require additional deployment
-        * data.
-        * 
-        * @return always null
-        */
-       public DeploymentData getDeploymentData() {
-               return null;
-       }
-
-       /** The related distribution. */
-       public Distribution getDistribution() {
-               return distribution;
-       }
-
-       /**
-        * The related distribution, a jar file with OSGi metadata referenced by a
-        * {@link Resource}.
-        */
-       public ResourceDistribution getResourceDistribution() {
-               return distribution;
-       }
-
-       /** TODO: reference the {@link OsgiRuntime} as target data? */
-       public TargetData getTargetData() {
-               throw new UnsupportedOperationException();
-       }
-
-       public void setResourceDistribution(ResourceDistribution distribution) {
-               this.distribution = distribution;
-       }
-
-       /**
-        * Bundle ID used by the OSGi runtime. To be used for optimization when
-        * looking in the bundle context. Can therefore be null.
-        */
-       public Long getInternalBundleId() {
-               return internalBundleId;
-       }
-
-       /** Only package access for the time being. e.g. from {@link BundlesManager} */
-       void setInternalBundleId(Long internalBundleId) {
-               this.internalBundleId = internalBundleId;
-       }
-
-       /** Value of the <code>Bundle-Name</code> directive. */
-       public String getTitle() {
-               return title;
-       }
-
-       public void setTitle(String label) {
-               this.title = label;
-       }
-
-       /** Value of the <code>Bundle-Description</code> directive. */
-       public String getDescription() {
-               return description;
-       }
-
-       public void setDescription(String description) {
-               this.description = description;
-       }
-
-       public ModuleDescriptor getModuleDescriptor() {
-               ModuleDescriptor moduleDescriptor = new ModuleDescriptor();
-               moduleDescriptor.setName(getName());
-               moduleDescriptor.setVersion(getVersion());
-               moduleDescriptor.setDescription(description);
-               moduleDescriptor.setTitle(title);
-               return moduleDescriptor;
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionModule.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionModule.java
deleted file mode 100644 (file)
index df7ae9b..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.core.execution.AbstractSpringExecutionModule;
-import org.argeo.slc.execution.ExecutionContext;
-
-@Deprecated
-public class OsgiExecutionModule extends AbstractSpringExecutionModule {
-       private final static Log log = LogFactory.getLog(OsgiExecutionModule.class);
-
-       public OsgiExecutionModule() {
-               log.error("######## ERROR - DEPRECATED APPROACH USED ########");
-               log.error(OsgiExecutionModule.class.getName() + " is deprecated. ");
-               log
-                               .error("It will be removed in the next release. Remove its bean definition.");
-               log
-                               .error("And replace: <service interface=\"org.argeo.slc.execution.ExecutionModule\" ref=\"executionModule\" />");
-               log
-                               .error("by: <beans:import resource=\"classpath:org/argeo/slc/osgi/execution/spring.xml\" /> ");
-               log.error("in osgi.xml.\n\n");
-       }
-
-       public void setExecutionContext(ExecutionContext executionContext) {
-               // do nothing, just for compatibility
-       }
-
-       /*
-        * private BundleContext bundleContext;
-        * 
-        * @Override public void execute(ExecutionFlowDescriptor
-        * executionFlowDescriptor) { if (descriptorConverter != null)
-        * executionContext.addVariables(descriptorConverter
-        * .convertValues(executionFlowDescriptor));
-        * 
-        * ExecutionFlow flow = findExecutionFlow(getName(), getVersion(),
-        * executionFlowDescriptor.getName()); flow.run(); }
-        * 
-        * @Override protected Map<String, ExecutionFlow> listFlows() { String
-        * filter = "(org.argeo.slc.execution.module.name=" + getName() + ")";
-        * ServiceReference[] sfs; try { sfs =
-        * bundleContext.getServiceReferences(ExecutionFlow.class .getName(),
-        * filter); } catch (InvalidSyntaxException e) { throw new SlcException(
-        * "Cannot retrieve service reference for flow " + filter, e); }
-        * 
-        * Map<String, ExecutionFlow> flows = new HashMap<String, ExecutionFlow>();
-        * for (ServiceReference sf : sfs) { ExecutionFlow flow = (ExecutionFlow)
-        * bundleContext.getService(sf); flows.put(flow.getName(), flow); } return
-        * flows; }
-        * 
-        * public String getName() { return
-        * bundleContext.getBundle().getSymbolicName(); }
-        * 
-        * public String getVersion() { return
-        * bundleContext.getBundle().getHeaders().get("Bundle-Version") .toString();
-        * }
-        * 
-        * public void setBundleContext(BundleContext bundleContext) {
-        * this.bundleContext = bundleContext; }
-        * 
-        * protected ExecutionFlow findExecutionFlow(String moduleName, String
-        * moduleVersion, String flowName) { String filter =
-        * "(&(org.argeo.slc.execution.module.name=" + moduleName +
-        * ")(org.argeo.slc.execution.flow.name=" + flowName + "))";
-        * log.debug("OSGi filter: " + filter);
-        * 
-        * Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter");
-        * ServiceReference[] sfs; try { sfs =
-        * bundleContext.getServiceReferences(ExecutionFlow.class .getName(),
-        * filter); } catch (InvalidSyntaxException e) { throw new
-        * SlcException("Cannot retrieve service reference for " + filter, e); }
-        * 
-        * if (sfs == null || sfs.length == 0) throw new
-        * SlcException("No execution flow found for " + filter); else if
-        * (sfs.length > 1) throw new
-        * SlcException("More than one execution flow found for " + filter); return
-        * (ExecutionFlow) bundleContext.getService(sfs[0]); }
-        */
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionModulesManager.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionModulesManager.java
deleted file mode 100644 (file)
index 046cfb6..0000000
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi;
-
-import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.management.StandardMBean;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.DefaultNameVersion;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.core.execution.AbstractExecutionModulesManager;
-import org.argeo.slc.core.execution.DefaultExecutionFlowDescriptorConverter;
-import org.argeo.slc.deploy.Module;
-import org.argeo.slc.deploy.ModuleDescriptor;
-import org.argeo.slc.execution.ExecutionContext;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionFlowDescriptor;
-import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
-import org.argeo.slc.execution.ExecutionModuleDescriptor;
-import org.argeo.slc.execution.ExecutionModulesListener;
-import org.argeo.slc.execution.RealizedFlow;
-import org.eclipse.gemini.blueprint.service.importer.OsgiServiceLifecycleListener;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.BundleListener;
-import org.osgi.framework.Constants;
-import org.osgi.framework.launch.Framework;
-import org.springframework.context.ApplicationContext;
-
-/** Execution modules manager implementation based on an OSGi runtime. */
-public class OsgiExecutionModulesManager extends
-               AbstractExecutionModulesManager implements
-               OsgiServiceLifecycleListener, BundleListener {
-
-       private final static Log log = LogFactory
-                       .getLog(OsgiExecutionModulesManager.class);
-
-       private BundlesManager bundlesManager;
-       private Map<OsgiBundle, ExecutionContext> executionContexts = new HashMap<OsgiBundle, ExecutionContext>();
-       private Map<OsgiBundle, ExecutionFlowDescriptorConverter> executionFlowDescriptorConverters = new HashMap<OsgiBundle, ExecutionFlowDescriptorConverter>();
-       private Map<OsgiBundle, Set<ExecutionFlow>> executionFlows = new HashMap<OsgiBundle, Set<ExecutionFlow>>();
-       private ExecutionFlowDescriptorConverter defaultDescriptorConverter = new DefaultExecutionFlowDescriptorConverter();
-
-       private List<ExecutionModulesListener> executionModulesListeners = new ArrayList<ExecutionModulesListener>();
-
-       private Boolean registerFlowsToJmx = false;
-
-       public void init() throws Exception {
-               bundlesManager.getBundleContext().addBundleListener(this);
-
-               final String module = System.getProperty(UNIQUE_LAUNCH_MODULE_PROPERTY);
-               final String flow = System.getProperty(UNIQUE_LAUNCH_FLOW_PROPERTY);
-               if (module != null) {
-                       // launch a flow and stops
-                       new Thread("Unique Flow") {
-                               @Override
-                               public void run() {
-                                       executeFlowAndExit(module, null, flow);
-                               }
-                       }.start();
-               }
-       }
-
-       public void destroy() {
-               bundlesManager.getBundleContext().removeBundleListener(this);
-       }
-
-       /** Executes a single flow and <b>stops the JVM</b> */
-       protected void executeFlowAndExit(final String module,
-                       final String version, final String flow) {
-               if (log.isDebugEnabled())
-                       log.debug("Launch unique flow " + flow + " from module " + module);
-               try {
-                       OsgiBundle osgiBundle = bundlesManager.findFromPattern(module);
-                       if (osgiBundle == null)
-                               throw new SlcException("No OSGi bundle found for " + module);
-                       // Bundle moduleBundle =
-                       // bundlesManager.findRelatedBundle(osgiBundle);
-                       start(osgiBundle);
-
-                       RealizedFlow lastLaunch = findRealizedFlow(module, flow);
-                       if (lastLaunch == null)
-                               throw new SlcException("Cannot find launch for " + module + " "
-                                               + flow);
-                       execute(lastLaunch);
-               } catch (Exception e) {
-                       log.error(
-                                       "Error in unique flow " + flow + " from module " + module,
-                                       e);
-               } finally {
-                       if (log.isDebugEnabled())
-                               log.debug("Shutdown OSGi runtime...");
-                       Framework framework = (Framework) bundlesManager.getBundleContext()
-                                       .getBundle(0);
-                       try {
-                               // shutdown framework
-                               framework.stop();
-                               // wait 1 min for shutdown
-                               framework.waitForStop(60 * 1000);
-                               // close VM
-                               System.exit(0);
-                       } catch (Exception e) {
-                               e.printStackTrace();
-                               System.exit(1);
-                       }
-               }
-       }
-
-       // public void startExectionModule(String moduleName, String moduleVersion)
-       // {
-       // try {
-       // ServiceReference[] sr = bundlesManager.getServiceRefSynchronous(
-       // ApplicationContext.class.getName(),
-       // "org.springframework.context.service.name=" + moduleName);
-       // // bundlesManager.startSynchronous(moduleBundle);
-       // if (sr == null || sr.length == 0)
-       // throw new SlcException(
-       // "Cannot find execution module application context "
-       // + moduleName);
-       // } catch (InvalidSyntaxException e) {
-       // throw new SlcException("Cannot start exeuction module "
-       // + moduleName, e);
-       // }
-       // }
-
-       public synchronized ExecutionModuleDescriptor getExecutionModuleDescriptor(
-                       String moduleName, String version) {
-               ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
-               OsgiBundle osgiBundle = null;
-               DefaultNameVersion nameVersion = new DefaultNameVersion(moduleName,
-                               version);
-               bundles: for (Iterator<OsgiBundle> iterator = executionContexts
-                               .keySet().iterator(); iterator.hasNext();) {
-                       OsgiBundle ob = iterator.next();
-                       if (nameVersion.getVersion() != null) {
-                               if (ob.equals(nameVersion)) {
-                                       osgiBundle = ob;
-                                       break bundles;
-                               }
-                       } else {
-                               if (ob.getName().equals(nameVersion.getName())) {
-                                       osgiBundle = ob;
-                                       break bundles;
-                               }
-                       }
-               }
-               if (osgiBundle == null)
-                       throw new SlcException("No execution module registered for "
-                                       + nameVersion);
-               md.setName(osgiBundle.getName());
-               md.setVersion(osgiBundle.getVersion());
-               md.setTitle(osgiBundle.getTitle());
-               md.setDescription(osgiBundle.getDescription());
-
-               ExecutionFlowDescriptorConverter executionFlowDescriptorConverter = getExecutionFlowDescriptorConverter(
-                               moduleName, version);
-               if (executionFlowDescriptorConverter == null)
-                       throw new SlcException("No flow converter found.");
-               executionFlowDescriptorConverter.addFlowsToDescriptor(md,
-                               listFlows(moduleName, version));
-               return md;
-       }
-
-       public synchronized List<ExecutionModuleDescriptor> listExecutionModules() {
-               List<ExecutionModuleDescriptor> descriptors = new ArrayList<ExecutionModuleDescriptor>();
-
-               for (Iterator<OsgiBundle> iterator = executionContexts.keySet()
-                               .iterator(); iterator.hasNext();) {
-                       OsgiBundle osgiBundle = iterator.next();
-                       ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
-                       setMetadataFromBundle(md,
-                                       bundlesManager.findRelatedBundle(osgiBundle));
-                       descriptors.add(md);
-               }
-               return descriptors;
-       }
-
-       protected synchronized Map<String, ExecutionFlow> listFlows(
-                       String moduleName, String moduleVersion) {
-
-               Map<String, ExecutionFlow> flows = new HashMap<String, ExecutionFlow>();
-               OsgiBundle key = bundlesManager.findRelatedBundle(moduleName,
-                               moduleVersion);
-               if (!executionFlows.containsKey(key))
-                       return flows;
-               Set<ExecutionFlow> flowsT = executionFlows.get(key);
-               for (ExecutionFlow flow : flowsT)
-                       flows.put(flow.getName(), flow);
-               return flows;
-       }
-
-       protected ExecutionFlow findExecutionFlow(String moduleName,
-                       String moduleVersion, String flowName) {
-               String filter = moduleVersion == null || moduleVersion.equals("0.0.0") ? "(&(Bundle-SymbolicName="
-                               + moduleName
-                               + ")(org.eclipse.gemini.blueprint.bean.name="
-                               + flowName + "))"
-                               : "(&(Bundle-SymbolicName=" + moduleName + ")(Bundle-Version="
-                                               + moduleVersion
-                                               + ")(org.eclipse.gemini.blueprint.bean.name="
-                                               + flowName + "))";
-               return bundlesManager.getSingleServiceStrict(ExecutionFlow.class,
-                               filter, true);
-       }
-
-       protected ExecutionContext findExecutionContext(String moduleName,
-                       String moduleVersion) {
-               String filter = moduleFilter(moduleName, moduleVersion);
-               return bundlesManager.getSingleServiceStrict(ExecutionContext.class,
-                               filter, true);
-       }
-
-       protected ExecutionFlowDescriptorConverter findExecutionFlowDescriptorConverter(
-                       String moduleName, String moduleVersion) {
-               String filter = moduleFilter(moduleName, moduleVersion);
-               return bundlesManager.getSingleService(
-                               ExecutionFlowDescriptorConverter.class, filter, false);
-       }
-
-       /** Only based on symbolic name if version is null or "0.0.0" */
-       protected String moduleFilter(String moduleName, String moduleVersion) {
-               return moduleVersion == null || moduleVersion.equals("0.0.0") ? "(Bundle-SymbolicName="
-                               + moduleName + ")"
-                               : "(&(Bundle-SymbolicName=" + moduleName + ")(Bundle-Version="
-                                               + moduleVersion + "))";
-
-       }
-
-       /**
-        * Builds a minimal realized flow, based on the provided information
-        * (typically from the command line).
-        * 
-        * @param module
-        *            a bundle id, or a pattern contained in a bundle symbolic name
-        * @param module
-        *            the execution flow name
-        * @return a minimal realized flow, to be used in an execution
-        */
-       public RealizedFlow findRealizedFlow(String module, String executionName) {
-               // First check whether we have a bundleId
-               Long bundleId = null;
-               try {
-                       bundleId = Long.parseLong(module);
-               } catch (NumberFormatException e) {
-                       // silent
-               }
-
-               // Look for bundle names containing pattern
-               OsgiBundle bundle = null;
-               if (bundleId != null) {
-                       bundle = bundlesManager.getBundle(bundleId);
-               } else {
-                       bundle = bundlesManager.findFromPattern(module);
-               }
-
-               if (bundle != null) {
-                       RealizedFlow launch = new RealizedFlow();
-                       launch.setModuleName(bundle.getName());
-                       launch.setModuleVersion(bundle.getVersion());
-                       ExecutionFlowDescriptor descriptor = new ExecutionFlowDescriptor();
-                       descriptor.setName(executionName);
-                       launch.setFlowDescriptor(descriptor);
-                       return launch;
-               } else {
-                       log.warn("Could not find any execution module matching these requirements.");
-                       return null;
-               }
-       }
-
-       public void upgrade(NameVersion nameVersion) {
-               OsgiBundle osgiBundle = new OsgiBundle(nameVersion);
-               bundlesManager.upgradeSynchronous(osgiBundle);
-       }
-
-       protected synchronized ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
-                       String moduleName, String moduleVersion) {
-               return findExecutionFlowDescriptorConverter(moduleName, moduleVersion);
-               // OsgiBundle osgiBundle = new OsgiBundle(moduleName, moduleVersion);
-               // return getExecutionFlowDescriptorConverter(osgiBundle);
-       }
-
-       protected synchronized ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
-                       OsgiBundle osgiBundle) {
-               if (executionFlowDescriptorConverters.containsKey(osgiBundle))
-                       return executionFlowDescriptorConverters.get(osgiBundle);
-               else
-                       return defaultDescriptorConverter;
-       }
-
-       public ModuleDescriptor getModuleDescriptor(String moduleName,
-                       String version) {
-               return getExecutionModuleDescriptor(moduleName, version);
-       }
-
-       public List<ModuleDescriptor> listModules() {
-               Bundle[] bundles = bundlesManager.getBundleContext().getBundles();
-               List<ModuleDescriptor> lst = new ArrayList<ModuleDescriptor>();
-               for (Bundle bundle : bundles) {
-                       ModuleDescriptor moduleDescriptor = new ModuleDescriptor();
-                       setMetadataFromBundle(moduleDescriptor, bundle);
-                       lst.add(moduleDescriptor);
-               }
-               return lst;
-       }
-
-       public void start(NameVersion nameVersion) {
-               try {
-                       Bundle bundle = bundlesManager.findRelatedBundle(new OsgiBundle(
-                                       nameVersion));
-                       if (bundle == null)
-                               throw new SlcException("Could not find bundle for "
-                                               + nameVersion);
-
-                       bundlesManager.startSynchronous(bundle);
-                       if (isSpringInstrumented(bundle)) {
-                               // Wait for Spring application context to be ready
-                               String filter = "(Bundle-SymbolicName="
-                                               + bundle.getSymbolicName() + ")";
-                               try {
-                                       bundlesManager.getServiceRefSynchronous(
-                                                       ApplicationContext.class, filter);
-                               } catch (Exception e) {
-                                       // stop if application context not found
-                                       bundle.stop();
-                                       throw e;
-                               }
-                       }
-               } catch (Exception e) {
-                       throw new SlcException("Cannot start " + nameVersion, e);
-               }
-       }
-
-       /** Do it calmly in order to avoid NPE */
-       private Boolean isSpringInstrumented(Bundle bundle) {
-               Dictionary<?, ?> headers = bundle.getHeaders();
-               if (headers != null && headers.get("Spring-Context") != null)
-                       return true;
-               Enumeration<?> springEntryPaths = bundle
-                               .getEntryPaths("/META-INF/spring");
-               if (springEntryPaths != null && springEntryPaths.hasMoreElements())
-                       return true;
-               return false;
-       }
-
-       public void stop(NameVersion nameVersion) {
-               try {
-                       Bundle bundle = bundlesManager.findRelatedBundle(new OsgiBundle(
-                                       nameVersion));
-                       bundlesManager.stopSynchronous(bundle);
-               } catch (BundleException e) {
-                       throw new SlcException("Cannot stop " + nameVersion, e);
-               }
-       }
-
-       protected void setMetadataFromBundle(ModuleDescriptor md, Bundle bundle) {
-               Bundle bdl = bundle;
-               if (bdl == null) {
-                       if (md.getName() == null || md.getVersion() == null)
-                               throw new SlcException("Name and version not available.");
-
-                       Bundle[] bundles = bundlesManager.getBundleContext().getBundles();
-                       for (Bundle b : bundles) {
-                               if (b.getSymbolicName().equals(md.getName())
-                                               && md.getVersion().equals(
-                                                               getHeaderSafe(b, Constants.BUNDLE_VERSION))) {
-                                       bdl = b;
-                                       break;
-                               }
-                       }
-
-               }
-
-               if (bdl == null)
-                       throw new SlcException("Cannot find bundle.");
-
-               md.setName(bdl.getSymbolicName());
-               md.setVersion(getHeaderSafe(bdl, Constants.BUNDLE_VERSION));
-               md.setTitle(getHeaderSafe(bdl, Constants.BUNDLE_NAME));
-               md.setDescription(getHeaderSafe(bdl, Constants.BUNDLE_DESCRIPTION));
-
-               // copy manifets header to meta data
-               Dictionary<?, ?> headers = bundle.getHeaders();
-               Enumeration<?> keys = headers.keys();
-               while (keys.hasMoreElements()) {
-                       Object key = keys.nextElement();
-                       Object value = headers.get(key);
-                       if (value != null)
-                               md.getMetadata().put(key.toString(), value.toString());
-               }
-
-               // check if started
-               if (bundle.getState() == Bundle.ACTIVE
-                               || bundle.getState() == Bundle.STARTING)
-                       md.setStarted(true);
-               else
-                       md.setStarted(false);
-       }
-
-       private String getHeaderSafe(Bundle bundle, Object key) {
-               Object obj = bundle.getHeaders().get(key);
-               if (obj == null)
-                       return null;
-               else
-                       return obj.toString();
-       }
-
-       /*
-        * REGISTRATION
-        */
-
-       /** Registers an execution context. */
-       public synchronized void register(ExecutionContext executionContext,
-                       Map<String, String> properties) {
-               OsgiBundle osgiBundle = asOsgiBundle(properties);
-               Bundle bundle = bundlesManager.findRelatedBundle(osgiBundle);
-               osgiBundle.setTitle(getHeaderSafe(bundle, Constants.BUNDLE_NAME));
-               osgiBundle.setDescription(getHeaderSafe(bundle,
-                               Constants.BUNDLE_DESCRIPTION));
-               executionContexts.put(osgiBundle, executionContext);
-               if (log.isTraceEnabled())
-                       log.trace("Registered execution context from " + osgiBundle);
-               // Notify
-               ModuleDescriptor md = osgiBundle.getModuleDescriptor();
-               md.setStarted(true);
-               for (ExecutionModulesListener listener : executionModulesListeners)
-                       listener.executionModuleAdded(md);
-       }
-
-       /** Unregisters an execution context. */
-       public synchronized void unregister(ExecutionContext executionContext,
-                       Map<String, String> properties) {
-               // FIXME why are properties null?
-               if (properties == null)
-                       return;
-               OsgiBundle osgiBundle = asOsgiBundle(properties);
-               if (executionContexts.containsKey(osgiBundle)) {
-                       executionContexts.remove(osgiBundle);
-                       if (log.isTraceEnabled())
-                               log.trace("Removed execution context from " + osgiBundle);
-                       // Notify
-                       ModuleDescriptor md = osgiBundle.getModuleDescriptor();
-                       md.setStarted(false);
-                       for (ExecutionModulesListener listener : executionModulesListeners)
-                               listener.executionModuleRemoved(md);
-               }
-       }
-
-       /** Registers an execution flow. */
-       public synchronized void register(ExecutionFlow executionFlow,
-                       Map<String, String> properties) {
-               OsgiBundle osgiBundle = asOsgiBundle(properties);
-               if (!executionFlows.containsKey(osgiBundle)) {
-                       executionFlows.put(osgiBundle, new HashSet<ExecutionFlow>());
-               }
-               executionFlows.get(osgiBundle).add(executionFlow);
-               if (log.isTraceEnabled())
-                       log.trace("Registered " + executionFlow + " from " + osgiBundle);
-
-               // notifications
-               if (registerFlowsToJmx)
-                       registerMBean(osgiBundle, executionFlow);
-               ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle);
-               for (ExecutionModulesListener listener : executionModulesListeners)
-                       listener.executionFlowAdded(osgiBundle.getModuleDescriptor(),
-                                       efdc.getExecutionFlowDescriptor(executionFlow));
-       }
-
-       /** Unregisters an execution flow. */
-       public synchronized void unregister(ExecutionFlow executionFlow,
-                       Map<String, String> properties) {
-               // FIXME why are properties null?
-               if (properties == null)
-                       return;
-               OsgiBundle osgiBundle = asOsgiBundle(properties);
-               if (executionFlows.containsKey(osgiBundle)) {
-                       Set<ExecutionFlow> flows = executionFlows.get(osgiBundle);
-                       flows.remove(executionFlow);
-                       if (log.isTraceEnabled())
-                               log.trace("Removed " + executionFlow + " from " + osgiBundle);
-                       if (flows.size() == 0) {
-                               executionFlows.remove(osgiBundle);
-                               if (log.isTraceEnabled())
-                                       log.trace("Removed flows set from " + osgiBundle);
-                       }
-
-                       // notifications
-                       if (registerFlowsToJmx)
-                               unregisterMBean(osgiBundle, executionFlow);
-                       ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle);
-                       for (ExecutionModulesListener listener : executionModulesListeners)
-                               listener.executionFlowRemoved(osgiBundle.getModuleDescriptor(),
-                                               efdc.getExecutionFlowDescriptor(executionFlow));
-               }
-       }
-
-       /** Registers an execution module listener. */
-       public synchronized void register(
-                       ExecutionModulesListener executionModulesListener,
-                       Map<String, String> properties) {
-               // sync with current state
-               for (OsgiBundle osgiBundle : executionContexts.keySet()) {
-                       executionModulesListener.executionModuleAdded(osgiBundle
-                                       .getModuleDescriptor());
-               }
-               for (OsgiBundle osgiBundle : executionFlows.keySet()) {
-                       ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle);
-                       for (ExecutionFlow executionFlow : executionFlows.get(osgiBundle))
-                               executionModulesListener.executionFlowAdded(
-                                               osgiBundle.getModuleDescriptor(),
-                                               efdc.getExecutionFlowDescriptor(executionFlow));
-               }
-               executionModulesListeners.add(executionModulesListener);
-       }
-
-       /** Unregisters an execution module listener. */
-       public synchronized void unregister(
-                       ExecutionModulesListener executionModulesListener,
-                       Map<String, String> properties) {
-               executionModulesListeners.remove(executionModulesListener);
-       }
-
-       /*
-        * INTERFACE IMPLEMENTATIONS
-        */
-
-       public void bundleChanged(BundleEvent evt) {
-               Bundle bundle = evt.getBundle();
-               if (bundle.getHeaders().get(
-                               ExecutionModuleDescriptor.SLC_EXECUTION_MODULE) != null) {
-                       OsgiBundle osgiBundle = new OsgiBundle(bundle);
-                       if (evt.getType() == BundleEvent.INSTALLED)
-                               for (ExecutionModulesListener listener : executionModulesListeners)
-                                       listener.executionModuleAdded(osgiBundle
-                                                       .getModuleDescriptor());
-                       else if (evt.getType() == BundleEvent.UNINSTALLED)
-                               for (ExecutionModulesListener listener : executionModulesListeners)
-                                       listener.executionModuleRemoved(osgiBundle
-                                                       .getModuleDescriptor());
-               }
-
-       }
-
-       @SuppressWarnings({ "rawtypes" })
-       public synchronized void bind(Object service, Map properties)
-                       throws Exception {
-               if (service instanceof ExecutionFlowDescriptorConverter) {
-                       ExecutionFlowDescriptorConverter executionFlowDescriptorConverter = (ExecutionFlowDescriptorConverter) service;
-                       OsgiBundle osgiBundle = asOsgiBundle(properties);
-                       executionFlowDescriptorConverters.put(osgiBundle,
-                                       executionFlowDescriptorConverter);
-                       if (log.isTraceEnabled())
-                               log.debug("Registered execution flow descriptor converter from "
-                                               + osgiBundle);
-               } else {
-                       // ignore
-               }
-       }
-
-       @SuppressWarnings("rawtypes")
-       public synchronized void unbind(Object service, Map properties)
-                       throws Exception {
-               if (service instanceof ExecutionFlowDescriptorConverter) {
-                       OsgiBundle osgiBundle = asOsgiBundle(properties);
-                       if (executionFlowDescriptorConverters.containsKey(osgiBundle)) {
-                               executionFlowDescriptorConverters.remove(osgiBundle);
-                               if (log.isTraceEnabled())
-                                       log.debug("Removed execution flow descriptor converter from "
-                                                       + osgiBundle);
-                       }
-               } else {
-                       // ignore
-               }
-       }
-
-       /*
-        * JMX
-        */
-       protected MBeanServer getMBeanServer() {
-               return ManagementFactory.getPlatformMBeanServer();
-       }
-
-       public void registerMBean(Module module, ExecutionFlow executionFlow) {
-               try {
-                       StandardMBean mbean = new StandardMBean(executionFlow,
-                                       ExecutionFlow.class);
-                       getMBeanServer().registerMBean(mbean,
-                                       flowMBeanName(module, executionFlow));
-               } catch (Exception e) {
-                       String msg = "Cannot register execution flow " + executionFlow
-                                       + " as mbean";
-                       throw new SlcException(msg, e);
-               }
-       }
-
-       public void unregisterMBean(Module module, ExecutionFlow executionFlow) {
-               try {
-                       getMBeanServer().unregisterMBean(
-                                       flowMBeanName(module, executionFlow));
-               } catch (Exception e) {
-                       String msg = "Cannot unregister execution flow " + executionFlow
-                                       + " as mbean";
-                       throw new SlcException(msg, e);
-               }
-       }
-
-       protected ObjectName flowMBeanName(Module module,
-                       ExecutionFlow executionFlow) {
-               String executionModulesPrefix = "SLCExecutionModules";
-               // String path = executionFlow.getPath();
-               String name = executionFlow.getName();
-               // if (path == null && name.indexOf('/') >= 0) {
-               // path = name.substring(0, name.lastIndexOf('/'));
-               // name = name.substring(name.lastIndexOf('/'));
-               // }
-
-               StringBuffer buf = new StringBuffer(executionModulesPrefix + ":"
-                               + "module=" + module.getName() + " [" + module.getVersion()
-                               + "],");
-
-               // if (path != null && !path.equals("")) {
-               // int depth = 0;
-               // for (String token : path.split("/")) {
-               // if (!token.equals("")) {
-               // buf.append("path").append(depth).append('=');
-               // // in order to have directories first
-               // buf.append('/');
-               // buf.append(token).append(',');
-               // depth++;
-               // }
-               // }
-               // }
-               buf.append("name=").append(name);
-               try {
-                       return new ObjectName(buf.toString());
-               } catch (Exception e) {
-                       throw new SlcException("Cannot generate object name based on "
-                                       + buf, e);
-               }
-       }
-
-       /*
-        * UTILITIES
-        */
-       @SuppressWarnings("rawtypes")
-       private OsgiBundle asOsgiBundle(Map properties) {
-               String bundleSymbolicName = checkAndGet(Constants.BUNDLE_SYMBOLICNAME,
-                               properties);
-               String bundleVersion = checkAndGet(Constants.BUNDLE_VERSION, properties);
-               return new OsgiBundle(bundleSymbolicName, bundleVersion);
-       }
-
-       @SuppressWarnings("rawtypes")
-       private String checkAndGet(Object key, Map properties) {
-               if (!properties.containsKey(key) || properties.get(key) == null)
-                       throw new SlcException(key + " not set in " + properties);
-               else
-                       return properties.get(key).toString();
-       }
-
-       public void setBundlesManager(BundlesManager bundlesManager) {
-               this.bundlesManager = bundlesManager;
-       }
-
-       public void setDefaultDescriptorConverter(
-                       ExecutionFlowDescriptorConverter defaultDescriptorConverter) {
-               this.defaultDescriptorConverter = defaultDescriptorConverter;
-       }
-
-       public void setRegisterFlowsToJmx(Boolean registerFlowsToJmx) {
-               this.registerFlowsToJmx = registerFlowsToJmx;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionResources.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionResources.java
deleted file mode 100644 (file)
index 306ad07..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-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.eclipse.gemini.blueprint.context.BundleContextAware;
-import org.eclipse.gemini.blueprint.io.OsgiBundleResource;
-import org.osgi.framework.BundleContext;
-import org.springframework.core.io.Resource;
-
-/** Write access to resources in an OSGi context */
-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());
-                       // log.debug(framework);
-                       String installArea = System.getProperty("osgi.install.area")
-                                       .substring("file:".length());
-                       // log.debug(installArea);
-                       base = installArea + '/' + relPath;
-                       // 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 (!file.exists())
-                       throw new SlcException(file
-                                       + " was retrieved in bundle located at '" + location
-                                       + "' for resource " + resource + " but it does not exist");
-
-               if (log.isTraceEnabled())
-                       log.debug("OSGi local resource: " + file + " from " + resource);
-               return file;
-       }
-
-       public void setBundleContext(BundleContext bundleContext) {
-               this.bundleContext = bundleContext;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiRuntime.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiRuntime.java
deleted file mode 100644 (file)
index 8286ecc..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.StreamReadable;
-import org.argeo.slc.UnsupportedException;
-import org.argeo.slc.build.Distribution;
-import org.argeo.slc.core.build.VersionedResourceDistribution;
-import org.argeo.slc.deploy.DeploymentData;
-import org.argeo.slc.deploy.DynamicRuntime;
-import org.argeo.slc.deploy.TargetData;
-import org.eclipse.gemini.blueprint.context.BundleContextAware;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.springframework.context.ResourceLoaderAware;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.ResourceLoader;
-
-public class OsgiRuntime implements BundleContextAware, ResourceLoaderAware,
-               DynamicRuntime<OsgiBundle> {
-       private String uuid = UUID.randomUUID().toString();
-       private BundleContext bundleContext;
-       private ResourceLoader resourceLoader;
-
-       public List<OsgiBundle> listModules() {
-               List<OsgiBundle> modules = new ArrayList<OsgiBundle>();
-               Bundle[] bundles = bundleContext.getBundles();
-               for (Bundle bundle : bundles) {
-                       OsgiBundle osgiBundle = new OsgiBundle(bundle);
-                       modules.add(osgiBundle);
-                       String location = bundle.getLocation();
-                       if (location != null) {
-                               Resource resource = resourceLoader.getResource(location);
-                               osgiBundle
-                                               .setResourceDistribution(new VersionedResourceDistribution(
-                                                               osgiBundle.getName(), osgiBundle.getVersion(),
-                                                               resource));
-                       }
-               }
-               return modules;
-       }
-
-       public OsgiBundle installModule(Distribution distribution) {
-               if (!(distribution instanceof StreamReadable))
-                       throw new UnsupportedException("distribution", distribution);
-
-               StreamReadable sr = (StreamReadable) distribution;
-               Bundle bundle;
-               try {
-                       bundle = bundleContext.installBundle(sr.toString(), sr
-                                       .getInputStream());
-               } catch (BundleException e) {
-                       throw new SlcException(
-                                       "Cannot install OSGi bundle " + distribution, e);
-               }
-               return new OsgiBundle(bundle);
-       }
-
-       public void updateModule(NameVersion nameVersion) {
-               Bundle bundle = findBundle(nameVersion);
-               try {
-                       bundle.update();
-               } catch (BundleException e) {
-                       throw new SlcException("Cannot update " + bundle, e);
-               }
-       }
-
-       public void uninstallModule(NameVersion nameVersion) {
-               Bundle bundle = findBundle(nameVersion);
-               try {
-                       bundle.uninstall();
-               } catch (BundleException e) {
-                       throw new SlcException("Cannot uninstall " + bundle, e);
-               }
-       }
-
-       public void startModule(NameVersion nameVersion) {
-               Bundle bundle = findBundle(nameVersion);
-               try {
-                       bundle.start();
-                       // TODO: use bundle manager
-               } catch (BundleException e) {
-                       throw new SlcException("Cannot uninstall " + bundle, e);
-               }
-       }
-
-       protected Bundle findBundle(NameVersion nameVersion) {
-               Bundle[] bundles = bundleContext.getBundles();
-               for (Bundle bundle : bundles) {
-                       OsgiBundle osgiBundle = new OsgiBundle(bundle);
-                       if (osgiBundle.equals(nameVersion)) {
-                               return bundle;
-                       }
-               }
-               throw new SlcException("Could not find bundle " + nameVersion);
-       }
-
-       public void shutdown() {
-               // FIXME use framework
-               throw new UnsupportedException();
-       }
-
-       public String getDeployedSystemId() {
-               return uuid;
-       }
-
-       public DeploymentData getDeploymentData() {
-               throw new UnsupportedException();
-       }
-
-       public Distribution getDistribution() {
-               throw new UnsupportedException();
-       }
-
-       public TargetData getTargetData() {
-               throw new UnsupportedException();
-       }
-
-       public void setBundleContext(BundleContext bundleContext) {
-               this.bundleContext = bundleContext;
-       }
-
-       public void setResourceLoader(ResourceLoader resourceLoader) {
-               this.resourceLoader = resourceLoader;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/build/AbstractOsgiModularDistribution.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/build/AbstractOsgiModularDistribution.java
deleted file mode 100644 (file)
index c76659f..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi.build;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.DefaultNameVersion;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.UnsupportedException;
-import org.argeo.slc.build.Distribution;
-import org.argeo.slc.build.ModularDistribution;
-import org.eclipse.gemini.blueprint.context.BundleContextAware;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.springframework.beans.factory.InitializingBean;
-
-public abstract class AbstractOsgiModularDistribution implements
-               ModularDistribution, BundleContextAware, InitializingBean {
-       private final static Log log = LogFactory
-                       .getLog(AbstractOsgiModularDistribution.class);
-
-       private BundleContext bundleContext;
-       private EclipseUpdateSite eclipseUpdateSite;
-
-       /** Initialized by the object itself. */
-       private SortedMap<NameVersion, Distribution> distributions = new TreeMap<NameVersion, Distribution>();
-
-       protected abstract void fillDistributions(
-                       SortedMap<NameVersion, Distribution> distributions)
-                       throws Exception;
-
-       public Distribution getModuleDistribution(String moduleName,
-                       String moduleVersion) {
-               return distributions.get(new DefaultNameVersion(moduleName,
-                               moduleVersion));
-       }
-
-       public String getDistributionId() {
-               return bundleContext.getBundle().getSymbolicName()
-                               + "-"
-                               + bundleContext.getBundle().getHeaders()
-                                               .get(Constants.BUNDLE_VERSION);
-       }
-
-       public Set<NameVersion> listModulesNameVersions() {
-               return distributions.keySet();
-       }
-
-       public Iterator<NameVersion> nameVersions() {
-               return distributions.keySet().iterator();
-       }
-
-       public void setBundleContext(BundleContext bundleContext) {
-               this.bundleContext = bundleContext;
-       }
-
-       public void afterPropertiesSet() throws Exception {
-               fillDistributions(distributions);
-               if (log.isDebugEnabled())
-                       log.debug("Distribution " + getName() + ":" + getVersion()
-                                       + " loaded (" + distributions.size() + " modules)");
-       }
-
-       protected String findVersion(String name) {
-               Set<String> versions = new HashSet<String>();
-               for (NameVersion key : distributions.keySet()) {
-                       if (key.getName().equals(name))
-                               versions.add(key.getVersion());
-               }
-
-               if (versions.size() == 0)
-                       throw new SlcException("Cannot find version for name " + name);
-               else if (versions.size() > 1)
-                       throw new SlcException("Found more than one version for name "
-                                       + name + ": " + versions);
-               else
-                       return versions.iterator().next();
-
-       }
-
-       public Object getModulesDescriptor(String descriptorType) {
-               if (descriptorType.equals("eclipse"))
-                       return writeEclipseUpdateSite();
-               else
-                       throw new UnsupportedException("descriptorType", descriptorType);
-       }
-
-       protected Set<NameVersion> writePlainUrlList() {
-               return distributions.keySet();
-       }
-
-       protected String writeEclipseUpdateSite() {
-               if (eclipseUpdateSite == null)
-                       throw new SlcException("No eclipse update site declared.");
-
-               StringBuffer buf = new StringBuffer("");
-               buf.append("<site>");
-
-               List<EclipseUpdateSiteCategory> usedCategories = new ArrayList<EclipseUpdateSiteCategory>();
-               for (EclipseUpdateSiteFeature feature : eclipseUpdateSite.getFeatures()) {
-
-                       String featureId = feature.getName();
-                       String featureVersion = findVersion(featureId);
-                       buf.append("<feature");
-                       buf.append(" url=\"features/").append(featureId).append('_')
-                                       .append(featureVersion).append(".jar\"");
-                       buf.append(" id=\"").append(featureId).append("\"");
-                       buf.append(" version=\"").append(featureVersion).append("\"");
-                       buf.append(">\n");
-
-                       for (EclipseUpdateSiteCategory category : feature.getCategories()) {
-                               usedCategories.add(category);
-                               buf.append("  <category name=\"").append(category.getName())
-                                               .append("\"/>\n");
-                       }
-                       buf.append("</feature>\n\n");
-               }
-
-               for (EclipseUpdateSiteCategory category : usedCategories) {
-                       buf.append("<category-def");
-                       buf.append(" name=\"").append(category.getName()).append("\"");
-                       buf.append(" label=\"").append(category.getLabel()).append("\"");
-                       buf.append(">\n");
-                       buf.append("  <description>").append(category.getDescription())
-                                       .append("</description>\n");
-                       buf.append("</category-def>\n\n");
-               }
-
-               buf.append("</site>");
-               return buf.toString();
-       }
-
-       public String getName() {
-               return bundleContext.getBundle().getSymbolicName();
-       }
-
-       public String getVersion() {
-               return bundleContext.getBundle().getHeaders()
-                               .get(Constants.BUNDLE_VERSION).toString();
-       }
-
-       @Override
-       public String toString() {
-               return new DefaultNameVersion(this).toString();
-       }
-
-       public void setEclipseUpdateSite(EclipseUpdateSite eclipseUpdateSite) {
-               this.eclipseUpdateSite = eclipseUpdateSite;
-       }
-
-       public BundleContext getBundleContext() {
-               return bundleContext;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/build/BundleModularDistribution.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/build/BundleModularDistribution.java
deleted file mode 100644 (file)
index db7c7e8..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi.build;
-
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.SortedMap;
-import java.util.StringTokenizer;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.slc.DefaultNameVersion;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.build.Distribution;
-import org.argeo.slc.core.build.VersionedResourceDistribution;
-import org.osgi.framework.Constants;
-import org.springframework.context.ResourceLoaderAware;
-import org.springframework.core.io.ResourceLoader;
-
-public class BundleModularDistribution extends AbstractOsgiModularDistribution
-               implements ResourceLoaderAware {
-       private ResourceLoader resourceLoader;
-
-       private String libDirectory = "/lib";
-
-       protected void fillDistributions(
-                       SortedMap<NameVersion, Distribution> distributions)
-                       throws Exception {
-               Enumeration<URL> urls = (Enumeration<URL>) getBundleContext()
-                               .getBundle().findEntries(libDirectory, "*.jar", false);
-               while (urls.hasMoreElements()) {
-                       URL url = urls.nextElement();
-                       JarInputStream in = null;
-                       try {
-                               in = new JarInputStream(url.openStream());
-                               Manifest mf = in.getManifest();
-                               String name = mf.getMainAttributes().getValue(
-                                               Constants.BUNDLE_SYMBOLICNAME);
-                               // Skip additional specs such as
-                               // ; singleton:=true
-                               if (name.indexOf(';') > -1) {
-                                       name = new StringTokenizer(name, " ;").nextToken();
-                               }
-
-                               String version = mf.getMainAttributes().getValue(
-                                               Constants.BUNDLE_VERSION);
-                               DefaultNameVersion nameVersion = new DefaultNameVersion(name,
-                                               version);
-                               distributions.put(nameVersion,
-                                               new VersionedResourceDistribution(name, version,
-                                                               resourceLoader.getResource(url.toString())));
-                       } finally {
-                               IOUtils.closeQuietly(in);
-                       }
-               }
-       }
-
-       public void setLibDirectory(String libDirectory) {
-               this.libDirectory = libDirectory;
-       }
-
-       public void setResourceLoader(ResourceLoader resourceLoader) {
-               this.resourceLoader = resourceLoader;
-       }
-
-       /*
-        * @SuppressWarnings(value = { "unchecked" }) protected URL
-        * findModule(String moduleName, String version) { Enumeration<URL> urls =
-        * (Enumeration<URL>) bundleContext.getBundle() .findEntries(libDirectory,
-        * moduleName + "*", false);
-        * 
-        * if (!urls.hasMoreElements()) throw new SlcException("Cannot find module "
-        * + moduleName);
-        * 
-        * URL url = urls.nextElement();
-        * 
-        * // TODO: check version as well if (urls.hasMoreElements()) throw new
-        * SlcException("More than one module with name " + moduleName); return url;
-        * }
-        */
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSite.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSite.java
deleted file mode 100644 (file)
index e38d9c0..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi.build;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class EclipseUpdateSite {
-       private List<EclipseUpdateSiteFeature> features = new ArrayList<EclipseUpdateSiteFeature>();
-
-       public List<EclipseUpdateSiteFeature> getFeatures() {
-               return features;
-       }
-
-       public void setFeatures(List<EclipseUpdateSiteFeature> features) {
-               this.features = features;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSiteCategory.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSiteCategory.java
deleted file mode 100644 (file)
index c716562..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi.build;
-
-public class EclipseUpdateSiteCategory {
-       private String name;
-       private String label;
-       private String description;
-
-       public String getLabel() {
-               return label;
-       }
-
-       public void setLabel(String label) {
-               this.label = label;
-       }
-
-       public String getDescription() {
-               return description;
-       }
-
-       public void setDescription(String description) {
-               this.description = description;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSiteFeature.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSiteFeature.java
deleted file mode 100644 (file)
index f28c0cb..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi.build;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class EclipseUpdateSiteFeature {
-       private String name;
-       private List<EclipseUpdateSiteCategory> categories = new ArrayList<EclipseUpdateSiteCategory>();
-
-       public String getName() {
-               return name;
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       public List<EclipseUpdateSiteCategory> getCategories() {
-               return categories;
-       }
-
-       public void setCategories(List<EclipseUpdateSiteCategory> categories) {
-               this.categories = categories;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/build/OsgiRuntimeModularDistribution.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/build/OsgiRuntimeModularDistribution.java
deleted file mode 100644 (file)
index 5523e6e..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi.build;
-
-import java.net.URL;
-import java.util.SortedMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.build.Distribution;
-import org.argeo.slc.core.build.VersionedResourceDistribution;
-import org.argeo.slc.osgi.OsgiBundle;
-import org.eclipse.gemini.blueprint.util.OsgiBundleUtils;
-import org.osgi.framework.Bundle;
-import org.springframework.context.ResourceLoaderAware;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.ResourceLoader;
-
-public class OsgiRuntimeModularDistribution extends
-               AbstractOsgiModularDistribution implements ResourceLoaderAware {
-       private final static Log log = LogFactory
-                       .getLog(OsgiRuntimeModularDistribution.class);
-
-       private ResourceLoader resourceLoader;
-
-       protected void fillDistributions(
-                       SortedMap<NameVersion, Distribution> distributions)
-                       throws Exception {
-
-               String frameworkUrl = System.getProperty("osgi.framework");
-               String frameworkBaseUrl = null;
-               if (frameworkUrl != null)
-                       frameworkBaseUrl = frameworkUrl.substring(0, frameworkUrl
-                                       .lastIndexOf('/'));
-               bundles: for (Bundle bundle : getBundleContext().getBundles()) {
-                       OsgiBundle osgiBundle = new OsgiBundle(bundle);
-
-                       String originalLocation = bundle.getLocation();
-
-                       if (OsgiBundleUtils.isSystemBundle(bundle)) {
-                               continue bundles;
-                       }
-
-                       String location = originalLocation;
-                       if (originalLocation.startsWith("reference:file:"))
-                               location = originalLocation.substring("reference:".length());
-
-                       if (frameworkBaseUrl != null
-                                       && originalLocation.startsWith("initial@reference:file:")) {
-                               location = frameworkBaseUrl
-                                               + '/'
-                                               + originalLocation.substring("initial@reference:file:"
-                                                               .length());
-                       }
-
-                       try {
-                               URL url = new URL(location);
-                               Resource res = resourceLoader.getResource(url.toString());
-                               distributions.put(osgiBundle,
-                                               new VersionedResourceDistribution(osgiBundle, res));
-
-                               if (log.isTraceEnabled())
-                                       log.debug("Added url " + url + " from original location "
-                                                       + originalLocation);
-                       } catch (Exception e) {
-                               log.warn("Cannot interpret location " + location
-                                               + " of bundle " + bundle + ": " + e);
-                       }
-               }
-       }
-
-       public void setResourceLoader(ResourceLoader resourceLoader) {
-               this.resourceLoader = resourceLoader;
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/deploy/OsgiResourceSet.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/deploy/OsgiResourceSet.java
deleted file mode 100644 (file)
index 2414788..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.osgi.deploy;
-
-import org.argeo.slc.core.deploy.DefaultResourceSet;
-import org.eclipse.gemini.blueprint.context.BundleContextAware;
-import org.eclipse.gemini.blueprint.io.OsgiBundleResourceLoader;
-import org.eclipse.gemini.blueprint.io.OsgiBundleResourcePatternResolver;
-import org.eclipse.gemini.blueprint.util.OsgiBundleUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.springframework.core.io.ResourceLoader;
-
-/**
- * Retrieves ressources from an OSGi bundle either the active one or another one
- * referenced by its symbolic name.
- */
-public class OsgiResourceSet extends DefaultResourceSet implements
-               BundleContextAware {
-       private BundleContext bundleContext;
-       private Bundle bundle = null;
-       private String bundleSymbolicName = null;
-
-       private OsgiBundleResourceLoader osgiBundleResourceLoader = null;
-
-       @Override
-       public void afterPropertiesSet() throws Exception {
-               osgiBundleResourceLoader = new OsgiBundleResourceLoader(getBundle());
-               if (getResourcePatternResolver() == null)
-                       setResourcePatternResolver(new OsgiBundleResourcePatternResolver(
-                                       osgiBundleResourceLoader));
-               super.afterPropertiesSet();
-       }
-
-       public Bundle getBundle() {
-               if (bundle != null)
-                       return bundle;
-               else if (bundleSymbolicName != null)// do not cache
-                       return OsgiBundleUtils.findBundleBySymbolicName(bundleContext,
-                                       bundleSymbolicName);
-               else
-                       // containing bundle
-                       return bundleContext.getBundle();
-       }
-
-       public void setBundleContext(BundleContext bundleContext) {
-               this.bundleContext = bundleContext;
-       }
-
-       @Override
-       public ResourceLoader getResourceLoaderToUse() {
-               return osgiBundleResourceLoader;
-       }
-
-       public void setBundle(Bundle bundle) {
-               this.bundle = bundle;
-       }
-
-       public void setBundleSymbolicName(String bundleSymbolicName) {
-               this.bundleSymbolicName = bundleSymbolicName;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/osgi/execution.xml b/org.argeo.slc.core/src/org/argeo/slc/osgi/execution.xml
deleted file mode 100644 (file)
index cc0aac0..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2007-2012 Argeo GmbH Licensed under the Apache License, 
-       Version 2.0 (the "License"); you may not use this file except in compliance 
-       with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
-       Unless required by applicable law or agreed to in writing, software distributed 
-       under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
-       OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
-       the specific language governing permissions and limitations under the License. -->
-<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under 
-       the Apache License, Version 2.0 (the "License"); you may not use this file 
-       except in compliance with the License. You may obtain a copy of the License 
-       at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
-       law or agreed to in writing, software distributed under the License is distributed 
-       on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
-       express or implied. See the License for the specific language governing permissions 
-       and limitations under the License. -->
-
-<beans xmlns:osgi="http://www.springframework.org/schema/osgi"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"
-       xsi:schemaLocation="http://www.springframework.org/schema/osgi  
-       http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd
-       http://www.springframework.org/schema/beans   
-       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
-
-       <osgi:service interface="org.argeo.slc.execution.ExecutionContext"
-               ref="executionContext" />
-       <osgi:service
-               interface="org.argeo.slc.execution.ExecutionFlowDescriptorConverter"
-               ref="executionFlowDescriptorConverter" />
-
-       <osgi:reference id="callbackHandler"
-               interface="javax.security.auth.callback.CallbackHandler" cardinality="0..1" />
-
-       <bean class="org.argeo.slc.osgi.MultipleServiceExporterPostProcessor">
-               <property name="interfaces">
-                       <list>
-                               <value><![CDATA[org.argeo.slc.execution.ExecutionFlow]]></value>
-                       </list>
-               </property>
-               <property name="bundleContext" ref="bundleContext" />
-       </bean>
-
-       <bean id="osgiExecutionResources" class="org.argeo.slc.osgi.OsgiExecutionResources">
-               <property name="executionContext" ref="executionContext" />
-       </bean>
-</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.core/src/org/argeo/slc/spring/AbstractSystemExecution.java b/org.argeo.slc.core/src/org/argeo/slc/spring/AbstractSystemExecution.java
deleted file mode 100644 (file)
index 7813b9a..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.spring;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.node.NodeConstants;
-import org.argeo.slc.SlcException;
-
-/** Provides base method for executing code with system authorization. */
-abstract class AbstractSystemExecution {
-       private final static Log log = LogFactory.getLog(AbstractSystemExecution.class);
-       private final Subject subject = new Subject();
-
-       /** Authenticate the calling thread */
-       protected void authenticateAsSystem() {
-               ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader();
-               Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-               try {
-                       LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN, subject);
-                       lc.login();
-               } catch (LoginException e) {
-                       throw new SlcException("Cannot login as system", e);
-               } finally {
-                       Thread.currentThread().setContextClassLoader(origClassLoader);
-               }
-               if (log.isTraceEnabled())
-                       log.trace("System authenticated");
-       }
-
-       protected void deauthenticateAsSystem() {
-               ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader();
-               Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-               try {
-                       LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN, subject);
-                       lc.logout();
-               } catch (LoginException e) {
-                       throw new SlcException("Cannot logout as system", e);
-               } finally {
-                       Thread.currentThread().setContextClassLoader(origClassLoader);
-               }
-       }
-
-       protected Subject getSubject() {
-               return subject;
-       }
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/spring/AuthenticatedApplicationContextInitialization.java b/org.argeo.slc.core/src/org/argeo/slc/spring/AuthenticatedApplicationContextInitialization.java
deleted file mode 100644 (file)
index 68a9cc9..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.spring;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.security.auth.Subject;
-
-import org.eclipse.gemini.blueprint.context.DependencyInitializationAwareBeanPostProcessor;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.support.AbstractBeanFactory;
-import org.springframework.beans.factory.support.SecurityContextProvider;
-import org.springframework.beans.factory.support.SimpleSecurityContextProvider;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-
-/**
- * Executes with a system authentication the instantiation and initialization
- * methods of the application context where it has been defined.
- */
-public class AuthenticatedApplicationContextInitialization extends
-               AbstractSystemExecution implements
-               DependencyInitializationAwareBeanPostProcessor, ApplicationContextAware {
-       /** If non empty, restricts to these beans */
-       private List<String> beanNames = new ArrayList<String>();
-
-       public Object postProcessBeforeInitialization(Object bean, String beanName)
-                       throws BeansException {
-               if (beanNames.size() == 0 || beanNames.contains(beanName))
-                       authenticateAsSystem();
-               return bean;
-       }
-
-       public Object postProcessAfterInitialization(Object bean, String beanName)
-                       throws BeansException {
-               if (beanNames.size() == 0 || beanNames.contains(beanName))
-                       deauthenticateAsSystem();
-               return bean;
-       }
-
-       public void setBeanNames(List<String> beanNames) {
-               this.beanNames = beanNames;
-       }
-
-       @Override
-       public void setApplicationContext(ApplicationContext applicationContext)
-                       throws BeansException {
-               if (applicationContext.getAutowireCapableBeanFactory() instanceof AbstractBeanFactory) {
-                       final AbstractBeanFactory beanFactory = ((AbstractBeanFactory) applicationContext
-                                       .getAutowireCapableBeanFactory());
-                       // retrieve subject's access control context
-                       // and set it as the bean factory security context
-                       Subject.doAs(getSubject(), new PrivilegedAction<Void>() {
-                               @Override
-                               public Void run() {
-                                       SecurityContextProvider scp = new SimpleSecurityContextProvider(
-                                                       AccessController.getContext());
-                                       beanFactory.setSecurityContextProvider(scp);
-                                       return null;
-                               }
-                       });
-               }
-       }
-}
diff --git a/org.argeo.slc.spring/.classpath b/org.argeo.slc.spring/.classpath
new file mode 100644 (file)
index 0000000..70b08e8
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" output="target/classes" path="src"/>
+       <classpathentry kind="src" path="ext/test"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.argeo.slc.spring/.gitignore b/org.argeo.slc.spring/.gitignore
new file mode 100644 (file)
index 0000000..09e3bc9
--- /dev/null
@@ -0,0 +1,2 @@
+/bin/
+/target/
diff --git a/org.argeo.slc.spring/.project b/org.argeo.slc.spring/.project
new file mode 100644 (file)
index 0000000..c45aff2
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.slc.spring</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+               <nature>org.eclipse.pde.PluginNature</nature>
+       </natures>
+</projectDescription>
diff --git a/org.argeo.slc.spring/META-INF/.gitignore b/org.argeo.slc.spring/META-INF/.gitignore
new file mode 100644 (file)
index 0000000..4854a41
--- /dev/null
@@ -0,0 +1 @@
+/MANIFEST.MF
diff --git a/org.argeo.slc.spring/META-INF/spring.handlers b/org.argeo.slc.spring/META-INF/spring.handlers
new file mode 100644 (file)
index 0000000..417a952
--- /dev/null
@@ -0,0 +1 @@
+http\://www.argeo.org/schema/slc-flow=org.argeo.slc.core.execution.xml.FlowNamespaceHandler
\ No newline at end of file
diff --git a/org.argeo.slc.spring/META-INF/spring.schemas b/org.argeo.slc.spring/META-INF/spring.schemas
new file mode 100644 (file)
index 0000000..229d4c5
--- /dev/null
@@ -0,0 +1,3 @@
+http\://www.argeo.org/schema/slc-flow.xsd=org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd
+http\://www.argeo.org/schema/slc-flow-1.2.xsd=org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd
+http\://www.argeo.org/schema/slc-flow-0.12.xsd=org/argeo/slc/core/execution/xml/slc-flow-0.12.xsd
diff --git a/org.argeo.slc.spring/bnd.bnd b/org.argeo.slc.spring/bnd.bnd
new file mode 100644 (file)
index 0000000..fb76254
--- /dev/null
@@ -0,0 +1,6 @@
+Import-Package: javax.jcr.nodetype,\
+javax.jcr.security,\
+org.apache.tools.ant.*;resolution:="optional",\
+junit.framework;resolution:="optional",\
+org.osgi.*;version=0.0.0,\
+*
diff --git a/org.argeo.slc.spring/build.properties b/org.argeo.slc.spring/build.properties
new file mode 100644 (file)
index 0000000..7abe079
--- /dev/null
@@ -0,0 +1,3 @@
+additional.bundles = org.springframework.context
+bin.includes = META-INF/,.
+source.. = src/
diff --git a/org.argeo.slc.spring/ext/test/log4j.properties b/org.argeo.slc.spring/ext/test/log4j.properties
new file mode 100644 (file)
index 0000000..0133bab
--- /dev/null
@@ -0,0 +1,22 @@
+# Set root logger level to DEBUG and its only appender to A1.\r
+log4j.rootLogger=WARN, console\r
+\r
+## Levels\r
+# Slc\r
+log4j.logger.org.argeo=DEBUG\r
+\r
+# Castor\r
+log4j.logger.org.exolab.castor=WARN\r
+\r
+# Spring\r
+log4j.logger.org.springframework=WARN\r
+\r
+\r
+## Appenders\r
+# A1 is set to be a ConsoleAppender.\r
+log4j.appender.console=org.apache.log4j.ConsoleAppender\r
+\r
+# A1 uses PatternLayout.\r
+log4j.appender.console.layout=org.apache.log4j.PatternLayout\r
+log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n\r
+\r
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/DefaultResourceSetTest.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/DefaultResourceSetTest.java
new file mode 100644 (file)
index 0000000..15fb429
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.core.test.context.AbstractInternalSpringTestCase;
+import org.springframework.core.io.Resource;
+
+public class DefaultResourceSetTest extends AbstractInternalSpringTestCase {
+       private final static Log log = LogFactory
+                       .getLog(DefaultResourceSetTest.class);
+
+       public void testListResources() {
+               DefaultResourceSet rrs = getBean("relativeResourceSet");
+               Map<String, Resource> res = rrs.listResources();
+               for (String relativePath : res.keySet())
+                       log.debug(relativePath + "=" + res.get(relativePath));
+               assertEquals(2, res.size());
+       }
+
+       @Override
+       protected String getApplicationContextLocation() {
+               return inPackage("relativeResourceSet.xml");
+       }
+
+}
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/data/file1.txt b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/data/file1.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/data/subdir/file2.txt b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/data/subdir/file2.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/relativeResourceSet.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/deploy/relativeResourceSet.xml
new file mode 100644 (file)
index 0000000..074c205
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
+\r
+       <bean id="relativeResourceSet" class="org.argeo.slc.core.deploy.DefaultResourceSet">\r
+               <property name="base" value="classpath:/org/argeo/slc/core/deploy/data" />\r
+       </bean>\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/AbstractExecutionFlowTestCase.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/AbstractExecutionFlowTestCase.java
new file mode 100644 (file)
index 0000000..004605c
--- /dev/null
@@ -0,0 +1,83 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution;\r
+\r
+import junit.framework.TestCase;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.core.test.SimpleTestResult;\r
+import org.argeo.slc.execution.ExecutionContext;\r
+import org.argeo.slc.execution.ExecutionFlow;\r
+import org.argeo.slc.test.TestResultPart;\r
+import org.argeo.slc.test.TestStatus;\r
+import org.springframework.context.ConfigurableApplicationContext;\r
+import org.springframework.context.support.ClassPathXmlApplicationContext;\r
+\r
+public abstract class AbstractExecutionFlowTestCase extends TestCase {\r
+\r
+       protected final Log log = LogFactory.getLog(getClass());\r
+\r
+       protected void logException(Throwable ex) {\r
+               log.info("Got Exception of class " + ex.getClass().toString()\r
+                               + " with message '" + ex.getMessage() + "'.");\r
+       }\r
+\r
+       protected void validateTestResult(SimpleTestResult testResult) {\r
+               validateTestResult(testResult, TestStatus.PASSED);\r
+       }\r
+\r
+       protected void validateTestResult(SimpleTestResult testResult,\r
+                       int expectedStatus) {\r
+               for (TestResultPart part : testResult.getParts()) {\r
+                       if (part.getStatus() != expectedStatus) {\r
+                               fail("Error found in TestResult: " + part.getMessage());\r
+                       }\r
+               }\r
+       }\r
+\r
+       protected ConfigurableApplicationContext createApplicationContext(\r
+                       String applicationContextSuffix) {\r
+               ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext(\r
+                               inPackage(applicationContextSuffix));\r
+               // applicationContext.start();\r
+               return applicationContext;\r
+       }\r
+\r
+       protected void configureAndExecuteSlcFlow(String applicationContextSuffix,\r
+                       String beanName) {\r
+               ConfigurableApplicationContext applicationContext = createApplicationContext(applicationContextSuffix);\r
+               ExecutionContext executionContext = (ExecutionContext) applicationContext\r
+                               .getBean("executionContext");\r
+               ExecutionFlow executionFlow = (ExecutionFlow) applicationContext\r
+                               .getBean(beanName);\r
+               if (executionFlow instanceof DefaultExecutionFlow)\r
+                       ((DefaultExecutionFlow) executionFlow)\r
+                                       .setExecutionContext(executionContext);\r
+               try {\r
+                       executionContext.beforeFlow(executionFlow);\r
+                       executionFlow.run();\r
+               } finally {\r
+                       executionContext.afterFlow(executionFlow);\r
+               }\r
+               applicationContext.close();\r
+       }\r
+\r
+       protected String inPackage(String suffix) {\r
+               String prefix = getClass().getPackage().getName().replace('.', '/');\r
+               return prefix + '/' + suffix;\r
+       }\r
+}\r
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/BasicExecutionFlowTest.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/BasicExecutionFlowTest.java
new file mode 100644 (file)
index 0000000..91be3bd
--- /dev/null
@@ -0,0 +1,185 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.argeo.slc.core.test.SimpleTestResult;\r
+import org.argeo.slc.execution.ExecutionContext;\r
+import org.argeo.slc.execution.ExecutionFlow;\r
+import org.argeo.slc.test.TestStatus;\r
+import org.springframework.beans.factory.BeanCreationException;\r
+import org.springframework.context.ConfigurableApplicationContext;\r
+\r
+public class BasicExecutionFlowTest extends AbstractExecutionFlowTestCase {\r
+       // TO TEST\r
+       // - post-processing for @{} replacement in beans with complex properties\r
+       // - bean of scope other than execution are not resolved at execution\r
+\r
+       // public void testMyTest() throws Exception {\r
+       // ConfigurableApplicationContext applicationContext =\r
+       // createApplicationContext("test.xml");\r
+       // log.info("Start Execution");\r
+       // ((ExecutionFlow) applicationContext.getBean("flow1")).execute();\r
+       // applicationContext.close();\r
+       // }\r
+\r
+       public void testSpecOverriding() throws Exception {\r
+               ConfigurableApplicationContext applicationContext = createApplicationContext("specOverriding.xml");\r
+               ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
+               SimpleTestResult res = (SimpleTestResult) applicationContext\r
+                               .getBean("myTestResult");\r
+               validateTestResult(res);\r
+       }\r
+\r
+       public void testMultipleFlows() throws Exception {\r
+               ConfigurableApplicationContext applicationContext = createApplicationContext("multipleFlow.xml");\r
+               ((ExecutionFlow) applicationContext.getBean("flow1")).run();\r
+               SimpleTestResult res = (SimpleTestResult) applicationContext\r
+                               .getBean("myTestResult");\r
+               validateTestResult(res);\r
+               res.getParts().clear();\r
+               ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
+               validateTestResult(res, TestStatus.FAILED);\r
+               applicationContext.close();\r
+       }\r
+\r
+       /**\r
+        * Test placeholder resolution in a context without scope execution or proxy\r
+        * and with cascading flows (the flow A contains the flow B)\r
+        * \r
+        * @throws Exception\r
+        */\r
+       public void testPlaceHolders() throws Exception {\r
+               ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.xml");\r
+               ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
+               validateTestResult((SimpleTestResult) applicationContext\r
+                               .getBean("myTestResult"));\r
+               applicationContext.close();\r
+       }\r
+\r
+       /**\r
+        * Test placeholder resolution in a context without scope execution or proxy\r
+        * and with cascading flows (the flow A contains the flow B) setting\r
+        * execution values (should have no effect)\r
+        * \r
+        * @throws Exception\r
+        */\r
+       public void testPlaceHoldersWithExecutionValues() throws Exception {\r
+               ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.xml");\r
+\r
+               ExecutionContext executionContext = (ExecutionContext) applicationContext\r
+                               .getBean("executionContext");\r
+               Map<String, String> executionParameters = new HashMap<String, String>();\r
+               executionParameters.put("p1", "e1");\r
+               executionParameters.put("p2", "e2");\r
+               executionParameters.put("p3", "e3");\r
+               executionParameters.put("p4", "e4");\r
+               executionParameters.put("p5", "e5");\r
+               executionParameters.put("p6", "e6");\r
+               executionParameters.put("p7", "e7");\r
+               executionParameters.put("p8", "e8");\r
+               addVariables(executionContext, executionParameters);\r
+\r
+               ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
+               validateTestResult((SimpleTestResult) applicationContext\r
+                               .getBean("myTestResult"));\r
+               applicationContext.close();\r
+       }\r
+\r
+       public void testPlaceHoldersExec() throws Exception {\r
+               ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.exec.xml");\r
+\r
+               ExecutionContext executionContext = (ExecutionContext) applicationContext\r
+                               .getBean("executionContext");\r
+               Map<String, String> executionParameters = new HashMap<String, String>();\r
+               executionParameters.put("p1", "e1");\r
+               executionParameters.put("p2", "e2");\r
+               executionParameters.put("p3", "e3");\r
+               executionParameters.put("p4", "e4");\r
+               executionParameters.put("p5", "e5");\r
+               executionParameters.put("p6", "e6");\r
+               addVariables(executionContext, executionParameters);\r
+\r
+               ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
+               validateTestResult((SimpleTestResult) applicationContext\r
+                               .getBean("myTestResult"));\r
+               applicationContext.close();\r
+       }\r
+\r
+       public void testCanonicFlowParameters() throws Exception {\r
+               configureAndExecuteSlcFlow("canonic-001.xml", "canonic.001");\r
+       }\r
+\r
+       public void testCanonicDefaultValues() throws Exception {\r
+               configureAndExecuteSlcFlow("canonic-002.xml", "canonic.002");\r
+       }\r
+\r
+       public void testCanonicMissingValues() throws Exception {\r
+               try {\r
+                       configureAndExecuteSlcFlow("canonic-003.error.xml", "canonic.003");\r
+                       fail("Parameter not set - should be rejected.");\r
+               } catch (BeanCreationException e) {\r
+                       // exception expected\r
+                       logException(e);\r
+               }\r
+       }\r
+\r
+       public void testCanonicUnknownParameter() throws Exception {\r
+               try {\r
+                       configureAndExecuteSlcFlow("canonic-004.error.xml", "canonic.004");\r
+                       fail("Unknown parameter set - should be rejected.");\r
+               } catch (BeanCreationException e) {\r
+                       // exception expected\r
+                       logException(e);\r
+               }\r
+       }\r
+\r
+       public void testListSetMap() throws Exception {\r
+               ConfigurableApplicationContext applicationContext = createApplicationContext("listSetMap.xml");\r
+               ExecutionFlow executionFlow = (ExecutionFlow) applicationContext\r
+                               .getBean("myFlow");\r
+               executionFlow.run();\r
+\r
+               validateTestResult((SimpleTestResult) applicationContext\r
+                               .getBean("myTestResult"));\r
+\r
+               // BasicTestData res = (BasicTestData)\r
+               // applicationContext.getBean("cascadingComplex.testData");\r
+               // log.info("res=" + res.getReached().toString());\r
+\r
+               applicationContext.close();\r
+       }\r
+\r
+       public void testListSetMapMultipleFlows() throws Exception {\r
+               ConfigurableApplicationContext applicationContext = createApplicationContext("listSetMapMultipleFlow.xml");\r
+               ((ExecutionFlow) applicationContext.getBean("flow1")).run();\r
+               SimpleTestResult res = (SimpleTestResult) applicationContext\r
+                               .getBean("myTestResult");\r
+               validateTestResult(res);\r
+               res.getParts().clear();\r
+               ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
+               validateTestResult(res, TestStatus.FAILED);\r
+               applicationContext.close();\r
+       }\r
+\r
+       protected void addVariables(ExecutionContext executionContext,\r
+                       Map<String, String> vars) {\r
+               for (String key : vars.keySet())\r
+                       executionContext.setVariable(key, vars.get(key));\r
+       }\r
+}\r
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/DefaultAgentCliTest.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/DefaultAgentCliTest.java
new file mode 100644 (file)
index 0000000..a7d9b8b
--- /dev/null
@@ -0,0 +1,18 @@
+package org.argeo.slc.core.execution;
+
+import java.net.URI;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public class DefaultAgentCliTest extends TestCase {
+       public void testArgsToUris() {
+               String[] args = { "org.argeo.slc.demo.minimal", "HelloWorld/WithVar",
+                               "--testKey", "555" };
+               List<URI> uris = DefaultAgentCli.asURIs(args);
+               assertEquals(1, uris.size());
+               assertEquals(
+                               "flow:/org.argeo.slc.demo.minimal/HelloWorld/WithVar?testKey=555",
+                               uris.get(0).toString());
+       }
+}
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/ExceptionIfInitCalledTwice.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/ExceptionIfInitCalledTwice.java
new file mode 100644 (file)
index 0000000..55afdc0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.InitializingBean;
+
+public class ExceptionIfInitCalledTwice implements Runnable, InitializingBean {
+       private final static Log log = LogFactory
+                       .getLog(ExceptionIfInitCalledTwice.class);
+
+       private Boolean calledOnce = false;
+
+       public void run() {
+               log.info(getClass().getSimpleName() + " ran properly");
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               log.info(getClass().getSimpleName() + " init method called");
+
+               if (calledOnce)
+                       throw new SlcException(getClass().getSimpleName()
+                                       + "init method called twice.");
+               else
+                       calledOnce = true;
+       }
+}
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesSpringTest.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesSpringTest.java
new file mode 100644 (file)
index 0000000..8b3d2ec
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+
+public class FileExecutionResourcesSpringTest extends
+               AbstractExecutionFlowTestCase {
+       private String basePath = FileExecutionResources.DEFAULT_EXECUTION_RESOURCES_TMP_PATH;
+
+       public void testSimple() throws Exception {
+               File file = getFile("subdir/writeTo");
+               try {
+                       assertFalse(file.exists());
+                       configureAndExecuteSlcFlow("executionResources.xml",
+                                       "executionResources.simple");
+                       assertTrue(file.exists());
+               } finally {
+                       file.deleteOnExit();
+               }
+       }
+
+       public void testPlaceholderPass() throws Exception {
+               File file = getFile("subdir/60");
+               try {
+                       assertFalse(file.exists());
+                       configureAndExecuteSlcFlow("executionResources.xml",
+                                       "executionResources.placeholderPass");
+                       assertTrue(file.exists());
+               } finally {
+                       file.deleteOnExit();
+               }
+       }
+
+       /**
+        * Test that it generate the wrong file because of issue when using
+        * execution placeholder in contructor-arg
+        */
+       public void testPlaceholderFail() throws Exception {
+               File file = getFile("subdir/@{var}");
+               try {
+                       assertFalse(file.exists());
+                       configureAndExecuteSlcFlow("executionResources.xml",
+                                       "executionResources.placeholderFail");
+                       assertTrue(file.exists());
+               } finally {
+                       file.deleteOnExit();
+               }
+       }
+
+       protected File getFile(String relativePath) {
+               return new File(basePath + File.separator
+                               + relativePath.replace('/', File.separatorChar));
+       }
+}
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesTest.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/FileExecutionResourcesTest.java
new file mode 100644 (file)
index 0000000..e2dae65
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.io.FileUtils;
+import org.argeo.slc.execution.ExecutionContext;
+import org.springframework.core.io.Resource;
+
+public class FileExecutionResourcesTest extends TestCase {
+       public void testGetWritableFile() throws Exception {
+               FileExecutionResources executionResources = new FileExecutionResources();
+               ExecutionContext executionContext = new MapExecutionContext();
+               executionResources.setExecutionContext(executionContext);
+
+               String expected = "TEST";
+               String reached = "";
+               try {
+                       // Resource
+                       Resource resource = executionResources
+                                       .getWritableResource("subdir1/textRes.txt");
+                       assertTrue(resource.getFile().getParentFile().exists());
+                       assertFalse(resource.getFile().exists());
+                       FileUtils.writeStringToFile(resource.getFile(), expected);
+                       reached = FileUtils.readFileToString(resource.getFile());
+                       assertEquals(expected, reached);
+
+                       // File
+                       File file = executionResources.getFile("subdir2/textFile.txt");
+                       assertFalse(file.getParentFile().exists());
+                       assertFalse(file.exists());
+                       FileUtils.writeStringToFile(file, expected);
+                       reached = FileUtils.readFileToString(file);
+                       assertEquals(expected, reached);
+               } finally {
+                       if (executionResources.getBaseDir() != null
+                                       && executionResources.getBaseDir().exists())
+                               FileUtils.deleteDirectory(executionResources.getBaseDir());
+               }
+
+       }
+}
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/ParameterRefTest.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/ParameterRefTest.java
new file mode 100644 (file)
index 0000000..35df7eb
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.argeo.slc.core.test.SimpleTestResult;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.test.TestStatus;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class ParameterRefTest extends AbstractExecutionFlowTestCase {
+       public void test001() throws Exception {
+               ConfigurableApplicationContext applicationContext = createApplicationContext("parameterRef.xml");
+               ((ExecutionFlow) applicationContext.getBean("parameterRef.001")).run();
+
+               SimpleTestResult res = (SimpleTestResult) applicationContext
+                               .getBean("parameterRef.testResult");
+               assertEquals(res.getParts().get(0).getStatus(), TestStatus.PASSED);
+               assertEquals(res.getParts().get(1).getStatus(), TestStatus.FAILED);
+
+               applicationContext.close();
+       }
+
+}
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/applicationContext.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/applicationContext.xml
new file mode 100644 (file)
index 0000000..d83c2c1
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" /> \r
+\r
+       <bean id="executionModule_1" class="org.argeo.slc.core.execution.SimpleSpringExecutionModule" >\r
+               <property name="executionContext">\r
+                       <ref bean="executionContext" />\r
+               </property>     \r
+               <property name="name" value="dummyname" />\r
+               <property name="version" value="dummyversion" />\r
+       </bean>\r
\r
+       <bean id="main" parent="slcTemplate.simpleFlow">\r
+               <constructor-arg>\r
+                       <bean parent="slcTemplate.simpleSpec">\r
+                               <property name="attributes">\r
+                                       <map>\r
+                                               <entry key="testKey">\r
+                                                       <bean parent="specAttr.primitive" p:value="660" />\r
+                                               </entry>\r
+                                       </map>\r
+                               </property>\r
+                       </bean>\r
+               </constructor-arg>\r
+               <property name="executables">\r
+                       <list>\r
+                               <ref local="echo1" />\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="echo1" parent="task.echo" scope="execution">\r
+               <property name="message"\r
+                       value="From main! @{testKey}" />\r
+               <aop:scoped-proxy />\r
+       </bean>\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-001.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-001.xml
new file mode 100644 (file)
index 0000000..a1c59c9
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="canonic.xml" />\r
+\r
+       <bean id="canonic.001" parent="canonic.flowTemplate">\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="parameterAtInstantiation" value="1" />\r
+                       </map>\r
+               </constructor-arg>\r
+       </bean>\r
+</beans>\r
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-002.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-002.xml
new file mode 100644 (file)
index 0000000..57f0c8a
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="canonic.xml" />\r
+\r
+       <bean id="canonic.002" parent="canonic.flowTemplate">\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="parameterAtInstantiation" value="2" />\r
+                               <entry key="displayWithoutControl" value="102" />\r
+                               <entry key="displayWithControl" value="202" />\r
+                               <entry key="hide" value="202" />\r
+                               <entry key="notParameterAtInstantiation" value="202" />\r
+                       </map>\r
+               </constructor-arg>\r
+       </bean>\r
+</beans>\r
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-003.error.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-003.error.xml
new file mode 100644 (file)
index 0000000..6de8810
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="canonic.xml" />\r
+\r
+       <bean id="canonic.003" parent="canonic.flowTemplate">\r
+               <constructor-arg>\r
+                       <map>\r
+                               <!-- missing parameter -->\r
+                               <entry key="displayWithoutControl" value="102" />\r
+                               <entry key="displayWithControl" value="202" />\r
+                               <entry key="hide" value="202" />\r
+                       </map>\r
+               </constructor-arg>\r
+       </bean>\r
+</beans>\r
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-004.error.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic-004.error.xml
new file mode 100644 (file)
index 0000000..2638ed6
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="canonic.xml" />\r
+\r
+       <bean id="canonic.004" parent="canonic.flowTemplate">\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="parameterAtInstantiation" value="2" />\r
+                               <entry key="displayWithoutControl" value="102" />\r
+                               <entry key="displayWithControl" value="202" />\r
+                               <entry key="hide" value="202" />\r
+                               <entry key="unknownParameter" value="1" />\r
+                       </map>\r
+               </constructor-arg>\r
+       </bean>\r
+</beans>\r
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/canonic.xml
new file mode 100644 (file)
index 0000000..8d6af0e
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" />\r
+\r
+       <bean id="canonic.spec" parent="slcTemplate.simpleSpec">\r
+               <property name="attributes">\r
+                       <map>\r
+                               <entry key="parameterAtInstantiation">\r
+                                       <bean parent="specAttr.primitive" p:isParameter="true" p:type="integer" />\r
+                               </entry>\r
+                               <entry key="displayWithoutControl">\r
+                                       <bean parent="specAttr.primitive" p:value="100" p:isParameter="true"\r
+                                               p:isFrozen="true" p:type="integer" />\r
+                               </entry>\r
+                               <entry key="displayWithControl">\r
+                                       <bean parent="specAttr.primitive" p:value="200" p:isParameter="true"\r
+                                               p:isFrozen="false" p:type="integer" />\r
+                               </entry>\r
+                               <entry key="hide">\r
+                                       <bean parent="specAttr.primitive" p:value="300" p:isParameter="true"\r
+                                               p:isFrozen="false" p:isHidden="true" p:type="integer" />\r
+                               </entry>                        \r
+                               <entry key="notParameterAtInstantiation">\r
+                                       <bean parent="specAttr.primitive" p:value="400" p:isParameter="false"\r
+                                               p:isFrozen="false" p:isHidden="false" p:type="integer" />\r
+                               </entry>                                                        \r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="canonic.flowTemplate" parent="slcTemplate.simpleFlow"\r
+               abstract="true">\r
+               <constructor-arg ref="canonic.spec" />\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.echo"\r
+                                       p:message="Canonical: displayWithControl=@{displayWithControl}, displayWithoutControl=@{displayWithoutControl}, hide=@{hide}">\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/executionResources.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/executionResources.xml
new file mode 100644 (file)
index 0000000..654f8b4
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" />\r
+\r
+       <bean id="executionResources.spec" parent="slcTemplate.simpleSpec">\r
+               <property name="attributes">\r
+                       <map>\r
+                               <entry key="var">\r
+                                       <bean parent="specAttr.primitive" p:isParameter="false"\r
+                                               p:type="integer" p:value="60" />\r
+                               </entry>\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="executionResources.placeholderPass" parent="slcTemplate.simpleFlow">\r
+               <constructor-arg ref="executionResources.spec" />\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.echo">\r
+                                       <property name="message" value="DATA" />\r
+                                       <property name="writeTo">\r
+                                               <bean parent="slcTemplate.resourcesFactoryBean" scope="execution">\r
+                                                       <property name="executionResources" ref="executionResources" />\r
+                                                       <property name="relativePath" value="subdir/@{var}" />\r
+                                                       <aop:scoped-proxy />\r
+                                               </bean>\r
+                                       </property>\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="executionResources.placeholderFail" parent="slcTemplate.simpleFlow">\r
+               <constructor-arg ref="executionResources.spec" />\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.echo">\r
+                                       <property name="message" value="DATA" />\r
+                                       <property name="writeTo">\r
+                                               <bean factory-bean="executionResources" factory-method="getWritableResource"\r
+                                                       scope="execution">\r
+                                                       <constructor-arg value="subdir/@{var}" />\r
+                                                       <aop:scoped-proxy />\r
+                                               </bean>\r
+                                       </property>\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="executionResources.simple" parent="slcTemplate.simpleFlow">\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.echo">\r
+                                       <property name="message" value="DATA" />\r
+                                       <property name="writeTo">\r
+                                               <bean factory-bean="executionResources" factory-method="getWritableResource"\r
+                                                       scope="execution">\r
+                                                       <constructor-arg value="subdir/writeTo" />\r
+                                                       <aop:scoped-proxy />\r
+                                               </bean>\r
+                                       </property>\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="executionResources" parent="slcTemplate.fileResources">\r
+               <property name="executionContext" ref="executionContext" />\r
+               <property name="withExecutionSubdirectory" value="false" />\r
+       </bean>\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/imports.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/imports.xml
new file mode 100644 (file)
index 0000000..7ddb4ea
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (C) 2007-2012 Argeo GmbH
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+            http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<!-- Copyright (C) 2007-2012 Mathieu Baudier Licensed under the Apache License, 
+       Version 2.0 (the "License"); you may not use this file except in compliance 
+       with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
+       Unless required by applicable law or agreed to in writing, software distributed 
+       under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
+       OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
+       the specific language governing permissions and limitations under the License. -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+       <import resource="classpath:org/argeo/slc/core/execution/spring.xml" />
+       <import resource="classpath:/org/argeo/slc/core/test/spring.xml" />
+
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/listSetMap.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/listSetMap.xml
new file mode 100644 (file)
index 0000000..8cf72e3
--- /dev/null
@@ -0,0 +1,309 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" /> \r
+\r
+       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
+               <property name="testDefinition" ref="basic.testDef" />\r
+               <property name="testResult" ref="myTestResult"/>\r
+       </bean>         \r
+\r
+       <bean id="myFlow" parent="slcTemplate.simpleFlow">\r
+               <constructor-arg>\r
+                       <bean parent="slcTemplate.simpleSpec">\r
+                               <property name="attributes">\r
+                                       <map>\r
+                                               <entry key="testKey">\r
+                                                       <bean parent="specAttr.primitive" p:value="myValue" />\r
+                                               </entry>\r
+                                       </map>\r
+                               </property>\r
+                       </bean>\r
+               </constructor-arg>\r
+               <property name="executables">\r
+                       <list>\r
+                               <ref local="echo1" />\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="simpleMap.testData" />\r
+                               </bean>                         \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingMap.testData" />\r
+                               </bean>                         \r
+                                               \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="simpleList.testData" />\r
+                               </bean>                         \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingList.testData" />\r
+                               </bean>                         \r
+                                                       \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="simpleSet.testData" />\r
+                               </bean>                         \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingSet.testData" />\r
+                               </bean> \r
+                                                       \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingListMap.testData" />\r
+                               </bean>                         \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingSetMap.testData" />\r
+                               </bean> \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingComplex.testData" />\r
+                               </bean>                                 \r
+       \r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+\r
+       <bean id="simpleMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <map>\r
+                               <entry key="key1" value="myValue_myValue" />\r
+                       </map>\r
+               </property>\r
+               <property name="reached">\r
+                       <map>\r
+                               <entry key="key1" value="@{testKey}_@{testKey}" />\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+       \r
+       <bean id="cascadingMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <map>\r
+                               <entry key="key3">\r
+                                       <map>\r
+                                               <entry key="key2">\r
+                                                       <map>\r
+                                                               <entry key="key1" value="myValue" />\r
+                                                       </map>\r
+                                               </entry>\r
+                                               <entry key="key2bis" value="myValue" />\r
+                                       </map>\r
+                               </entry>\r
+                       </map>\r
+               </property>\r
+               <property name="reached">\r
+                       <map>\r
+                               <entry key="key3">\r
+                                       <map>\r
+                                               <entry key="key2">\r
+                                                       <map>\r
+                                                               <entry key="key1" value="@{testKey}" />\r
+                                                       </map>\r
+                                               </entry>\r
+                                               <entry key="key2bis" value="@{testKey}" />\r
+                                       </map>\r
+                               </entry>\r
+                       </map>\r
+               </property>\r
+       </bean> \r
+       \r
+       <bean id="simpleList.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <list>\r
+                               <value>myValue</value>\r
+                               <value>_myValue_</value>\r
+                       </list>\r
+               </property>\r
+               <property name="reached">\r
+                       <list>\r
+                               <value>@{testKey}</value>\r
+                               <value>_@{testKey}_</value>                             \r
+                       </list>\r
+               </property>\r
+       </bean>         \r
+       \r
+       <bean id="cascadingList.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <list>\r
+                               <list>\r
+                                       <value>myValue</value>\r
+                                       <value>_myValue_</value>\r
+                               </list>\r
+                               <value>myValue</value>\r
+                       </list>\r
+               </property>\r
+               <property name="reached">\r
+                       <list>\r
+                               <list>\r
+                                       <value>@{testKey}</value>\r
+                                       <value>_@{testKey}_</value>\r
+                               </list>\r
+                               <value>@{testKey}</value>\r
+                       </list>\r
+               </property>\r
+       </bean>         \r
+       \r
+       <bean id="simpleSet.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <set>\r
+                               <value>myValue</value>\r
+                               <value>_myValue_</value>\r
+                       </set>\r
+               </property>\r
+               <property name="reached">\r
+                       <set>\r
+                               <value>@{testKey}</value>\r
+                               <value>_@{testKey}_</value>                             \r
+                       </set>\r
+               </property>\r
+       </bean>         \r
+       \r
+       <bean id="cascadingSet.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <set>\r
+                               <set>\r
+                                       <value>myValue</value>\r
+                                       <value>_myValue_</value>\r
+                               </set>\r
+                               <value>myValue</value>\r
+                       </set>\r
+               </property>\r
+               <property name="reached">\r
+                       <set>\r
+                               <set>\r
+                                       <value>@{testKey}</value>\r
+                                       <value>_@{testKey}_</value>\r
+                               </set>\r
+                               <value>@{testKey}</value>\r
+                       </set>\r
+               </property>\r
+       </bean>         \r
+       \r
+       <bean id="cascadingListMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <list>\r
+                               <map>\r
+                                       <entry key="key1" value="myValue" />\r
+                               </map>                                          \r
+                       </list>\r
+               </property>\r
+               <property name="reached">\r
+                       <list>\r
+                               <map>\r
+                                       <entry key="key1" value="@{testKey}" />\r
+                               </map>                                  \r
+                       </list>\r
+               </property>\r
+       </bean> \r
+       \r
+       <bean id="cascadingSetMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <set>\r
+                               <map>\r
+                                       <entry key="key1" value="myValue" />\r
+                               </map>                                          \r
+                       </set>\r
+               </property>\r
+               <property name="reached">\r
+                       <set>\r
+                               <map>\r
+                                       <entry key="key1" value="@{testKey}" />\r
+                               </map>                                  \r
+                       </set>\r
+               </property>\r
+       </bean>         \r
+       \r
+       <bean id="cascadingComplex.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <set>\r
+                               <map>\r
+                                       <entry key="key1" value="myValue" />\r
+                               </map>  \r
+                               <list>\r
+                                       <map>\r
+                                               <entry key="key1" value="myValue" />\r
+                                       </map>          \r
+                                       <set>\r
+                                               <set>\r
+                                                       <value>myValue</value>\r
+                                                       <value>_myValue_</value>\r
+                                                       <list>\r
+                                                               <list>\r
+                                                                       <value>myValue</value>\r
+                                                                       <value>_myValue_</value>\r
+                                                               </list>\r
+                                                               <value>myValue</value>\r
+                                                       </list>                                                 \r
+                                               </set>\r
+                                               <value>myValue</value>\r
+                                       </set>                                                                  \r
+                               </list> \r
+                               <set>\r
+                                       <map>\r
+                                               <entry key="key1" value="myValue" />\r
+                                       </map>  \r
+                               </set>                                                                                          \r
+                       </set>\r
+               </property>\r
+               <property name="reached">\r
+                       <set>\r
+                               <map>\r
+                                       <entry key="key1" value="@{testKey}" />\r
+                               </map>  \r
+                               <list>\r
+                                       <map>\r
+                                               <entry key="key1" value="@{testKey}" />\r
+                                       </map>          \r
+                                       <set>\r
+                                               <set>\r
+                                                       <value>@{testKey}</value>\r
+                                                       <value>_@{testKey}_</value>\r
+                                                       <list>\r
+                                                               <list>\r
+                                                                       <value>@{testKey}</value>\r
+                                                                       <value>_@{testKey}_</value>\r
+                                                               </list>\r
+                                                               <value>@{testKey}</value>\r
+                                                       </list>                                                 \r
+                                               </set>\r
+                                               <value>@{testKey}</value>\r
+                                       </set>                                                                  \r
+                               </list> \r
+                               <set>\r
+                                       <map>\r
+                                               <entry key="key1" value="@{testKey}" />\r
+                                       </map>  \r
+                               </set>                                                                                          \r
+                       </set>\r
+               </property>\r
+       </bean>                 \r
+       \r
+       <bean id="basic.testDef" class="org.argeo.slc.core.test.BasicTestDefinition">\r
+       </bean> \r
+\r
+\r
+       <bean id="echo1" parent="task.echo" scope="prototype">\r
+               <property name="message"\r
+                       value="testKey=@{testKey}" />\r
+       </bean>\r
+       \r
+       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/listSetMapMultipleFlow.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/listSetMapMultipleFlow.xml
new file mode 100644 (file)
index 0000000..b8626f8
--- /dev/null
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" /> \r
+\r
+       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
+               <property name="testDefinition" ref="basic.testDef" />\r
+               <property name="testResult" ref="myTestResult"/>\r
+       </bean>         \r
+\r
+       <bean id="abstractFlow" parent="slcTemplate.simpleFlow" abstract="true">\r
+               <property name="executables">\r
+                       <list>\r
+                               <ref local="echo1" />\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="simpleMap.testData" />\r
+                               </bean>                         \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingMap.testData" />\r
+                               </bean>                         \r
+                                               \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="simpleList.testData" />\r
+                               </bean>                         \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingList.testData" />\r
+                               </bean>                         \r
+                                                       \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="simpleSet.testData" />\r
+                               </bean>                         \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingSet.testData" />\r
+                               </bean> \r
+                                                       \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingListMap.testData" />\r
+                               </bean>                         \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingSetMap.testData" />\r
+                               </bean> \r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData" ref="cascadingComplex.testData" />\r
+                               </bean>                                 \r
+       \r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="flow1" parent="abstractFlow" scope="prototype">\r
+               <constructor-arg>\r
+                       <bean parent="slcTemplate.simpleSpec">\r
+                               <property name="attributes">\r
+                                       <map>\r
+                                               <entry key="testKey">\r
+                                                       <bean parent="specAttr.primitive" p:value="myValue" />\r
+                                               </entry>\r
+                                       </map>\r
+                               </property>\r
+                       </bean>\r
+               </constructor-arg>\r
+       </bean> \r
+\r
+       <bean id="flow2" parent="abstractFlow" scope="prototype">\r
+               <constructor-arg>\r
+                       <bean parent="slcTemplate.simpleSpec">\r
+                               <property name="attributes">\r
+                                       <map>\r
+                                               <entry key="testKey">\r
+                                                       <bean parent="specAttr.primitive" p:value="myValue2" />\r
+                                               </entry>\r
+                                       </map>\r
+                               </property>\r
+                       </bean>\r
+               </constructor-arg>\r
+       </bean> \r
+\r
+\r
+       <bean id="simpleMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <map>\r
+                               <entry key="key1" value="myValue_myValue" />\r
+                       </map>\r
+               </property>\r
+               <property name="reached">\r
+                       <map>\r
+                               <entry key="key1" value="@{testKey}_@{testKey}" />\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+       \r
+       <bean id="cascadingMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <map>\r
+                               <entry key="key3">\r
+                                       <map>\r
+                                               <entry key="key2">\r
+                                                       <map>\r
+                                                               <entry key="key1" value="myValue" />\r
+                                                       </map>\r
+                                               </entry>\r
+                                               <entry key="key2bis" value="myValue" />\r
+                                       </map>\r
+                               </entry>\r
+                       </map>\r
+               </property>\r
+               <property name="reached">\r
+                       <map>\r
+                               <entry key="key3">\r
+                                       <map>\r
+                                               <entry key="key2">\r
+                                                       <map>\r
+                                                               <entry key="key1" value="@{testKey}" />\r
+                                                       </map>\r
+                                               </entry>\r
+                                               <entry key="key2bis" value="@{testKey}" />\r
+                                       </map>\r
+                               </entry>\r
+                       </map>\r
+               </property>\r
+       </bean> \r
+       \r
+       <bean id="simpleList.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <list>\r
+                               <value>myValue</value>\r
+                               <value>_myValue_</value>\r
+                       </list>\r
+               </property>\r
+               <property name="reached">\r
+                       <list>\r
+                               <value>@{testKey}</value>\r
+                               <value>_@{testKey}_</value>                             \r
+                       </list>\r
+               </property>\r
+       </bean>         \r
+       \r
+       <bean id="cascadingList.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <list>\r
+                               <list>\r
+                                       <value>myValue</value>\r
+                                       <value>_myValue_</value>\r
+                               </list>\r
+                               <value>myValue</value>\r
+                       </list>\r
+               </property>\r
+               <property name="reached">\r
+                       <list>\r
+                               <list>\r
+                                       <value>@{testKey}</value>\r
+                                       <value>_@{testKey}_</value>\r
+                               </list>\r
+                               <value>@{testKey}</value>\r
+                       </list>\r
+               </property>\r
+       </bean>         \r
+       \r
+       <bean id="simpleSet.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <set>\r
+                               <value>myValue</value>\r
+                               <value>_myValue_</value>\r
+                       </set>\r
+               </property>\r
+               <property name="reached">\r
+                       <set>\r
+                               <value>@{testKey}</value>\r
+                               <value>_@{testKey}_</value>                             \r
+                       </set>\r
+               </property>\r
+       </bean>         \r
+       \r
+       <bean id="cascadingSet.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <set>\r
+                               <set>\r
+                                       <value>myValue</value>\r
+                                       <value>_myValue_</value>\r
+                               </set>\r
+                               <value>myValue</value>\r
+                       </set>\r
+               </property>\r
+               <property name="reached">\r
+                       <set>\r
+                               <set>\r
+                                       <value>@{testKey}</value>\r
+                                       <value>_@{testKey}_</value>\r
+                               </set>\r
+                               <value>@{testKey}</value>\r
+                       </set>\r
+               </property>\r
+       </bean>         \r
+       \r
+       <bean id="cascadingListMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <list>\r
+                               <map>\r
+                                       <entry key="key1" value="myValue" />\r
+                               </map>                                          \r
+                       </list>\r
+               </property>\r
+               <property name="reached">\r
+                       <list>\r
+                               <map>\r
+                                       <entry key="key1" value="@{testKey}" />\r
+                               </map>                                  \r
+                       </list>\r
+               </property>\r
+       </bean> \r
+       \r
+       <bean id="cascadingSetMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <set>\r
+                               <map>\r
+                                       <entry key="key1" value="myValue" />\r
+                               </map>                                          \r
+                       </set>\r
+               </property>\r
+               <property name="reached">\r
+                       <set>\r
+                               <map>\r
+                                       <entry key="key1" value="@{testKey}" />\r
+                               </map>                                  \r
+                       </set>\r
+               </property>\r
+       </bean>         \r
+       \r
+       <bean id="cascadingComplex.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+               <property name="expected">\r
+                       <set>\r
+                               <map>\r
+                                       <entry key="key1" value="myValue" />\r
+                               </map>  \r
+                               <list>\r
+                                       <map>\r
+                                               <entry key="key1" value="myValue" />\r
+                                       </map>          \r
+                                       <set>\r
+                                               <set>\r
+                                                       <value>myValue</value>\r
+                                                       <value>_myValue_</value>\r
+                                                       <list>\r
+                                                               <list>\r
+                                                                       <value>myValue</value>\r
+                                                                       <value>_myValue_</value>\r
+                                                               </list>\r
+                                                               <value>myValue</value>\r
+                                                       </list>                                                 \r
+                                               </set>\r
+                                               <value>myValue</value>\r
+                                       </set>                                                                  \r
+                               </list> \r
+                               <set>\r
+                                       <map>\r
+                                               <entry key="key1" value="myValue" />\r
+                                       </map>  \r
+                               </set>                                                                                          \r
+                       </set>\r
+               </property>\r
+               <property name="reached">\r
+                       <set>\r
+                               <map>\r
+                                       <entry key="key1" value="@{testKey}" />\r
+                               </map>  \r
+                               <list>\r
+                                       <map>\r
+                                               <entry key="key1" value="@{testKey}" />\r
+                                       </map>          \r
+                                       <set>\r
+                                               <set>\r
+                                                       <value>@{testKey}</value>\r
+                                                       <value>_@{testKey}_</value>\r
+                                                       <list>\r
+                                                               <list>\r
+                                                                       <value>@{testKey}</value>\r
+                                                                       <value>_@{testKey}_</value>\r
+                                                               </list>\r
+                                                               <value>@{testKey}</value>\r
+                                                       </list>                                                 \r
+                                               </set>\r
+                                               <value>@{testKey}</value>\r
+                                       </set>                                                                  \r
+                               </list> \r
+                               <set>\r
+                                       <map>\r
+                                               <entry key="key1" value="@{testKey}" />\r
+                                       </map>  \r
+                               </set>                                                                                          \r
+                       </set>\r
+               </property>\r
+       </bean>                 \r
+               \r
+       <bean id="basic.testDef" class="org.argeo.slc.core.test.BasicTestDefinition">\r
+       </bean> \r
+\r
+\r
+       <bean id="echo1" parent="task.echo" scope="prototype">\r
+               <property name="message"\r
+                       value="testKey=@{testKey}" />\r
+       </bean>\r
+       \r
+       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/minimal.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/minimal.xml
new file mode 100644 (file)
index 0000000..5b16697
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" /> \r
+\r
+       <bean id="minimal" parent="slcTemplate.simpleFlow">\r
+               <property name="executionSpec">\r
+                       <bean parent="slcTemplate.simpleSpec">\r
+<!--                           <property name="attributes">\r
+                                       <map>\r
+                                               <entry key="testKey">\r
+                                                       <bean parent="specAttr.primitive" p:value="660" />\r
+                                               </entry>\r
+                                       </map>\r
+                               </property> -->\r
+                       </bean>\r
+               </property>\r
+               <property name="executables">\r
+                       <list>\r
+                               <ref local="echo1" />\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="echo1" parent="task.echo" scope="execution">\r
+               <property name="message"\r
+                       value="From minimal" />\r
+               <aop:scoped-proxy />\r
+       </bean>\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/multipleFlow.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/multipleFlow.xml
new file mode 100644 (file)
index 0000000..58a43e4
--- /dev/null
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" /> \r
+\r
+       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
+\r
+       <bean id="myTestDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
+\r
+       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
+               <property name="testDefinition" ref="myTestDef" />\r
+               <property name="testResult" ref="myTestResult"/>\r
+       </bean>         \r
+\r
+       <bean id="fileDiff.spec" parent="slcTemplate.simpleSpec">\r
+               <property name="attributes">\r
+                       <map>\r
+                               <entry key="fileName">\r
+                                       <bean parent="specAttr.primitive" p:isParameter="true" p:type="string"\r
+                                               p:isFrozen="true" />\r
+                               </entry>\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+\r
+       <bean id="fileDiff.flowTemplate" parent="slcTemplate.simpleFlow"\r
+               abstract="true">\r
+               <property name="path" value="/fileDiff/testcases" />\r
+               <constructor-arg ref="fileDiff.spec" />\r
+               <property name="executables">\r
+                       <list>                  \r
+                               <bean parent="task.echo">\r
+                                       <property name="message" value="fileName=@{fileName}" />\r
+                               </bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="file1" />\r
+                                                       <property name="reached" value="@{fileName}" />\r
+                                               </bean>\r
+                                       </property>     \r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+       \r
+       <bean id="echo" parent="task.echo" scope="prototype">\r
+               <property name="message" value="fileName=@{fileName}" />\r
+       </bean>                 \r
+       \r
+       <bean id="flow1" parent="fileDiff.flowTemplate">\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="fileName" value="file1" />\r
+                       </map>\r
+               </constructor-arg>\r
+       </bean> \r
+\r
+       <bean id="flow2" parent="fileDiff.flowTemplate">\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="fileName" value="file2" />\r
+                       </map>\r
+               </constructor-arg>\r
+       </bean> \r
\r
\r
+ <!-- \r
+       <bean id="flow1" parent="slcTemplate.simpleFlow">\r
+               <property name="path" value="/fileDiff/testcases" />\r
+               <constructor-arg ref="fileDiff.spec" />\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="fileName" value="file1" />\r
+                       </map>\r
+               </constructor-arg>              \r
+               <property name="executables">\r
+                       <list>                  \r
+                               <bean parent="task.echo" scope="execution">\r
+                                       <property name="message" value="fileName=@{fileName}" />\r
+                                       <aop:scoped-proxy />\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="flow2" parent="slcTemplate.simpleFlow">\r
+               <property name="path" value="/fileDiff/testcases" />\r
+               <constructor-arg ref="fileDiff.spec" />\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="fileName" value="file2" />\r
+                       </map>\r
+               </constructor-arg>              \r
+               <property name="executables">\r
+                       <list>                  \r
+                               <bean parent="task.echo" scope="execution">\r
+                                       <property name="message" value="fileName=@{fileName}" />\r
+                                       <aop:scoped-proxy />\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+ -->\r
+<!-- \r
+       <bean id="main" parent="slcTemplate.simpleFlow">\r
+               <property name="executables">\r
+                       <list>          \r
+                               <ref bean="flow1"/>     \r
+                               <ref bean="flow2"/>     \r
+                       </list>\r
+               </property>\r
+       </bean>\r
+ -->\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/parameterRef.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/parameterRef.xml
new file mode 100644 (file)
index 0000000..98cc14d
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" />\r
+\r
+       <!-- DEFINITIONS -->\r
+       <bean id="parameterRef.spec" parent="slcTemplate.simpleSpec">\r
+               <property name="attributes">\r
+                       <map>\r
+                               <entry key="exceptionIfInitCalledTwice">\r
+                                       <bean parent="specAttr.ref"\r
+                                               p:targetClass="org.argeo.slc.core.execution.ExceptionIfInitCalledTwice"\r
+                                               p:isParameter="true" p:isFrozen="true" />\r
+                               </entry>\r
+                               <entry key="testData1">\r
+                                       <bean parent="specAttr.ref" p:targetClass="org.argeo.slc.core.test.BasicTestData"\r
+                                               p:isParameter="true" p:isFrozen="true" />\r
+                               </entry>\r
+                               <entry key="testData2">\r
+                                       <bean parent="specAttr.ref" p:targetClass="org.argeo.slc.core.test.BasicTestData"\r
+                                               p:isParameter="true" p:isFrozen="true" />\r
+                               </entry>\r
+                               <entry key="testedComponentId">\r
+                                       <bean parent="specAttr.primitive" p:value="100" p:isParameter="true"\r
+                                               p:type="integer" />\r
+                               </entry>\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="parameterRef.flowTemplate" parent="slcTemplate.simpleFlow"\r
+               abstract="true">\r
+               <constructor-arg ref="parameterRef.spec" />\r
+               <property name="executables">\r
+                       <list>\r
+                               <!-- Primitive -->\r
+                               <bean parent="task.echo" scope="execution">\r
+                                       <property name="message" value="testedComponentId=@{testedComponentId}" />\r
+                               </bean>\r
+\r
+                               <!-- Exception if init called twice -->\r
+                               <bean parent="parameterRef">\r
+                                       <constructor-arg value="exceptionIfInitCalledTwice" />\r
+                               </bean>\r
+                               <bean parent="parameterRef">\r
+                                       <property name="name" value="exceptionIfInitCalledTwice" />\r
+                               </bean>\r
+\r
+                               <!-- Basic tests -->\r
+                               <bean parent="parameterRef.testRun">\r
+                                       <property name="testData">\r
+                                               <bean parent="parameterRef">\r
+                                                       <constructor-arg value="testData1" />\r
+                                               </bean>\r
+                                       </property>\r
+                               </bean>\r
+                               <bean parent="parameterRef.testRun">\r
+                                       <property name="testData" ref="ref1" />\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <!-- TEST CASES -->\r
+       <bean id="parameterRef.001" parent="parameterRef.flowTemplate">\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="exceptionIfInitCalledTwice">\r
+                                       <bean class="org.argeo.slc.core.execution.ExceptionIfInitCalledTwice" />\r
+                               </entry>\r
+                               <entry key="testData1">\r
+                                       <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                               <property name="expected" value="toto" />\r
+                                               <property name="reached" value="toto" />\r
+                                       </bean>\r
+                               </entry>\r
+                               <entry key="testData2">\r
+                                       <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                               <property name="expected" value="tata" />\r
+                                               <property name="reached" value="toto" />\r
+                                       </bean>\r
+                               </entry>\r
+                       </map>\r
+               </constructor-arg>\r
+       </bean>\r
+\r
+       <!-- UTILITIES -->\r
+\r
+       <bean id="ref1" parent="parameterRef">\r
+               <constructor-arg value="testData2" />\r
+       </bean>\r
+\r
+       <bean id="parameterRef.testResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
+\r
+       <bean id="parameterRef.testRun" class="org.argeo.slc.core.test.SimpleTestRun"\r
+               abstract="true">\r
+               <property name="testResult" ref="parameterRef.testResult" />\r
+               <property name="testDefinition">\r
+                       <bean class="org.argeo.slc.core.test.BasicTestDefinition" />\r
+               </property>\r
+       </bean>\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.exec.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.exec.xml
new file mode 100644 (file)
index 0000000..a36b4a1
--- /dev/null
@@ -0,0 +1,327 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" /> \r
+\r
+       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
+\r
+       <bean id="myTestDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
+\r
+       <bean id="echo1" parent="task.echo">\r
+               <property name="message" value="From minimal" />\r
+       </bean>\r
+\r
+       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
+               <property name="testDefinition" ref="myTestDef" />\r
+               <property name="testResult" ref="myTestResult"/>\r
+       </bean>         \r
+\r
+       <!-- \r
+               The Flow A contains the flow B as executable.\r
+       \r
+               Parameters\r
+               p1: flow A: default - flow B: - \r
+               p2: flow A: set     - flow B: - \r
+               p3: flow A: default - flow B: default \r
+               p4: flow A: set     - flow B: default\r
+               p5: flow A: default - flow B: set \r
+               p6: flow A: set     - flow B: set\r
+               p7: flow A: -       - flow B: default\r
+               p8: flow A: -       - flow B: set\r
+                \r
+               \r
+        -->\r
+\r
+       <bean id="flowA" parent="slcTemplate.simpleFlow">\r
+               <constructor-arg>\r
+                       <bean parent="slcTemplate.simpleSpec">\r
+                               <property name="attributes">\r
+                                       <map>\r
+                                               <entry key="p1"><bean parent="specAttr.primitive" p:value="da1" /></entry>\r
+                                               <entry key="p2"><bean parent="specAttr.primitive" p:value="da2" /></entry>                                              \r
+                                               <entry key="p3"><bean parent="specAttr.primitive" p:value="da3" /></entry>                                              \r
+                                               <entry key="p4"><bean parent="specAttr.primitive" p:value="da4" /></entry>                                              \r
+                                               <entry key="p5"><bean parent="specAttr.primitive" p:value="da5" /></entry>                                              \r
+                                               <entry key="p6"><bean parent="specAttr.primitive" p:value="da6" /></entry>                                              \r
+                                       </map>\r
+                               </property>\r
+                       </bean>\r
+               </constructor-arg>\r
+               <constructor-arg>               \r
+                       <map>\r
+                               <entry key="p2" value="va2"/>\r
+                               <entry key="p4" value="va4"/>\r
+                               <entry key="p6" value="va6"/>\r
+                       </map>\r
+               </constructor-arg>\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.echo"><property name="message" value="p1=@{p1}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da1" />\r
+                                                       <property name="reached" value="@{p1}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>\r
+                               <bean parent="task.echo"><property name="message" value="p2=@{p2}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va2" />\r
+                                                       <property name="reached" value="@{p2}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p3=@{p3}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da3" />\r
+                                                       <property name="reached" value="@{p3}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p4=@{p4}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va4" />\r
+                                                       <property name="reached" value="@{p4}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                                 \r
+                               <bean parent="task.echo"><property name="message" value="p5=@{p5}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da5" />\r
+                                                       <property name="reached" value="@{p5}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p6=@{p6}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va6" />\r
+                                                       <property name="reached" value="@{p6}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                                 \r
+                               <ref bean="flowB"/>                             \r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="flowB" parent="slcTemplate.simpleFlow" scope="prototype">\r
+               <constructor-arg>\r
+                       <bean parent="slcTemplate.simpleSpec">\r
+                               <property name="attributes">\r
+                                       <map>\r
+                                               <entry key="p3"><bean parent="specAttr.primitive" p:value="db3" /></entry>                                              \r
+                                               <entry key="p4"><bean parent="specAttr.primitive" p:value="db4" /></entry>\r
+                                               <entry key="p5"><bean parent="specAttr.primitive" p:value="db5" /></entry>                                              \r
+                                               <entry key="p6"><bean parent="specAttr.primitive" p:value="db6" /></entry>\r
+                                               <entry key="p7"><bean parent="specAttr.primitive" p:value="db7" /></entry>                                              \r
+                                               <entry key="p8"><bean parent="specAttr.primitive" p:value="db8" /></entry>\r
+                                       </map>\r
+                               </property>\r
+                       </bean>\r
+               </constructor-arg>\r
+               <constructor-arg>               \r
+                       <map>\r
+                               <entry key="p3" value="vb3"/>\r
+                               <entry key="p4" value="vb4"/>\r
+                               <entry key="p7" value="vb7"/>\r
+                       </map>\r
+               </constructor-arg>              \r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.echo"><property name="message" value="p1=@{p1}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da1" />\r
+                                                       <property name="reached" value="@{p1}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>\r
+                               <bean parent="task.echo"><property name="message" value="p2=@{p2}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va2" />\r
+                                                       <property name="reached" value="@{p2}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p3=@{p3}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da3" />\r
+                                                       <property name="reached" value="@{p3}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p4=@{p4}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va4" />\r
+                                                       <property name="reached" value="@{p4}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                                 \r
+                               <bean parent="task.echo"><property name="message" value="p5=@{p5}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da5" />\r
+                                                       <property name="reached" value="@{p5}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p6=@{p6}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va6" />\r
+                                                       <property name="reached" value="@{p6}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p7=@{p7}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="vb7" />\r
+                                                       <property name="reached" value="@{p7}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                                                         \r
+                               <bean parent="task.echo"><property name="message" value="p8=@{p8}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="db8" />\r
+                                                       <property name="reached" value="@{p8}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean> \r
+                               \r
+                               <!-- test in scope execution -->\r
+                               <bean parent="task.echo" scope="execution"><property name="message" value="p1=@{p1}" /><aop:scoped-proxy /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
+                                                       <property name="expected" value="e1" />\r
+                                                       <property name="reached" value="@{p1}" />\r
+                                                       <aop:scoped-proxy />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>\r
+                               <bean parent="task.echo" scope="execution"><property name="message" value="p2=@{p2}" /><aop:scoped-proxy /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
+                                                       <property name="expected" value="e2" />\r
+                                                       <property name="reached" value="@{p2}" />\r
+                                                       <aop:scoped-proxy />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo" scope="execution"><property name="message" value="p3=@{p3}" /><aop:scoped-proxy /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
+                                                       <property name="expected" value="e3" />\r
+                                                       <property name="reached" value="@{p3}" />\r
+                                                       <aop:scoped-proxy />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo" scope="execution"><property name="message" value="p4=@{p4}" /><aop:scoped-proxy /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
+                                                       <property name="expected" value="e4" />\r
+                                                       <property name="reached" value="@{p4}" />\r
+                                                       <aop:scoped-proxy />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                                 \r
+                               <bean parent="task.echo" scope="execution"><property name="message" value="p5=@{p5}" /><aop:scoped-proxy /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
+                                                       <property name="expected" value="e5" />\r
+                                                       <property name="reached" value="@{p5}" />\r
+                                                       <aop:scoped-proxy />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo" scope="execution"><property name="message" value="p6=@{p6}" /><aop:scoped-proxy /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
+                                                       <property name="expected" value="e6" />\r
+                                                       <property name="reached" value="@{p6}" />\r
+                                                       <aop:scoped-proxy />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>\r
+                                                               \r
+                               <!-- \r
+                                       p7 and p8 are not in the spec of FlowA and therefore can not be overridden\r
+                                       at the execution\r
+                                -->\r
+                               <bean parent="task.echo" scope="execution"><property name="message" value="p7=@{p7}" /><aop:scoped-proxy /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
+                                                       <property name="expected" value="vb7" />\r
+                                                       <property name="reached" value="@{p7}" />\r
+                                                       <aop:scoped-proxy />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                                                         \r
+                               <bean parent="task.echo" scope="execution"><property name="message" value="p8=@{p8}" /><aop:scoped-proxy /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
+                                                       <property name="expected" value="db8" />\r
+                                                       <property name="reached" value="@{p8}" />\r
+                                                       <aop:scoped-proxy />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>         \r
+                                                                                       \r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/placeHolders.cascading.xml
new file mode 100644 (file)
index 0000000..893768b
--- /dev/null
@@ -0,0 +1,239 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" /> \r
+\r
+       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
+\r
+       <bean id="myTestDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
+\r
+       <bean id="echo1" parent="task.echo">\r
+               <property name="message" value="From minimal" />\r
+       </bean>\r
+\r
+       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
+               <property name="testDefinition" ref="myTestDef" />\r
+               <property name="testResult" ref="myTestResult"/>\r
+       </bean>         \r
+\r
+       <!-- \r
+               The Flow A contains the flow B as executable.\r
+       \r
+               Parameters\r
+               p1: flow A: default - flow B: - \r
+               p2: flow A: set     - flow B: - \r
+               p3: flow A: default - flow B: default \r
+               p4: flow A: set     - flow B: default\r
+               p5: flow A: default - flow B: set \r
+               p6: flow A: set     - flow B: set\r
+               p7: flow A: -       - flow B: default\r
+               p8: flow A: -       - flow B: set\r
+                \r
+               \r
+        -->\r
+\r
+       <bean id="flowA" parent="slcTemplate.simpleFlow">\r
+               <constructor-arg>\r
+                       <bean parent="slcTemplate.simpleSpec">\r
+                               <property name="attributes">\r
+                                       <map>\r
+                                               <entry key="p1"><bean parent="specAttr.primitive" p:value="da1" /></entry>\r
+                                               <entry key="p2"><bean parent="specAttr.primitive" p:value="da2" /></entry>                                              \r
+                                               <entry key="p3"><bean parent="specAttr.primitive" p:value="da3" /></entry>                                              \r
+                                               <entry key="p4"><bean parent="specAttr.primitive" p:value="da4" /></entry>                                              \r
+                                               <entry key="p5"><bean parent="specAttr.primitive" p:value="da5" /></entry>                                              \r
+                                               <entry key="p6"><bean parent="specAttr.primitive" p:value="da6" /></entry>                                              \r
+                                       </map>\r
+                               </property>\r
+                       </bean>\r
+               </constructor-arg>\r
+               <constructor-arg>               \r
+                       <map>\r
+                               <entry key="p2" value="va2"/>\r
+                               <entry key="p4" value="va4"/>\r
+                               <entry key="p6" value="va6"/>\r
+                       </map>\r
+               </constructor-arg>\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.echo"><property name="message" value="p1=@{p1}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da1" />\r
+                                                       <property name="reached" value="@{p1}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>\r
+                               <bean parent="task.echo"><property name="message" value="p2=@{p2}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va2" />\r
+                                                       <property name="reached" value="@{p2}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p3=@{p3}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da3" />\r
+                                                       <property name="reached" value="@{p3}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p4=@{p4}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va4" />\r
+                                                       <property name="reached" value="@{p4}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                                 \r
+                               <bean parent="task.echo"><property name="message" value="p5=@{p5}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da5" />\r
+                                                       <property name="reached" value="@{p5}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p6=@{p6}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va6" />\r
+                                                       <property name="reached" value="@{p6}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                                 \r
+                               <ref bean="flowB"/>                             \r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="flowB" parent="slcTemplate.simpleFlow" scope="prototype">\r
+               <constructor-arg>\r
+                       <bean parent="slcTemplate.simpleSpec">\r
+                               <property name="attributes">\r
+                                       <map>\r
+                                               <entry key="p3"><bean parent="specAttr.primitive" p:value="db3" /></entry>                                              \r
+                                               <entry key="p4"><bean parent="specAttr.primitive" p:value="db4" /></entry>\r
+                                               <entry key="p5"><bean parent="specAttr.primitive" p:value="db5" /></entry>                                              \r
+                                               <entry key="p6"><bean parent="specAttr.primitive" p:value="db6" /></entry>\r
+                                               <entry key="p7"><bean parent="specAttr.primitive" p:value="db7" /></entry>                                              \r
+                                               <entry key="p8"><bean parent="specAttr.primitive" p:value="db8" /></entry>\r
+                                       </map>\r
+                               </property>\r
+                       </bean>\r
+               </constructor-arg>\r
+               <constructor-arg>               \r
+                       <map>\r
+                               <entry key="p3" value="vb3"/>\r
+                               <entry key="p4" value="vb4"/>\r
+                               <entry key="p7" value="vb7"/>\r
+                       </map>\r
+               </constructor-arg>              \r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.echo"><property name="message" value="p1=@{p1}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da1" />\r
+                                                       <property name="reached" value="@{p1}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>\r
+                               <bean parent="task.echo"><property name="message" value="p2=@{p2}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va2" />\r
+                                                       <property name="reached" value="@{p2}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p3=@{p3}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da3" />\r
+                                                       <property name="reached" value="@{p3}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p4=@{p4}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va4" />\r
+                                                       <property name="reached" value="@{p4}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                                 \r
+                               <bean parent="task.echo"><property name="message" value="p5=@{p5}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="da5" />\r
+                                                       <property name="reached" value="@{p5}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p6=@{p6}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="va6" />\r
+                                                       <property name="reached" value="@{p6}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                         \r
+                               <bean parent="task.echo"><property name="message" value="p7=@{p7}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="vb7" />\r
+                                                       <property name="reached" value="@{p7}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean>                                                         \r
+                               <bean parent="task.echo"><property name="message" value="p8=@{p8}" /></bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                                       <property name="expected" value="db8" />\r
+                                                       <property name="reached" value="@{p8}" />\r
+                                               </bean>\r
+                                       </property>                                     \r
+                               </bean> \r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/specOverriding.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/specOverriding.xml
new file mode 100644 (file)
index 0000000..de1dc85
--- /dev/null
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" /> \r
\r
+       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
+\r
+       <bean id="myTestDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
+\r
+       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
+               <property name="testDefinition" ref="myTestDef" />\r
+               <property name="testResult" ref="myTestResult"/>\r
+       </bean>         \r
\r
+       <bean id="spec1" parent="slcTemplate.simpleSpec">\r
+               <property name="attributes">\r
+                       <map>\r
+                               <entry key="testedComponentId">\r
+                                       <bean parent="specAttr.primitive" p:isParameter="true"\r
+                                               p:type="integer" />\r
+                               </entry>\r
+                               <entry key="testData1">\r
+                                       <bean parent="specAttr.ref" p:targetClass="org.argeo.slc.core.test.BasicTestData"\r
+                                               p:isParameter="true" p:isFrozen="true" />\r
+                               </entry>\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="flowTemplate1" parent="slcTemplate.simpleFlow"\r
+               abstract="true">\r
+               <constructor-arg ref="spec1" />\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.echo" scope="execution">\r
+                                       <property name="message" value="From basic @{testedComponentId}" />\r
+                                       <aop:scoped-proxy />\r
+                               </bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean parent="parameterRef">\r
+                                                       <constructor-arg value="testData1" />\r
+                                               </bean>\r
+                                       </property>\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="flow1" parent="flowTemplate1" scope="prototype">\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="testedComponentId" value="200" />\r
+                               <entry key="testData1">\r
+                                       <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
+                                               <aop:scoped-proxy/>\r
+                                               <property name="expected" value="tata101" />\r
+                                               <property name="reached" value="tata@{testedComponentId}" />\r
+                                       </bean>\r
+                               </entry>\r
+                       </map>                  \r
+               </constructor-arg>\r
+       </bean>\r
+\r
+       <bean id="spec2" parent="slcTemplate.simpleSpec">\r
+               <property name="attributes">\r
+                       <map>\r
+                               <entry key="testData1">\r
+                                       <bean parent="specAttr.ref" p:targetClass="org.argeo.slc.core.test.BasicTestData"\r
+                                               p:isParameter="true" p:isFrozen="true" />\r
+                               </entry>\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="flowTemplate2" parent="slcTemplate.simpleFlow" abstract="true">\r
+               <constructor-arg ref="spec2" />\r
+               <property name="executables">\r
+                       <list>\r
+                               <ref bean="flow1"/>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+       \r
+       <bean id="flow2" parent="flowTemplate2">\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="testData1">\r
+                                       <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                               <property name="expected" value="tata100" />\r
+                                               <property name="reached" value="tata100" />\r
+                                       </bean>\r
+                               </entry>\r
+                       </map>                  \r
+               </constructor-arg>\r
+       </bean> \r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/tasks/SystemCallTest.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/tasks/SystemCallTest.java
new file mode 100644 (file)
index 0000000..8301b85
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.core.execution.AbstractExecutionFlowTestCase;
+
+public class SystemCallTest extends AbstractExecutionFlowTestCase {
+       private final static Log log = LogFactory.getLog(SystemCallTest.class);
+
+       private final String defFile = "systemCall.xml";
+
+       public void testSystemCallSimple() throws Exception {
+               if (isOsSupported())
+                       configureAndExecuteSlcFlow(defFile, "systemCallSimple");
+       }
+
+       public void testSystemCallList() throws Exception {
+               if (isOsSupported())
+                       configureAndExecuteSlcFlow(defFile, "systemCallList");
+       }
+
+       public void testSystemCallOsSpecific() throws Exception {
+               if (isOsSupported())
+                       configureAndExecuteSlcFlow(defFile, "systemCallOsSpecific");
+       }
+
+       public void testSystemCallWithVar() throws Exception {
+               if (isOsSupported())
+                       configureAndExecuteSlcFlow(defFile, "systemCallWithVar");
+       }
+
+       protected boolean isOsSupported() {
+               String osName = System.getProperty("os.name");
+               final Boolean ret;
+               if (osName.contains("Windows"))
+                       ret = false;
+               else
+                       ret = true;
+
+               if (ret == false)
+                       log.warn("Skip test because OS '" + osName + "' is not supported.");
+               return ret;
+       }
+}
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/tasks/systemCall.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/tasks/systemCall.xml
new file mode 100644 (file)
index 0000000..8d35650
--- /dev/null
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="../imports.xml" />\r
+\r
+       <bean id="systemCallSimple" parent="slcTemplate.simpleFlow">\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.echo">\r
+                                       <property name="message" value="os.name=${os.name}" />\r
+                               </bean>\r
+                               <bean parent="task.systemCall">\r
+                                       <property name="cmd" value="echo Hello World" />\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="systemCallList" parent="slcTemplate.simpleFlow">\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.systemCall">\r
+                                       <property name="command">\r
+                                               <list>\r
+                                                       <value>echo</value>\r
+                                                       <value>Hello</value>\r
+                                                       <value>World</value>\r
+                                               </list>\r
+                                       </property>\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="systemCallOsSpecific" parent="slcTemplate.simpleFlow">\r
+               <!-- Direct call to dir under Windows isnot working -->\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.systemCall">\r
+                                       <property name="cmd" value="dir" />\r
+                                       <property name="execDir" value="../.." />\r
+                                       <property name="osCmds">\r
+                                               <map>\r
+                                                       <entry key="Linux" value="ls" />\r
+                                                       <entry key="Mac OS X" value="ls" />\r
+                                               </map>\r
+                                       </property>\r
+                               </bean>\r
+                               <bean parent="task.systemCall">\r
+                                       <property name="command">\r
+                                               <list>\r
+                                                       <value>dir</value>\r
+                                               </list>\r
+                                       </property>\r
+                                       <property name="osCommands">\r
+                                               <map>\r
+                                                       <entry key="Linux">\r
+                                                               <list>\r
+                                                                       <value>ls</value>\r
+                                                               </list>\r
+                                                       </entry>\r
+                                                       <entry key="Mac OS X">\r
+                                                               <list>\r
+                                                                       <value>ls</value>\r
+                                                               </list>\r
+                                                       </entry>\r
+                                               </map>\r
+                                       </property>\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="systemCallWithVar" parent="slcTemplate.simpleFlow">\r
+               <constructor-arg>\r
+                       <bean parent="slcTemplate.simpleSpec">\r
+                               <property name="attributes">\r
+                                       <map>\r
+                                               <entry key="var">\r
+                                                       <bean parent="specAttr.primitive" p:value="660" />\r
+                                               </entry>\r
+                                       </map>\r
+                               </property>\r
+                       </bean>\r
+               </constructor-arg>\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.systemCall" scope="execution">\r
+                                       <property name="cmd" value="echo var=@{var}" />\r
+                                       <aop:scoped-proxy />\r
+                               </bean>\r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/test.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/test.xml
new file mode 100644 (file)
index 0000000..d8bec3d
--- /dev/null
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+       xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+       <import resource="imports.xml" /> \r
+\r
+       <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
+\r
+       <bean id="myTestDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
+\r
+       <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
+               <property name="testDefinition" ref="myTestDef" />\r
+               <property name="testResult" ref="myTestResult"/>\r
+       </bean>         \r
\r
+       <bean id="spec1" parent="slcTemplate.simpleSpec">\r
+               <property name="attributes">\r
+                       <map>\r
+                               <entry key="testedComponentId">\r
+                                       <bean parent="specAttr.primitive" p:isParameter="true"\r
+                                               p:type="integer" />\r
+                               </entry>\r
+                               <entry key="testData1">\r
+                                       <bean parent="specAttr.ref" p:targetClass="org.argeo.slc.core.test.BasicTestData"\r
+                                               p:isParameter="true" p:isFrozen="true" />\r
+                               </entry>\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="flowTemplate1" parent="slcTemplate.simpleFlow"\r
+               abstract="true">\r
+               <constructor-arg ref="spec1" />\r
+               <property name="executables">\r
+                       <list>\r
+                               <bean parent="task.echo">\r
+                                       <property name="message" value="From basic @{testedComponentId}" />\r
+                               </bean>\r
+                               <bean parent="myTestRunTemplate">\r
+                                       <property name="testData">\r
+                                               <bean parent="parameterRef">\r
+                                                       <constructor-arg value="testData1" />\r
+                                               </bean>\r
+                                       </property>\r
+                               </bean>\r
+                               <bean parent="task.echo">\r
+                                       <property name="message"><value>From basic @{testedComponentId}</value></property>\r
+                               </bean>         \r
+                               <bean parent="task.echo">\r
+                                       <property name="message"><value>testData1='@{testData1}'</value></property>\r
+                               </bean>                                                 \r
+                       </list>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="flow1" parent="flowTemplate1" scope="prototype">\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="testedComponentId" value="200" />\r
+                               <entry key="testData1">\r
+                                       <bean class="org.argeo.slc.core.test.BasicTestData" scope="execution">\r
+                                               <aop:scoped-proxy/>\r
+                                               <property name="expected" value="tata101" />\r
+                                               <property name="reached" value="tata@{testedComponentId}" />\r
+                                       </bean>\r
+                               </entry>\r
+                       </map>                  \r
+               </constructor-arg>\r
+       </bean>\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/FlowNamespaceTest.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/FlowNamespaceTest.java
new file mode 100644 (file)
index 0000000..f673020
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import org.argeo.slc.core.execution.AbstractExecutionFlowTestCase;
+import org.argeo.slc.core.test.SimpleTestResult;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class FlowNamespaceTest extends AbstractExecutionFlowTestCase {
+       public void testCanonical() throws Exception {
+               ConfigurableApplicationContext applicationContext = createApplicationContext("canonic-ns.xml");
+               ((ExecutionFlow) applicationContext.getBean("canonic-ns.001")).run();
+               ((ExecutionFlow) applicationContext.getBean("canonic-ns.002")).run();
+       }
+
+       public void testAdvanced() throws Exception {
+               ConfigurableApplicationContext applicationContext = createApplicationContext("advanced.xml");
+               ((ExecutionFlow) applicationContext.getBean("flow1")).run();
+               ((ExecutionFlow) applicationContext.getBean("flow2")).run();
+               ((ExecutionFlow) applicationContext.getBean("flow3")).run();
+
+               validateTestResult((SimpleTestResult) applicationContext
+                               .getBean("testResult"));
+       }
+
+       public void testAdvancedExecution() throws Exception {
+               ConfigurableApplicationContext applicationContext = createApplicationContext("advanced.xml");
+
+               ExecutionContext executionContext = (ExecutionContext) applicationContext
+                               .getBean("executionContext");
+               executionContext.setVariable("param2", 4);
+
+               ((ExecutionFlow) applicationContext.getBean("flow4")).run();
+
+               validateTestResult((SimpleTestResult) applicationContext
+                               .getBean("testResult"));
+       }
+
+       // These tests causes pb when using Spring 3
+       
+       // public void testContainers() throws Exception {
+       // ConfigurableApplicationContext applicationContext =
+       // createApplicationContext("containers.xml");
+       // ((ExecutionFlow) applicationContext.getBean("test.list.flow1")).run();
+       // ((ExecutionFlow) applicationContext.getBean("test.list.flow2")).run();
+       //
+       // validateTestResult((SimpleTestResult) applicationContext
+       // .getBean("testResult"));
+       // }
+}
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/advanced.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/advanced.xml
new file mode 100644 (file)
index 0000000..49b6f7e
--- /dev/null
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+       xmlns:flow="http://www.argeo.org/schema/slc-flow"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
+       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
+\r
+       <import resource="classpath:org/argeo/slc/core/execution/spring.xml" />\r
+       <import resource="classpath:/org/argeo/slc/core/test/spring.xml" />\r
+\r
+       <bean id="testResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
+\r
+       <bean id="testDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
+\r
+       <bean id="testRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
+               <property name="testDefinition" ref="testDef" />\r
+               <property name="testResult" ref="testResult"/>\r
+       </bean> \r
+\r
+       <flow:spec id="advanced.spec">\r
+               <description>spec description</description>\r
+               <flow:primitive name="param1" isParameter="true"\r
+                       type="integer" />\r
+               <flow:primitive name="param2" isParameter="true"\r
+                       type="integer" />                       \r
+       </flow:spec>\r
+\r
+\r
+       <flow:flow id="advanced.flowTemplate" abstract="true" spec="advanced.spec"\r
+               path="/path">\r
+               <description>flow description</description>\r
+               <bean parent="task.echo">\r
+                       <property name="message" value="Advanced: param1=@{param1}, param2=@{param2}" />\r
+                       <flow:variable/>\r
+               </bean> \r
+               <flow:flow>\r
+                       <bean parent="task.echo" p:message="Flow in Flow - param1=@{param1}, param2=@{param2} [Not variable]" />\r
+               </flow:flow>\r
\r
+               <bean parent="testRunTemplate">\r
+                       <property name="testData">\r
+                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                       <flow:variable/>\r
+                                       <property name="expected" value="@{param1}" />\r
+                                       <property name="reached" value="@{param2}" />\r
+                               </bean>\r
+                       </property>                                     \r
+               </bean>\r
\r
+       </flow:flow>\r
+\r
+       <flow:flow id="advanced.flowTemplate2" abstract="true" spec="advanced.spec"\r
+               path="/path">\r
+               <bean parent="task.echo" p:message="Advanced2: param1=@{param1}, param2=@{param2}">\r
+                       <flow:variable/>\r
+               </bean>\r
+               <flow:flow parent="advanced.flowTemplate">\r
+                       <flow:arg name="param1" value="@{param1}"/>\r
+                       <flow:arg name="param2">\r
+                               <!-- flow:param in flow:arg -->\r
+                               <flow:param name="param2" />\r
+                       </flow:arg>\r
+               </flow:flow>\r
+       </flow:flow>\r
+\r
+       \r
+       <flow:flow id="flow1" parent="advanced.flowTemplate">\r
+               <flow:arg name="param1" value="1" />\r
+               <flow:arg name="param2" value="1" />\r
+       </flow:flow>\r
+       \r
+       <flow:flow id="flow2">\r
+               <flow:flow parent="advanced.flowTemplate">\r
+                       <flow:arg name="param1" value="2" />\r
+                       <flow:arg name="param2" value="2" />\r
+               </flow:flow>\r
+       </flow:flow>\r
+\r
+       <flow:flow id="flow3" parent="advanced.flowTemplate2">\r
+               <flow:arg name="param1" value="3" />\r
+               <flow:arg name="param2" value="3" />\r
+       </flow:flow>\r
+       \r
+       <flow:flow id="flow4" parent="advanced.flowTemplate">\r
+               <description>Would fail if param 2 is not changed at execution</description>\r
+               <flow:arg name="param1" value="4" />\r
+               <flow:arg name="param2" value="3" />\r
+       </flow:flow>    \r
+\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-001.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-001.xml
new file mode 100644 (file)
index 0000000..aeef3a3
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+       xmlns:flow="http://www.argeo.org/schema/slc-flow"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
+\r
+       <bean id="canonic-ns.001" parent="canonic-ns.flowTemplate">\r
+               <description>Canonic 001</description>\r
+               <constructor-arg>\r
+                       <map>\r
+                               <entry key="parameterAtInstantiation" value="1" />\r
+                       </map>\r
+               </constructor-arg>\r
+       </bean>\r
+</beans>\r
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-002.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/canonic-ns-002.xml
new file mode 100644 (file)
index 0000000..ac5f085
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans:beans xmlns="http://www.argeo.org/schema/slc-flow"\r
+       xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:p="http://www.springframework.org/schema/p"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
+\r
+       <flow id="canonic-ns.002" parent="canonic-ns.flowTemplate">\r
+               <arg name="parameterAtInstantiation" value="2" />\r
+               <arg name="displayWithoutControl" value="102" />\r
+               <arg name="displayWithControl" value="202" />\r
+               <arg name="hide" value="202" />\r
+               <arg name="refWithoutValue">\r
+                       <beans:bean id="testDataOk" p:expected="tata" p:reached="tata"\r
+                               class="org.argeo.slc.core.test.BasicTestData" />\r
+               </arg>\r
+       </flow>\r
+</beans:beans>\r
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/canonic-ns.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/canonic-ns.xml
new file mode 100644 (file)
index 0000000..facb277
--- /dev/null
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans:beans xmlns="http://www.argeo.org/schema/slc-flow"\r
+       xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd\r
+       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
+\r
+       <beans:import resource="classpath:org/argeo/slc/core/execution/spring.xml" />\r
+       <beans:import resource="classpath:/org/argeo/slc/core/test/spring.xml" />\r
+\r
+       <beans:import resource="canonic-ns-001.xml" />\r
+       <beans:import resource="canonic-ns-002.xml" />\r
+       <beans:import resource="tests.xml" />\r
+\r
+       <!--\r
+               Specifications definition is greatly simplified by the flow namespace\r
+       -->\r
+       <spec id="canonic-ns.spec">\r
+               <primitive name="parameterAtInstantiation" isParameter="true"\r
+                       type="integer" />\r
+               <primitive name="displayWithoutControl" value="100"\r
+                       isParameter="true" type="integer" isFrozen="true" />\r
+               <primitive name="displayWithControl" value="200"\r
+                       isParameter="true" type="integer" />\r
+               <primitive name="hide" value="300" isParameter="true" type="integer"\r
+                       isHidden="true" />\r
+               <ref name="refWithValue" targetClass="org.argeo.slc.core.test.BasicTestData"\r
+                       isParameter="true" ref="testDataNok" />\r
+               <ref name="refWithoutValue" targetClass="org.argeo.slc.core.test.BasicTestData" />\r
+               <ref name="refWithoutValueFrozen" targetClass="org.argeo.slc.core.test.BasicTestData"\r
+                       isParameter="true" isFrozen="true">\r
+                       <value>\r
+                               <beans:bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                       <aop:scoped-proxy />\r
+                                       <beans:property name="expected" value="tata" />\r
+                                       <beans:property name="reached" value="tata" />\r
+                               </beans:bean>\r
+                       </value>\r
+               </ref>\r
+       </spec>\r
+\r
+       <flow id="canonic-ns.flowTemplate" abstract="true" spec="canonic-ns.spec"\r
+               path="/path">\r
+               <beans:bean parent="task.echo"\r
+                       p:message="Canonical: displayWithControl=@{displayWithControl}, displayWithoutControl=@{displayWithoutControl}, hide=@{hide}"\r
+                       scope="execution">\r
+                       <aop:scoped-proxy />\r
+               </beans:bean>\r
+               <beans:ref bean="testRun" />\r
+       </flow>\r
+\r
+       <beans:bean id="testDataOk" class="org.argeo.slc.core.test.BasicTestData">\r
+               <aop:scoped-proxy />\r
+               <beans:property name="expected" value="tata" />\r
+               <beans:property name="reached" value="tata" />\r
+       </beans:bean>\r
+\r
+       <beans:bean id="testDataNok" class="org.argeo.slc.core.test.BasicTestData">\r
+               <aop:scoped-proxy />\r
+               <beans:property name="expected" value="tata" />\r
+               <beans:property name="reached" value="toto" />\r
+       </beans:bean>\r
+</beans:beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/containers.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/containers.xml
new file mode 100644 (file)
index 0000000..61bfa07
--- /dev/null
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+       xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd\r
+       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
+\r
+       <import resource="classpath:org/argeo/slc/core/execution/spring.xml" />\r
+       <import resource="classpath:/org/argeo/slc/core/test/spring.xml" />\r
+\r
+       <bean id="testResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
+\r
+       <bean id="testDef" class="org.argeo.slc.core.test.BasicTestDefinition" />\r
+\r
+       <bean id="testRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
+               <property name="testDefinition" ref="testDef" />\r
+               <property name="testResult" ref="testResult"/>\r
+       </bean> \r
+\r
+       <flow:spec id="test.list.spec">\r
+               <flow:ref name="list1" targetClass="java.util.List">\r
+                       <flow:value>\r
+                               <!-- a list element can be used directly as default value-->\r
+                               <list>\r
+                                       <value>val1</value>\r
+                               </list>\r
+                       </flow:value>\r
+               </flow:ref>\r
+               <flow:ref name="list2" targetClass="java.util.List" />\r
+               <!-- following parameters are not used in flow -->\r
+               <flow:ref name="dummyMap" targetClass="java.util.Map">\r
+                       <flow:value>\r
+                               <map></map>\r
+                       </flow:value>\r
+               </flow:ref>\r
+               <flow:ref name="dummySet" targetClass="java.util.Set">\r
+                       <flow:value>\r
+                               <set></set>\r
+                       </flow:value>\r
+               </flow:ref>\r
+               <flow:ref name="dummyProperties" targetClass="java.util.Properties">\r
+                       <flow:value>\r
+                               <props></props>\r
+                       </flow:value>\r
+               </flow:ref>\r
+               \r
+       </flow:spec>\r
+\r
+\r
+       <flow:flow id="test.list.flowTemplate" abstract="true" spec="test.list.spec"\r
+               path="/path">\r
+               <bean parent="task.echo">\r
+                       <property name="message" value="list1=@{list1}, list2=@{list2}" />\r
+                       <flow:variable/>\r
+               </bean> \r
+\r
+               <bean parent="testRunTemplate">\r
+                       <property name="testData">\r
+                               <bean class="org.argeo.slc.core.test.BasicTestData">\r
+                                       <property name="expected">\r
+                                               <flow:param name="list1"/>\r
+                                       </property>\r
+                                       <property name="reached">\r
+                                               <flow:param name="list2"/>\r
+                                       </property>\r
+                               </bean>\r
+                       </property>                                     \r
+               </bean>\r
\r
+       </flow:flow>\r
+\r
+       <flow:flow id="test.list.flow1" parent="test.list.flowTemplate">\r
+               <flow:arg name="list1">\r
+                       <list>\r
+                               <value>val1</value>\r
+                               <value>val2</value>                     \r
+                       </list>\r
+               </flow:arg>\r
+               <flow:arg name="list2">\r
+                       <list>\r
+                               <value>val1</value>\r
+                               <value>val2</value>                     \r
+                       </list>\r
+               </flow:arg>\r
+               \r
+               <!-- not used in flow (just to test that the syntax is accepted): -->\r
+               <flow:arg name="dummyMap">\r
+                       <map></map>\r
+               </flow:arg>\r
+               <flow:arg name="dummySet">\r
+                       <set></set>\r
+               </flow:arg>\r
+               <flow:arg name="dummyProperties">\r
+                       <props></props>\r
+               </flow:arg>             \r
+               \r
+       </flow:flow>\r
+       \r
+       <flow:flow id="test.list.flow2" parent="test.list.flowTemplate">\r
+               <description>use default value for parameter "list1"</description>\r
+               <flow:arg name="list2">\r
+                       <list>\r
+                               <value>val1</value>\r
+                       </list>\r
+               </flow:arg>\r
+       </flow:flow>\r
+\r
+\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/tests.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/execution/xml/tests.xml
new file mode 100644 (file)
index 0000000..ee58a18
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:flow="http://www.argeo.org/schema/slc-flow"\r
+       xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"\r
+       xsi:schemaLocation="\r
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd\r
+       http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-0.12.xsd">\r
+\r
+       <bean id="testRun" class="org.argeo.slc.core.test.SimpleTestRun">\r
+               <property name="testDefinition">\r
+                       <bean class="org.argeo.slc.core.test.BasicTestDefinition" />\r
+               </property>\r
+               <property name="testData">\r
+                       <flow:param name="refWithValue" />\r
+               </property>\r
+               <!--            <property name="testData">-->\r
+               <!--                    <bean parent="parameterRef">-->\r
+               <!--                            <constructor-arg value="refWithValue" />-->\r
+               <!--                    </bean>-->\r
+               <!--            </property>-->\r
+               <property name="testResult">\r
+                       <bean parent="slcDefault.test.basicSimpleTestResult" scope="execution">\r
+                               <property name="attributes">\r
+                                       <map>\r
+                                               <entry key="displayWithControl" value="@{displayWithControl}" />\r
+                                       </map>\r
+                               </property>\r
+                               <aop:scoped-proxy />\r
+                       </bean>\r
+               </property>\r
+       </bean>\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/test/context/AbstractInternalSpringTestCase.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/test/context/AbstractInternalSpringTestCase.java
new file mode 100644 (file)
index 0000000..61eb3b2
--- /dev/null
@@ -0,0 +1,101 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Map;\r
+\r
+import junit.framework.TestCase;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.SlcException;\r
+import org.springframework.beans.factory.BeanFactoryUtils;\r
+import org.springframework.beans.factory.ListableBeanFactory;\r
+import org.springframework.context.ConfigurableApplicationContext;\r
+import org.springframework.context.support.ClassPathXmlApplicationContext;\r
+\r
+/** Helper for tests using a Spring application context. */\r
+public abstract class AbstractInternalSpringTestCase extends TestCase {\r
+       protected final Log log = LogFactory.getLog(getClass());\r
+       private ConfigurableApplicationContext context;\r
+\r
+       /**\r
+        * Gets (and create if necessary) the application context to use. Default\r
+        * implementation uses a class path xml application context and calls\r
+        * {@link #getApplicationContextLocation()}.\r
+        */\r
+       protected ConfigurableApplicationContext getContext() {\r
+               if (context == null) {\r
+                       context = new ClassPathXmlApplicationContext(\r
+                                       getApplicationContextLocation());\r
+               }\r
+               return context;\r
+       }\r
+\r
+       /** Returns a bean from the underlying context */\r
+       @SuppressWarnings(value = { "unchecked" })\r
+       protected <T> T getBean(String beanId) {\r
+               return (T) getContext().getBean(beanId);\r
+       }\r
+\r
+       protected <T> T getBean(Class<? extends T> clss) {\r
+               T bean = loadSingleFromContext(getContext(), clss);\r
+               if (bean == null) {\r
+                       throw new SlcException("Cannot retrieve a unique bean of type "\r
+                                       + clss);\r
+               } else {\r
+                       return bean;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Th location of the application to load. The default implementation\r
+        * returns <i>applicationContext.xml</i> found in the same package as the\r
+        * test.\r
+        */\r
+       protected String getApplicationContextLocation() {\r
+               return inPackage("applicationContext.xml");\r
+       }\r
+\r
+       /**\r
+        * Prefixes the package of the class after converting the '.' to '/' in\r
+        * order to have a resource path.\r
+        */\r
+       protected String inPackage(String suffix) {\r
+               String prefix = getClass().getPackage().getName().replace('.', '/');\r
+               return prefix + '/' + suffix;\r
+       }\r
+\r
+       @SuppressWarnings(value = { "unchecked" })\r
+       protected <T> T loadSingleFromContext(ListableBeanFactory context,\r
+                       Class<T> clss) {\r
+               Map<String, T> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(\r
+                               context, clss, false, false);\r
+               if (beans.size() == 1) {\r
+                       return beans.values().iterator().next();\r
+               } else if (beans.size() > 1) {\r
+                       if (log.isDebugEnabled()) {\r
+                               log\r
+                                               .debug(("Found more that on bean for type " + clss\r
+                                                               + ": " + beans.keySet()));\r
+                       }\r
+                       return null;\r
+               } else {\r
+                       return null;\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/test/context/ContextTest.java b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/test/context/ContextTest.java
new file mode 100644 (file)
index 0000000..694851c
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.List;\r
+\r
+import org.argeo.slc.core.test.SimpleTestResult;\r
+import org.argeo.slc.test.TestResultPart;\r
+import org.argeo.slc.test.TestStatus;\r
+import org.argeo.slc.test.context.ContextAware;\r
+\r
+public class ContextTest extends AbstractInternalSpringTestCase {\r
+\r
+       public void testComplexContext() {\r
+               SimpleTestResult testResult = new SimpleTestResult();\r
+               ContextUtils.compareReachedExpected(\r
+                               (ContextAware) getBean("context.c1"), testResult);\r
+               ContextUtils.compareReachedExpected(\r
+                               (ContextAware) getBean("context.c2"), testResult);\r
+               ContextUtils.compareReachedExpected(\r
+                               (ContextAware) getBean("context.c3"), testResult);\r
+\r
+               List<TestResultPart> parts = testResult.getParts();\r
+               assertEquals(6, parts.size());\r
+               assertEquals(TestStatus.PASSED, parts.get(0).getStatus());\r
+               assertEquals(TestStatus.PASSED, parts.get(1).getStatus());\r
+               assertEquals(TestStatus.PASSED, parts.get(2).getStatus());\r
+               assertEquals(TestStatus.FAILED, parts.get(3).getStatus());\r
+               assertEquals(TestStatus.PASSED, parts.get(4).getStatus());\r
+               assertEquals(TestStatus.PASSED, parts.get(5).getStatus());\r
+       }\r
+}\r
diff --git a/org.argeo.slc.spring/ext/test/org/argeo/slc/core/test/context/applicationContext.xml b/org.argeo.slc.spring/ext/test/org/argeo/slc/core/test/context/applicationContext.xml
new file mode 100644 (file)
index 0000000..4949c4e
--- /dev/null
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+\r
+    Copyright (C) 2007-2012 Argeo GmbH\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+            http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+\r
+-->\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
+\r
+       <bean id="parentContext.pc1" parent="parentContext.template">\r
+               <property name="values">\r
+                       <map>\r
+                               <entry key="rootvar" value="text" />\r
+                       </map>\r
+               </property>\r
+               <property name="expectedValues">\r
+                       <map>\r
+                               <entry key="reference" value="20" />\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="context.c1" parent="context.template">\r
+               <property name="parentContext" ref="parentContext.pc1" />\r
+               <property name="values">\r
+                       <map>\r
+                               <entry key="reference" value="20" />\r
+                               <entry key="any" value="999" />\r
+                               <entry key="skipped" value="999" />\r
+                       </map>\r
+               </property>\r
+               <property name="expectedValues">\r
+                       <map>\r
+                               <entry key="reference" value="21" />\r
+                               <entry key="any" value="*" />\r
+                               <entry key="skipped" value="!" />\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="context.c2" parent="context.template">\r
+               <property name="parentContext" ref="parentContext.pc1" />\r
+               <property name="values">\r
+                       <map>\r
+                               <entry key="var" value="37" />\r
+                               <entry key="bad" value="56" />\r
+                       </map>\r
+               </property>\r
+               <property name="expectedValues">\r
+                       <map>\r
+                               <entry key="var" value="37" />\r
+                               <entry key="bad" value="57" />\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="parentContext.pc2" parent="parentContext.template">\r
+               <property name="parentContext" ref="parentContext.pc1" />\r
+               <property name="expectedValues">\r
+                       <map>\r
+                               <entry key="reference" value="40" />\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="context.c3" parent="context.template">\r
+               <property name="parentContext" ref="parentContext.pc2" />\r
+               <property name="values">\r
+                       <map>\r
+                               <entry key="reference" value="41" />\r
+                               <entry key="rootvar" value="textX" />\r
+                       </map>\r
+               </property>\r
+               <property name="expectedValues">\r
+                       <map>\r
+                               <entry key="reference" value="40" />\r
+                               <entry key="rootvar" value="text" />\r
+                       </map>\r
+               </property>\r
+       </bean>\r
+\r
+\r
+       <bean id="parentContext.template"\r
+               class="org.argeo.slc.core.test.context.SimpleParentContextAware"\r
+               abstract="true">\r
+       </bean>\r
+\r
+       <bean id="context.template"\r
+               class="org.argeo.slc.core.test.context.SimpleContextAware"\r
+               abstract="true">\r
+       </bean>\r
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/pom.xml b/org.argeo.slc.spring/pom.xml
new file mode 100644 (file)
index 0000000..29ba3cf
--- /dev/null
@@ -0,0 +1,92 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>org.argeo.slc</groupId>
+               <artifactId>argeo-slc</artifactId>
+               <version>2.1.17-SNAPSHOT</version>
+               <relativePath>..</relativePath>
+       </parent>
+       <artifactId>org.argeo.slc.spring</artifactId>
+       <name>SLC Spring Runtime</name>
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-surefire-plugin</artifactId>
+                               <configuration>
+                                       <skipTests>true</skipTests>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+       <dependencies>
+               <!-- Commons -->
+               <dependency>
+                       <groupId>org.argeo.commons</groupId>
+                       <artifactId>org.argeo.enterprise</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons</groupId>
+                       <artifactId>org.argeo.node.api</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons</groupId>
+                       <artifactId>org.argeo.cms</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons</groupId>
+                       <artifactId>org.argeo.jcr</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons</groupId>
+                       <artifactId>org.argeo.util</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
+
+               <!-- SLC -->
+               <dependency>
+                       <groupId>org.argeo.slc</groupId>
+                       <artifactId>org.argeo.slc.api</artifactId>
+                       <version>2.1.17-SNAPSHOT</version>
+               </dependency>
+
+               <!-- Spring -->
+               <dependency>
+                       <groupId>org.argeo.tp.spring</groupId>
+                       <artifactId>org.springframework.beans</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.tp.spring</groupId>
+                       <artifactId>org.springframework.core</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.tp.spring</groupId>
+                       <artifactId>org.springframework.context</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.tp.spring</groupId>
+                       <artifactId>org.springframework.aop</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.tp.gemini</groupId>
+                       <artifactId>org.eclipse.gemini.blueprint.core</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.tp.gemini</groupId>
+                       <artifactId>org.eclipse.gemini.blueprint.io</artifactId>
+               </dependency>
+
+               <!-- Ant -->
+               <dependency>
+                       <groupId>org.argeo.tp.apache.ant</groupId>
+                       <artifactId>org.apache.ant</artifactId>
+               </dependency>
+
+       </dependencies>
+</project>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/ant/AntFlowGenerator.java b/org.argeo.slc.spring/src/org/argeo/slc/ant/AntFlowGenerator.java
new file mode 100644 (file)
index 0000000..9dea43e
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.ant;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.argeo.slc.core.execution.AbstractExecutionFlowGenerator;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.core.io.Resource;
+
+public class AntFlowGenerator extends AbstractExecutionFlowGenerator {
+       private List<Resource> antFiles = new ArrayList<Resource>();
+
+       protected Map<String, BeanDefinition> createExecutionFlowDefinitions(
+                       ConfigurableListableBeanFactory beanFactory) {
+               Map<String, BeanDefinition> definitions = new HashMap<String, BeanDefinition>();
+
+               for (Resource antFile : antFiles) {
+                       AntRun antRun = new AntRun();
+                       antRun.setBuildFile(antFile);
+
+                       List<Runnable> executables = new ArrayList<Runnable>();
+                       executables.add(antRun);
+                       definitions.put("ant." + antFile.getFilename(),
+                                       createDefaultFlowDefinition(executables));
+               }
+               return definitions;
+       }
+
+       public void setAntFiles(List<Resource> antFiles) {
+               this.antFiles = antFiles;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/ant/AntRun.java b/org.argeo.slc.spring/src/org/argeo/slc/ant/AntRun.java
new file mode 100644 (file)
index 0000000..1e2dcb9
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.ant;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.helper.ProjectHelper2;
+import org.argeo.slc.SlcException;
+import org.springframework.core.io.Resource;
+
+public class AntRun implements Runnable {
+       private final static Log log = LogFactory.getLog(AntRun.class);
+
+       private Resource buildFile;
+       private File baseDir;
+
+       private List<String> targets = new ArrayList<String>();
+       private Map<Object, Object> properties = new HashMap<Object, Object>();
+
+       public void run() {
+               Project project = new Project();
+
+               try {
+                       String path = buildFile.getURL().getPath();
+                       project.setUserProperty("ant.file", path);
+                       project.setBaseDir(extractBaseDir(path));
+
+                       project.init();
+                       ProjectHelper projectHelper = new ProjectHelper2();
+                       project.addReference(ProjectHelper.PROJECTHELPER_REFERENCE,
+                                       projectHelper);
+                       projectHelper.parse(project, buildFile.getURL());
+               } catch (Exception e) {
+                       throw new SlcException("Could not parse " + buildFile, e);
+               }
+
+               if (properties != null) {
+                       for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+                               project.setUserProperty(entry.getKey().toString(), entry
+                                               .getValue().toString());
+                       }
+               }
+
+               project.fireBuildStarted();
+               Throwable exception = null;
+               try {
+                       project.addBuildListener(new LoggingListener());
+                       if (targets.size() == 0) {
+                               project.executeTarget(project.getDefaultTarget());
+                       } else {
+                               project.executeTargets(new Vector<String>(targets));
+                       }
+               } catch (Throwable e) {
+                       exception = e;
+                       throw new SlcException("Could not run Ant script " + buildFile, e);
+               } finally {
+                       project.fireBuildFinished(exception);
+               }
+       }
+
+       private File extractBaseDir(String path) {
+               if(this.baseDir!=null)
+                       return this.baseDir;
+               
+               String baseDir = null;
+               if (path.length() > 1) {
+                       int indx = path.lastIndexOf('/', path.length() - 1);
+                       if (indx == -1 || indx == 0) {
+                               baseDir = "/";
+                       } else {
+                               baseDir = path.substring(0, indx) + "/";
+                       }
+               } else {
+                       baseDir = "/";
+               }
+               File file = new File(baseDir);
+               if (file.exists()) {
+                       return file;
+               } else {
+                       return new File(System.getProperty("user.dir"));
+               }
+       }
+
+       public void setBuildFile(Resource buildFile) {
+               this.buildFile = buildFile;
+       }
+
+       public void setTargets(List<String> targets) {
+               this.targets = targets;
+       }
+
+       public void setProperties(Map<Object, Object> properties) {
+               this.properties = properties;
+       }
+
+       public void setBaseDir(File baseDir) {
+               this.baseDir = baseDir;
+       }
+
+       protected static class LoggingListener implements BuildListener {
+
+               public void buildFinished(BuildEvent event) {
+                       if (log.isDebugEnabled())
+                               log.debug("Ant build finished: " + event);
+               }
+
+               public void buildStarted(BuildEvent event) {
+                       if (log.isDebugEnabled())
+                               log.debug("Ant build started: " + event);
+               }
+
+               public void messageLogged(BuildEvent event) {
+                       if (event.getPriority() == Project.MSG_DEBUG) {
+                               if (log.isTraceEnabled())
+                                       log.trace(event.getMessage());
+                       } else if (event.getPriority() == Project.MSG_VERBOSE) {
+                               if (log.isDebugEnabled())
+                                       log.debug(event.getMessage());
+                       } else if (event.getPriority() == Project.MSG_INFO) {
+                               log.info(event.getMessage());
+
+                       } else if (event.getPriority() == Project.MSG_WARN) {
+                               log.warn(event.getMessage());
+
+                       } else if (event.getPriority() == Project.MSG_ERR) {
+                               log.error(event.getMessage());
+                       } else {
+                               log.error(event.getMessage());
+                       }
+               }
+
+               public void targetFinished(BuildEvent event) {
+                       if (log.isTraceEnabled())
+                               log.debug("Target finished: " + event.getTarget());
+               }
+
+               public void targetStarted(BuildEvent event) {
+                       if (log.isTraceEnabled())
+                               log.debug("Target started: " + event.getTarget());
+               }
+
+               public void taskFinished(BuildEvent event) {
+               }
+
+               public void taskStarted(BuildEvent event) {
+               }
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/Attachment.java b/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/Attachment.java
new file mode 100644 (file)
index 0000000..ecde0b9
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+public interface Attachment {
+       public String getUuid();
+
+       public void setUuid(String uuid);
+
+       public String getName();
+
+       public String getContentType();
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/AttachmentUploader.java b/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/AttachmentUploader.java
new file mode 100644 (file)
index 0000000..eb484c9
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+import org.springframework.core.io.Resource;
+
+public interface AttachmentUploader {
+       public void upload(Attachment attachment, Resource resource);
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/AttachmentsEnabled.java b/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/AttachmentsEnabled.java
new file mode 100644 (file)
index 0000000..780a6a4
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+public interface AttachmentsEnabled {
+       public void addAttachment(Attachment attachment);
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/AttachmentsStorage.java b/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/AttachmentsStorage.java
new file mode 100644 (file)
index 0000000..2214afa
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public interface AttachmentsStorage {
+       public void retrieveAttachment(Attachment attachment,
+                       OutputStream outputStream);
+
+       /** Does NOT close the provided input stream. */
+       public void storeAttachment(Attachment attachment, InputStream inputStream);
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/FileAttachmentsStorage.java b/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/FileAttachmentsStorage.java
new file mode 100644 (file)
index 0000000..3b7e62d
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.io.Resource;
+
+public class FileAttachmentsStorage implements AttachmentsStorage,
+               AttachmentUploader, InitializingBean {
+       private final static Log log = LogFactory
+                       .getLog(FileAttachmentsStorage.class);
+
+       private File attachmentsDirectory;
+
+       private String attachmentsTocFileName = "attachmentsToc.csv";
+
+       private DateFormat dateFormatDay = new SimpleDateFormat("yyyy-MM-dd");
+       private DateFormat dateFormatTime = new SimpleDateFormat("HH:mm:ss");
+
+       public void afterPropertiesSet() {
+               if (attachmentsDirectory == null) {
+
+                       String osgiInstanceArea = System.getProperty("osgi.instance.area");
+                       if (osgiInstanceArea != null) {
+                               if (osgiInstanceArea.startsWith("file:"))
+                                       osgiInstanceArea = osgiInstanceArea.substring("file:"
+                                                       .length());
+                               attachmentsDirectory = new File(osgiInstanceArea
+                                               + File.separator + "slcAttachments");
+                       }
+
+                       if (attachmentsDirectory == null) {
+                               String tempDir = System.getProperty("java.io.tmpdir");
+                               attachmentsDirectory = new File(tempDir + File.separator
+                                               + "slcAttachments");
+                       }
+               }
+               if (!attachmentsDirectory.exists())
+                       attachmentsDirectory.mkdirs();
+               if (log.isDebugEnabled())
+                       log.debug("File attachment storage initialized in directory "
+                                       + attachmentsDirectory);
+       }
+
+       public void retrieveAttachment(Attachment attachment,
+                       OutputStream outputStream) {
+               File file = getFile(attachment);
+               InputStream in = null;
+               try {
+                       byte[] buffer = new byte[1024 * 1024];
+                       in = new FileInputStream(file);
+                       int read = -1;
+                       while ((read = in.read(buffer)) >= 0) {
+                               outputStream.write(buffer, 0, read);
+                       }
+                       if (log.isTraceEnabled())
+                               log.trace("Read " + attachment + " from " + file);
+               } catch (IOException e) {
+                       throw new SlcException("Cannot write attachment " + attachment
+                                       + " to " + file, e);
+               } finally {
+                       IOUtils.closeQuietly(in);
+               }
+       }
+
+       public void storeAttachment(Attachment attachment, InputStream inputStream) {
+               File file = getFile(attachment);
+               FileOutputStream out = null;
+               try {
+                       byte[] buffer = new byte[1024 * 1024];
+                       out = new FileOutputStream(file);
+                       int read = -1;
+                       while ((read = inputStream.read(buffer)) >= 0) {
+                               out.write(buffer, 0, read);
+                       }
+                       if (log.isTraceEnabled())
+                               log.trace("Wrote " + attachment + " to " + file);
+                       updateAttachmentToc(attachment, file);
+               } catch (IOException e) {
+                       throw new SlcException("Cannot write attachment " + attachment
+                                       + " to " + file, e);
+               } finally {
+                       IOUtils.closeQuietly(out);
+               }
+
+       }
+
+       public void upload(Attachment attachment, Resource resource) {
+               try {
+                       storeAttachment(attachment, resource.getInputStream());
+               } catch (IOException e) {
+                       throw new SlcException("Cannot upload attachment " + attachment, e);
+               }
+       }
+
+       /** For monitoring purposes only */
+       protected void updateAttachmentToc(Attachment attachment, File file) {
+               Date date = new Date(file.lastModified());
+               FileWriter writer = null;
+               try {
+                       writer = new FileWriter(attachmentsDirectory + File.separator
+                                       + attachmentsTocFileName, true);
+                       writer.append(dateFormatDay.format(date));
+                       writer.append(',');
+                       writer.append(dateFormatTime.format(date));
+                       writer.append(',');
+                       writer.append(attachment.getUuid());
+                       writer.append(',');
+                       writer.append(attachment.getName());
+                       writer.append(',');
+                       writer.append(attachment.getContentType());
+                       writer.append(',');
+                       writer.append(Long.toString(file.length()));
+                       writer.append(',');
+                       writer.append(file.getCanonicalPath());
+                       writer.append('\n');
+               } catch (IOException e) {
+                       log.warn("Could not update attachments TOC for " + attachment
+                                       + " and file " + file, e);
+               } finally {
+                       IOUtils.closeQuietly(writer);
+               }
+
+       }
+
+       protected File getFile(Attachment attachment) {
+               File file = new File(attachmentsDirectory + File.separator
+                               + attachment.getUuid());
+               return file;
+       }
+
+       public void setAttachmentsDirectory(File attachmentsDirectory) {
+               this.attachmentsDirectory = attachmentsDirectory;
+       }
+
+       public void setAttachmentsTocFileName(String attachmentsTocFileName) {
+               this.attachmentsTocFileName = attachmentsTocFileName;
+       }
+
+       public void setDateFormatDay(DateFormat dateFormatDay) {
+               this.dateFormatDay = dateFormatDay;
+       }
+
+       public void setDateFormatTime(DateFormat dateFormatTime) {
+               this.dateFormatTime = dateFormatTime;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/SimpleAttachment.java b/org.argeo.slc.spring/src/org/argeo/slc/core/attachment/SimpleAttachment.java
new file mode 100644 (file)
index 0000000..6248dd7
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+import java.io.Serializable;
+import java.util.UUID;
+
+public class SimpleAttachment implements Attachment, Serializable {
+       private static final long serialVersionUID = 6615155908800610606L;
+       private String uuid = UUID.randomUUID().toString();
+       private String name;
+       private String contentType = "";
+
+       public SimpleAttachment() {
+       }
+
+       public SimpleAttachment(String uuid, String name, String contentType) {
+               super();
+               this.uuid = uuid;
+               this.name = name;
+               this.contentType = contentType;
+       }
+
+       public String getUuid() {
+               return uuid;
+       }
+
+       public void setUuid(String uuid) {
+               this.uuid = uuid;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getContentType() {
+               return contentType;
+       }
+
+       public void setContentType(String contentType) {
+               this.contentType = contentType;
+       }
+
+       public String toString() {
+               return "Attachment #" + uuid + "(" + name + ", " + contentType + ")";
+       }
+
+       public boolean equals(Object obj) {
+               if (obj instanceof Attachment) {
+                       Attachment attachment = (Attachment) obj;
+                       if (uuid != null && attachment.getUuid() != null)
+                               return uuid.equals(attachment.getUuid());
+
+                       if (name != null && attachment.getName() != null)
+                               return name.equals(attachment.getName());
+
+                       return hashCode() == attachment.hashCode();
+               }
+               return false;
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/build/ResourceDistribution.java b/org.argeo.slc.spring/src/org/argeo/slc/core/build/ResourceDistribution.java
new file mode 100644 (file)
index 0000000..4ebbe92
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.build;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.StreamReadable;
+import org.argeo.slc.build.Distribution;
+import org.springframework.core.io.Resource;
+
+/** A software distribution archive accessible via a {@link Resource}. */
+public class ResourceDistribution implements Distribution, StreamReadable {
+       private Resource resource;
+
+       public ResourceDistribution() {
+       }
+
+       public ResourceDistribution(Resource location) {
+               this.resource = location;
+       }
+
+       public String getDistributionId() {
+               return resource.toString();
+       }
+
+       public Resource getResource() {
+               return resource;
+       }
+
+       public void setResource(Resource resource) {
+               this.resource = resource;
+       }
+
+       public InputStream getInputStream() {
+               try {
+                       return resource.getInputStream();
+               } catch (IOException e) {
+                       throw new SlcException("Cannot get input stream", e);
+               }
+       }
+
+       @Override
+       public String toString() {
+               return resource.toString();
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/build/VersionDistributionId.java b/org.argeo.slc.spring/src/org/argeo/slc/core/build/VersionDistributionId.java
new file mode 100644 (file)
index 0000000..c11dc00
--- /dev/null
@@ -0,0 +1,97 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.build;\r
+\r
+import java.util.StringTokenizer;\r
+\r
+/**\r
+ * <p>\r
+ * An implementation of the distribution id using the standard\r
+ * Major.Minor.Release notation. And additional arbitrary string can also be\r
+ * added.\r
+ * </p>\r
+ * \r
+ * <p>\r
+ * <b>Examples:</b><br>\r
+ * 0.2.6<br>\r
+ * 2.4.12.RC1\r
+ * </p>\r
+ */\r
+public class VersionDistributionId {\r
+\r
+       private Integer major;\r
+       private Integer minor;\r
+       private Integer release;\r
+       private String additional;\r
+\r
+       /** Parse the provided string in order to set the various components. */\r
+       public void setVersionString(String str) {\r
+               StringTokenizer st = new StringTokenizer(str, ".");\r
+               if (st.hasMoreTokens())\r
+                       major = Integer.parseInt(st.nextToken());\r
+               if (st.hasMoreTokens())\r
+                       minor = Integer.parseInt(st.nextToken());\r
+               if (st.hasMoreTokens())\r
+                       release = Integer.parseInt(st.nextToken());\r
+               if (st.hasMoreTokens())\r
+                       additional = st.nextToken();\r
+       }\r
+\r
+       public Integer getMajor() {\r
+               return major;\r
+       }\r
+\r
+       public void setMajor(Integer major) {\r
+               this.major = major;\r
+       }\r
+\r
+       public Integer getMinor() {\r
+               return minor;\r
+       }\r
+\r
+       public void setMinor(Integer minor) {\r
+               this.minor = minor;\r
+       }\r
+\r
+       public Integer getRelease() {\r
+               return release;\r
+       }\r
+\r
+       public void setRelease(Integer release) {\r
+               this.release = release;\r
+       }\r
+\r
+       public String getAdditional() {\r
+               return additional;\r
+       }\r
+\r
+       public void setAdditional(String additional) {\r
+               this.additional = additional;\r
+       }\r
+\r
+       @Override\r
+       public boolean equals(Object obj) {\r
+               // TODO Auto-generated method stub\r
+               return super.equals(obj);\r
+       }\r
+\r
+       @Override\r
+       public String toString() {\r
+               return major + "." + minor + "." + release\r
+                               + (additional != null ? "." + additional : "");\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/build/VersionedResourceDistribution.java b/org.argeo.slc.spring/src/org/argeo/slc/core/build/VersionedResourceDistribution.java
new file mode 100644 (file)
index 0000000..52307ec
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.build;
+
+import org.argeo.slc.NameVersion;
+import org.springframework.core.io.Resource;
+
+/**
+ * The distribution of a software package (jar, zip, RPM, etc.) which is
+ * versioned. The archive itself is accessible via a {@link Resource}.
+ */
+public class VersionedResourceDistribution extends ResourceDistribution
+               implements NameVersion {
+       private String name;
+       private String version;
+
+       public VersionedResourceDistribution() {
+               super();
+       }
+
+       public VersionedResourceDistribution(NameVersion nameVersion,
+                       Resource resource) {
+               this(nameVersion.getName(), nameVersion.getVersion(), resource);
+       }
+
+       public VersionedResourceDistribution(String name, String version,
+                       Resource resource) {
+               super(resource);
+               this.name = name;
+               this.version = version;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getVersion() {
+               return version;
+       }
+
+       public void setVersion(String version) {
+               this.version = version;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/build/package.html b/org.argeo.slc.spring/src/org/argeo/slc/core/build/package.html
new file mode 100644 (file)
index 0000000..5da2052
--- /dev/null
@@ -0,0 +1,6 @@
+<html>\r
+<head></head>\r
+<body>\r
+SLC Build: building of software systems.\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/DefaultResourceSet.java b/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/DefaultResourceSet.java
new file mode 100644 (file)
index 0000000..abdcfee
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.PathMatcher;
+
+public class DefaultResourceSet implements ResourceLoaderAware,
+               InitializingBean, ResourceSet {
+       private final static Log log = LogFactory.getLog(DefaultResourceSet.class);
+       public final static String DEFAULT_EXCLUDES = "**/.svn/**";
+
+       private String base;
+       private String include;
+       private List<String> includes = new ArrayList<String>();
+       private String exclude;
+       private List<String> excludes = new ArrayList<String>();
+       private Boolean useDefaultExcludes = true;
+       private ResourcePatternResolver resourcePatternResolver;
+       private PathMatcher excludePathMatcher = new AntPathMatcher();
+
+       private ResourceLoader resourceLoader;
+
+       /** List the resources, identified by their relative path. */
+       public Map<String, Resource> listResources() {
+               try {
+                       Map<String, Resource> res = new TreeMap<String, Resource>();
+                       if (base == null)
+                               return res;
+                       String baseResUrl = getResourceLoaderToUse().getResource(base)
+                                       .getURL().toString();
+                       for (String includePattern : includes)
+                               processInclude(res, includePattern, baseResUrl);
+                       return res;
+               } catch (IOException e) {
+                       throw new SlcException("Cannot list resource from " + base, e);
+               }
+       }
+
+       protected void processInclude(Map<String, Resource> res, String include,
+                       String baseResUrl) throws IOException {
+               String pattern = base + "/" + include;
+               if (log.isTraceEnabled())
+                       log.trace("Look for resources with pattern '" + pattern
+                                       + "' in base url " + baseResUrl);
+               Resource[] resources = resourcePatternResolver.getResources(pattern);
+               resources: for (Resource resource : resources) {
+                       String url = resource.getURL().toString();
+                       String relPath = url.substring(baseResUrl.length());
+
+                       // skip dir
+                       if (relPath.charAt(relPath.length() - 1) == '/') {
+                               if (log.isTraceEnabled())
+                                       log.trace("Skip directory " + relPath + "=" + resource);
+                               continue resources;
+                       }
+
+                       // make sure there is not starting '/'
+                       if (relPath.charAt(0) == '/')
+                               relPath = relPath.substring(1);
+
+                       // skip excludes
+                       for (String exclude : excludes)
+                               if (excludePathMatcher.match(exclude, relPath)) {
+                                       if (log.isTraceEnabled())
+                                               log.trace("Exclude " + relPath + "=" + resource);
+                                       continue resources;
+                               }
+
+                       // check if already exists
+                       if (res.containsKey(relPath))
+                               log.warn(relPath + " already matched by " + res.get(relPath)
+                                               + ", " + resource + " will override it.");
+
+                       // store the marched resource
+                       res.put(relPath, resource);
+                       if (log.isTraceEnabled())
+                               log.trace(relPath + "=" + resource);
+               }
+
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               if (resourcePatternResolver == null)
+                       resourcePatternResolver = new PathMatchingResourcePatternResolver(
+                                       getResourceLoaderToUse());
+               if (include != null)
+                       addCommaSeparatedToList(include, includes);
+               if (exclude != null)
+                       addCommaSeparatedToList(exclude, excludes);
+
+               if (includes.size() == 0)
+                       includes.add("**");
+
+               if (useDefaultExcludes)
+                       addCommaSeparatedToList(DEFAULT_EXCLUDES, excludes);
+       }
+
+       private void addCommaSeparatedToList(String str, List<String> lst) {
+               StringTokenizer st = new StringTokenizer(str, ",");
+               while (st.hasMoreTokens()) {
+                       String token = st.nextToken();
+                       if (!lst.contains(token))
+                               lst.add(token);
+               }
+       }
+
+       public void setResourceLoader(ResourceLoader resourceLoader) {
+               this.resourceLoader = resourceLoader;
+       }
+
+       /**
+        * Can be overridden in order to provide the proper resource loader used to
+        * resolve resources.
+        */
+       public ResourceLoader getResourceLoaderToUse() {
+               return resourceLoader;
+       }
+
+       public void setBase(String base) {
+               this.base = base;
+       }
+
+       public void setInclude(String include) {
+               this.include = include;
+       }
+
+       public void setIncludes(List<String> includes) {
+               this.includes = includes;
+       }
+
+       public void setExclude(String exclude) {
+               this.exclude = exclude;
+       }
+
+       public void setExcludes(List<String> excludes) {
+               this.excludes = excludes;
+       }
+
+       public void setUseDefaultExcludes(Boolean useDefaultExcludes) {
+               this.useDefaultExcludes = useDefaultExcludes;
+       }
+
+       public void setExcludePathMatcher(PathMatcher excludePathMatcher) {
+               this.excludePathMatcher = excludePathMatcher;
+       }
+
+       public void setResourcePatternResolver(
+                       ResourcePatternResolver resourcePatternResolver) {
+               this.resourcePatternResolver = resourcePatternResolver;
+       }
+
+       public ResourcePatternResolver getResourcePatternResolver() {
+               return resourcePatternResolver;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/DigestCheck.java b/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/DigestCheck.java
new file mode 100644 (file)
index 0000000..be8355f
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.argeo.slc.SlcException;
+import org.springframework.core.io.Resource;
+import org.springframework.util.DigestUtils;
+
+/** Add Spring capabilities to {@link DigestUtils} */
+public class DigestCheck extends DigestUtils {
+       public static String digest(String algorithm, Resource resource) {
+               try {
+                       File file = resource.getFile();
+                       return org.argeo.util.DigestUtils.digest(algorithm, file);
+               } catch (IOException e) {
+                       try {
+                               return org.argeo.util.DigestUtils.digest(algorithm,
+                                               resource.getInputStream());
+                       } catch (IOException e1) {
+                               throw new SlcException("Cannot digest " + resource
+                                               + " with algorithm " + algorithm, e);
+                       }
+               }
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/LocalFilesDeployment.java b/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/LocalFilesDeployment.java
new file mode 100644 (file)
index 0000000..79ad835
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.argeo.slc.SlcException;
+import org.springframework.core.io.Resource;
+
+public class LocalFilesDeployment implements Runnable {
+       private String targetBase = "";
+       private ResourceSet resourceSet;
+
+       public LocalFilesDeployment() {
+       }
+
+       public LocalFilesDeployment(ResourceSet resourceSet) {
+               this.resourceSet = resourceSet;
+       }
+
+       public void run() {
+               Map<String, Resource> resources = resourceSet.listResources();
+               for (String relPath : resources.keySet()) {
+                       File targetFile = new File(targetBase + File.separator + relPath);
+                       File parentDir = targetFile.getParentFile();
+                       if (!parentDir.exists())
+                               parentDir.mkdirs();
+
+                       Resource resource = resources.get(relPath);
+
+                       InputStream in = null;
+                       OutputStream out = null;
+                       try {
+                               in = resource.getInputStream();
+                               out = FileUtils.openOutputStream(targetFile);
+                               IOUtils.copy(in, out);
+                       } catch (IOException e) {
+                               throw new SlcException("Cannot extract " + resource + " to "
+                                               + targetFile, e);
+                       } finally {
+                               IOUtils.closeQuietly(in);
+                               IOUtils.closeQuietly(out);
+                       }
+               }
+       }
+
+       public void setTargetBase(String targetBase) {
+               this.targetBase = targetBase;
+       }
+
+       public void setResourceSet(ResourceSet resourceSet) {
+               this.resourceSet = resourceSet;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/MultiResourceSet.java b/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/MultiResourceSet.java
new file mode 100644 (file)
index 0000000..8da17ba
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.core.io.Resource;
+
+public class MultiResourceSet implements ResourceSet {
+       private List<ResourceSet> resourceSets = new ArrayList<ResourceSet>();
+
+       public Map<String, Resource> listResources() {
+               Map<String, Resource> res = new HashMap<String, Resource>();
+               for (ResourceSet resourceSet : resourceSets) {
+                       res.putAll(resourceSet.listResources());
+               }
+               return res;
+       }
+
+       /** Last listed override previous for the same relative paths. */
+       public void setResourceSets(List<ResourceSet> resourceSets) {
+               this.resourceSets = resourceSets;
+       }
+
+       public List<ResourceSet> getResourceSets() {
+               return resourceSets;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/ResourceSet.java b/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/ResourceSet.java
new file mode 100644 (file)
index 0000000..01c01ab
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.util.Map;
+
+import org.springframework.core.io.Resource;
+
+public interface ResourceSet {
+       /**
+        * List the resources, identified by their relative path. Relative paths
+        * must NOT start with a '/'.
+        */
+       public Map<String, Resource> listResources();
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/SimpleExecutables.java b/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/SimpleExecutables.java
new file mode 100644 (file)
index 0000000..5a5b825
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.io.File;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.deploy.DeploymentData;
+import org.argeo.slc.deploy.InstalledExecutables;
+import org.argeo.slc.deploy.TargetData;
+
+public class SimpleExecutables implements InstalledExecutables {
+       private final static Log log = LogFactory.getLog(SimpleExecutables.class);
+
+       private String baseDir;
+       private Map<String, String> paths = new TreeMap<String, String>();
+
+       private Distribution distribution;
+
+       public String getExecutablePath(String key) {
+               String path = paths.get(key);
+               if (path == null) {
+                       if (log.isDebugEnabled())
+                               log.debug("No executable path found for key " + key
+                                               + ", using the key as executable name.");
+                       path = key;
+               }
+
+               if (baseDir != null)
+                       path = baseDir + File.separator + path;
+               return path;
+       }
+
+       public String getDeployedSystemId() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public DeploymentData getDeploymentData() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public Distribution getDistribution() {
+               return distribution;
+       }
+
+       public TargetData getTargetData() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public String getBaseDir() {
+               return baseDir;
+       }
+
+       public void setBaseDir(String baseDir) {
+               this.baseDir = baseDir;
+       }
+
+       public Map<String, String> getPaths() {
+               return paths;
+       }
+
+       public void setPaths(Map<String, String> paths) {
+               this.paths = paths;
+       }
+
+       public void setDistribution(Distribution distribution) {
+               this.distribution = distribution;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/VersionedDirSync.java b/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/VersionedDirSync.java
new file mode 100644 (file)
index 0000000..13d2543
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.deploy.VersioningDriver;
+
+/**
+ * Synchronizes an URL to a local directory, taking into account versioning
+ * information if possible.
+ */
+public class VersionedDirSync implements Runnable {
+       private final static Log log = LogFactory.getLog(VersionedDirSync.class);
+
+       private VersioningDriver versioningDriver;
+       private File dir;
+       private String url;
+       private Boolean clean = false;
+
+       private Boolean changed = null;
+
+       public void run() {
+               changed = null;
+               if (clean) {
+                       try {
+                               log.info("Clean " + dir);
+                               FileUtils.deleteDirectory(dir);
+                       } catch (IOException e) {
+                               throw new SlcException("Cannot delete checkout directory "
+                                               + dir, e);
+                       }
+                       dir.mkdirs();
+               }
+               log.info("Checkout " + url + " to " + dir);
+               changed = versioningDriver.checkout(url, dir, true);
+               if (log.isDebugEnabled())
+                       log.debug("Synchronized " + url + " to " + dir);
+       }
+
+       public void setVersioningDriver(VersioningDriver versioningDriver) {
+               this.versioningDriver = versioningDriver;
+       }
+
+       public void setDir(File dir) {
+               this.dir = dir;
+       }
+
+       public void setUrl(String url) {
+               this.url = url;
+       }
+
+       /** Delete before checkout */
+       public void setClean(Boolean clean) {
+               this.clean = clean;
+       }
+
+       /** Whether last call has changed the directory */
+       public Boolean getChanged() {
+               if (changed == null)
+                       throw new SlcException("Sync has not run");
+               return changed;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/package.html b/org.argeo.slc.spring/src/org/argeo/slc/core/deploy/package.html
new file mode 100644 (file)
index 0000000..f3a4c5b
--- /dev/null
@@ -0,0 +1,6 @@
+<html>\r
+<head></head>\r
+<body>\r
+SLC Deploy: deployment of software systems.\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractExecutionFlowGenerator.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractExecutionFlowGenerator.java
new file mode 100644 (file)
index 0000000..dc55b40
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.GenericBeanDefinition;
+import org.springframework.core.Ordered;
+import org.springframework.core.PriorityOrdered;
+
+public abstract class AbstractExecutionFlowGenerator implements
+               BeanFactoryPostProcessor, PriorityOrdered {
+       private final Log log = LogFactory.getLog(getClass());
+
+       protected abstract Map<String, BeanDefinition> createExecutionFlowDefinitions(
+                       ConfigurableListableBeanFactory beanFactory);
+
+       public void postProcessBeanFactory(
+                       ConfigurableListableBeanFactory beanFactory) throws BeansException {
+               if (!(beanFactory instanceof BeanDefinitionRegistry)) {
+                       throw new SlcException("Can only work on "
+                                       + BeanDefinitionRegistry.class);
+               }
+
+               Map<String, BeanDefinition> definitions = createExecutionFlowDefinitions(beanFactory);
+
+               for (String beanName : definitions.keySet()) {
+                       if (log.isTraceEnabled())
+                               log.debug("Registering execution flow " + beanName);
+                       ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(
+                                       beanName, definitions.get(beanName));
+               }
+       }
+
+       protected GenericBeanDefinition createDefaultFlowDefinition(
+                       List<Runnable> executables) {
+               GenericBeanDefinition bd = new GenericBeanDefinition();
+               bd.setBeanClass(DefaultExecutionFlow.class);
+
+               MutablePropertyValues mpv = new MutablePropertyValues();
+               mpv.addPropertyValue("executables", executables);
+
+               bd.setPropertyValues(mpv);
+               return bd;
+       }
+
+       public int getOrder() {
+               return Ordered.HIGHEST_PRECEDENCE;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java
new file mode 100644 (file)
index 0000000..1d401c6
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.RealizedFlow;
+
+/** Provides the base feature of an execution module manager. */
+public abstract class AbstractExecutionModulesManager implements
+               ExecutionModulesManager {
+       private final static Log log = LogFactory
+                       .getLog(AbstractExecutionModulesManager.class);
+
+       // private List<FilteredNotifier> filteredNotifiers = Collections
+       // .synchronizedList(new ArrayList<FilteredNotifier>());
+
+       protected abstract ExecutionFlow findExecutionFlow(String moduleName,
+                       String moduleVersion, String flowName);
+
+       protected abstract ExecutionContext findExecutionContext(String moduleName,
+                       String moduleVersion);
+
+       protected abstract ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
+                       String moduleName, String moduleVersion);
+
+       public void execute(RealizedFlow realizedFlow) {
+               if (log.isTraceEnabled())
+                       log.trace("Executing " + realizedFlow);
+
+               String moduleName = realizedFlow.getModuleName();
+               String moduleVersion = realizedFlow.getModuleVersion();
+
+               Map<? extends String, ? extends Object> variablesToAdd = getExecutionFlowDescriptorConverter(
+                               moduleName, moduleVersion).convertValues(
+                               realizedFlow.getFlowDescriptor());
+               ExecutionContext executionContext = findExecutionContext(moduleName,
+                               moduleVersion);
+               for (String key : variablesToAdd.keySet())
+                       executionContext.setVariable(key, variablesToAdd.get(key));
+
+               ExecutionFlow flow = findExecutionFlow(moduleName, moduleVersion,
+                               realizedFlow.getFlowDescriptor().getName());
+
+               //
+               // Actually runs the flow, IN THIS THREAD
+               //
+               executionContext.beforeFlow(flow);
+               try {
+                       flow.run();
+               } finally {
+                       executionContext.afterFlow(flow);
+               }
+               //
+               //
+               //
+       }
+
+       // public void dispatchUpdateStatus(ExecutionProcess process,
+       // String oldStatus, String newStatus) {
+       // // filtered notifiers
+       // for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
+       // .hasNext();) {
+       // FilteredNotifier filteredNotifier = it.next();
+       // if (filteredNotifier.receiveFrom(process))
+       // filteredNotifier.getNotifier().updateStatus(process, oldStatus,
+       // newStatus);
+       // }
+       //
+       // }
+
+       // public void dispatchAddSteps(ExecutionProcess process,
+       // List<ExecutionStep> steps) {
+       // process.addSteps(steps);
+       // for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
+       // .hasNext();) {
+       // FilteredNotifier filteredNotifier = it.next();
+       // if (filteredNotifier.receiveFrom(process))
+       // filteredNotifier.getNotifier().addSteps(process, steps);
+       // }
+       // }
+
+       // public void registerProcessNotifier(ExecutionProcessNotifier notifier,
+       // Map<String, String> properties) {
+       // filteredNotifiers.add(new FilteredNotifier(notifier, properties));
+       // }
+       //
+       // public void unregisterProcessNotifier(ExecutionProcessNotifier notifier,
+       // Map<String, String> properties) {
+       // filteredNotifiers.remove(notifier);
+       // }
+
+       // protected class FilteredNotifier {
+       // private final ExecutionProcessNotifier notifier;
+       // private final String processId;
+       //
+       // public FilteredNotifier(ExecutionProcessNotifier notifier,
+       // Map<String, String> properties) {
+       // super();
+       // this.notifier = notifier;
+       // if (properties == null)
+       // properties = new HashMap<String, String>();
+       // if (properties.containsKey(SLC_PROCESS_ID))
+       // processId = properties.get(SLC_PROCESS_ID);
+       // else
+       // processId = null;
+       // }
+       //
+       // /**
+       // * Whether event from this process should be received by this listener.
+       // */
+       // public Boolean receiveFrom(ExecutionProcess process) {
+       // if (processId != null)
+       // if (process.getUuid().equals(processId))
+       // return true;
+       // else
+       // return false;
+       // return true;
+       // }
+       //
+       // @Override
+       // public int hashCode() {
+       // return notifier.hashCode();
+       // }
+       //
+       // @Override
+       // public boolean equals(Object obj) {
+       // if (obj instanceof FilteredNotifier) {
+       // FilteredNotifier fn = (FilteredNotifier) obj;
+       // return notifier.equals(fn.notifier);
+       // } else if (obj instanceof ExecutionProcessNotifier) {
+       // ExecutionProcessNotifier epn = (ExecutionProcessNotifier) obj;
+       // return notifier.equals(epn);
+       // } else
+       // return false;
+       // }
+       //
+       // public ExecutionProcessNotifier getNotifier() {
+       // return notifier;
+       // }
+       //
+       // }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractExecutionValue.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractExecutionValue.java
new file mode 100644 (file)
index 0000000..131ffec
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.Serializable;
+
+/** Value to be used by an execution */
+public abstract class AbstractExecutionValue implements Serializable {
+       private static final long serialVersionUID = 1558444746120706961L;
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractSpecAttribute.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractSpecAttribute.java
new file mode 100644 (file)
index 0000000..109c033
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.Serializable;
+
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+
+/** Canonical implementation of the execution spec attribute booleans. */
+public abstract class AbstractSpecAttribute implements ExecutionSpecAttribute,
+               Serializable {
+       private static final long serialVersionUID = 6494963738891709440L;
+       private Boolean isImmutable = false;
+       private Boolean isConstant = false;
+       private Boolean isHidden = false;
+
+       private String description;
+
+       /** Has to be set at instantiation */
+       public Boolean getIsImmutable() {
+               return isImmutable;
+       }
+
+       public void setIsImmutable(Boolean isImmutable) {
+               this.isImmutable = isImmutable;
+       }
+
+       /** Cannot be overridden at runtime */
+       public Boolean getIsConstant() {
+               return isConstant;
+       }
+
+       public void setIsConstant(Boolean isConstant) {
+               this.isConstant = isConstant;
+       }
+
+       /** Should not be shown to the end user */
+       public Boolean getIsHidden() {
+               return isHidden;
+       }
+
+       public void setIsHidden(Boolean isHidden) {
+               this.isHidden = isHidden;
+       }
+
+       /*
+        * DEPRECATED
+        */
+       /** @deprecated use {@link #getIsImmutable()} instead */
+       public Boolean getIsParameter() {
+               return isImmutable;
+       }
+
+       /** @deprecated use {@link #getIsConstant()} instead */
+       public Boolean getIsFrozen() {
+               return isConstant;
+       }
+
+       /** @deprecated use {@link #setIsImmutable(Boolean)} instead */
+       public void setIsParameter(Boolean isParameter) {
+               this.isImmutable = isParameter;
+       }
+
+       /** @deprecated use {@link #setIsConstant(Boolean)} instead */
+       public void setIsFrozen(Boolean isFrozen) {
+               this.isConstant = isFrozen;
+       }
+
+       public void setDescription(String description) {
+               this.description = description;
+       }
+
+       public String getDescription() {
+               return description;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractSpringExecutionModule.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/AbstractSpringExecutionModule.java
new file mode 100644 (file)
index 0000000..b2252f6
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.argeo.slc.execution.ExecutionModule;
+
+@Deprecated
+public abstract class AbstractSpringExecutionModule implements ExecutionModule
+                {
+/*
+       protected ApplicationContext applicationContext;
+
+       protected ExecutionContext executionContext;
+
+       protected ExecutionFlowDescriptorConverter descriptorConverter = new DefaultDescriptorConverter();
+
+       public ExecutionModuleDescriptor getDescriptor() {
+               ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
+               md.setName(getName());
+               md.setVersion(getVersion());
+
+               Map<String, ExecutionFlow> executionFlows = listFlows();
+               for (String name : executionFlows.keySet()) {
+                       ExecutionFlow executionFlow = executionFlows.get(name);
+
+                       Assert.notNull(executionFlow.getName());
+                       Assert.state(name.equals(executionFlow.getName()));
+
+                       ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
+                       Assert.notNull(executionSpec);
+                       Assert.notNull(executionSpec.getName());
+
+                       Map<String, Object> values = new TreeMap<String, Object>();
+                       for (String key : executionSpec.getAttributes().keySet()) {
+                               ExecutionSpecAttribute attribute = executionSpec
+                                               .getAttributes().get(key);
+
+                               if (executionFlow.isSetAsParameter(key)) {
+                                       Object value = executionFlow.getParameter(key);
+                                       if (attribute instanceof PrimitiveSpecAttribute) {
+                                               PrimitiveValue primitiveValue = new PrimitiveValue();
+                                               primitiveValue
+                                                               .setType(((PrimitiveSpecAttribute) attribute)
+                                                                               .getType());
+                                               primitiveValue.setValue(value);
+                                               values.put(key, primitiveValue);
+                                       } else if (attribute instanceof RefSpecAttribute) {
+                                               RefValue refValue = new RefValue();
+                                               if (value instanceof ScopedObject) {
+                                                       refValue.setLabel("RUNTIME "
+                                                                       + value.getClass().getName());
+                                               } else {
+                                                       refValue.setLabel("STATIC "
+                                                                       + value.getClass().getName());
+                                               }
+                                               values.put(key, refValue);
+                                       } else if (attribute instanceof ResourceSpecAttribute) {
+                                               PrimitiveValue primitiveValue = new PrimitiveValue();
+                                               primitiveValue
+                                                               .setType(((ResourceSpecAttribute) attribute)
+                                                                               .getType());
+                                               primitiveValue.setValue(value);
+                                               values.put(key, primitiveValue);
+                                       } else {
+                                               throw new SlcException("Unkown spec attribute type "
+                                                               + attribute.getClass());
+                                       }
+                               }
+
+                       }
+
+                       ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name,
+                                       values, executionSpec);
+                       if (executionFlow.getPath() != null)
+                               efd.setPath(executionFlow.getPath());
+
+                       // Add execution spec if necessary
+                       if (!md.getExecutionSpecs().contains(executionSpec))
+                               md.getExecutionSpecs().add(executionSpec);
+
+                       // Add execution flow
+                       md.getExecutionFlows().add(efd);
+               }
+
+               return md;
+       }
+
+       protected Map<String, ExecutionFlow> listFlows() {
+               GenericBeanFactoryAccessor accessor = new GenericBeanFactoryAccessor(
+                               applicationContext);
+               Map<String, ExecutionFlow> executionFlows = accessor
+                               .getBeansOfType(ExecutionFlow.class);
+               return executionFlows;
+       }
+
+       public void execute(ExecutionFlowDescriptor executionFlowDescriptor) {
+               if (descriptorConverter != null)
+                       executionContext.addVariables(descriptorConverter
+                                       .convertValues(executionFlowDescriptor));
+               ExecutionFlow flow = (ExecutionFlow) applicationContext.getBean(
+                               executionFlowDescriptor.getName(), ExecutionFlow.class);
+               flow.run();
+       }
+
+       public void setApplicationContext(ApplicationContext applicationContext)
+                       throws BeansException {
+               this.applicationContext = applicationContext;
+       }
+
+       public void setExecutionContext(ExecutionContext executionContext) {
+               this.executionContext = executionContext;
+       }
+
+       public void setDescriptorConverter(
+                       ExecutionFlowDescriptorConverter descriptorConverter) {
+               this.descriptorConverter = descriptorConverter;
+       }*/
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultAgent.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultAgent.java
new file mode 100644 (file)
index 0000000..c692820
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLDecoder;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.SlcAgent;
+
+/** Implements the base methods of an SLC agent. */
+public class DefaultAgent implements SlcAgent {
+       // private final static Log log = LogFactory.getLog(DefaultAgent.class);
+       /** UTF-8 charset for encoding. */
+       private final static String UTF8 = "UTF-8";
+
+       private String agentUuid = null;
+       private ExecutionModulesManager modulesManager;
+
+       private ThreadGroup processesThreadGroup;
+       private Map<String, ProcessThread> runningProcesses = Collections
+                       .synchronizedMap(new HashMap<String, ProcessThread>());
+
+       private String defaultModulePrefix = null;
+
+       /*
+        * LIFECYCLE
+        */
+       /** Initialization */
+       public void init() {
+               agentUuid = initAgentUuid();
+               processesThreadGroup = new ThreadGroup("SLC Processes of Agent #"
+                               + agentUuid);
+       }
+
+       /** Clean up (needs to be called by overriding method) */
+       public void destroy() {
+       }
+
+       /**
+        * Called during initialization in order to determines the agent UUID. To be
+        * overridden. By default creates a new one per instance.
+        */
+       protected String initAgentUuid() {
+               return UUID.randomUUID().toString();
+       }
+
+       /*
+        * SLC AGENT
+        */
+       public void process(ExecutionProcess process) {
+               ProcessThread processThread = createProcessThread(processesThreadGroup,
+                               modulesManager, process);
+               processThread.start();
+               runningProcesses.put(process.getUuid(), processThread);
+
+               // clean up old processes
+               Iterator<ProcessThread> it = runningProcesses.values().iterator();
+               while (it.hasNext()) {
+                       ProcessThread pThread = it.next();
+                       if (!pThread.isAlive())
+                               it.remove();
+               }
+       }
+
+       public String process(List<URI> uris) {
+               DefaultProcess process = new DefaultProcess();
+               for (URI uri : uris) {
+                       String[] path = uri.getPath().split("/");
+                       if (path.length < 3)
+                               throw new SlcException("Badly formatted URI: " + uri);
+                       NameVersion nameVersion = new DefaultNameVersion(path[1]);
+                       StringBuilder flow = new StringBuilder();
+                       for (int i = 2; i < path.length; i++)
+                               flow.append('/').append(path[i]);
+
+                       Map<String, Object> values = getQueryMap(uri.getQuery());
+                       // Get execution module descriptor
+                       ExecutionModuleDescriptor emd = getExecutionModuleDescriptor(
+                                       nameVersion.getName(), nameVersion.getVersion());
+                       process.getRealizedFlows().add(
+                                       emd.asRealizedFlow(flow.toString(), values));
+               }
+               process(process);
+               return process.getUuid();
+       }
+
+       public void kill(String processUuid) {
+               if (runningProcesses.containsKey(processUuid)) {
+                       runningProcesses.get(processUuid).interrupt();
+               } else {
+                       // assume is finished
+               }
+       }
+
+       public void waitFor(String processUuid, Long millis) {
+               if (runningProcesses.containsKey(processUuid)) {
+                       try {
+                               if (millis != null)
+                                       runningProcesses.get(processUuid).join(millis);
+                               else
+                                       runningProcesses.get(processUuid).join();
+                       } catch (InterruptedException e) {
+                               // silent
+                       }
+               } else {
+                       // assume is finished
+               }
+       }
+
+       /** Creates the thread which will coordinate the execution for this agent. */
+       protected ProcessThread createProcessThread(
+                       ThreadGroup processesThreadGroup,
+                       ExecutionModulesManager modulesManager, ExecutionProcess process) {
+               ProcessThread processThread = new ProcessThread(processesThreadGroup,
+                               modulesManager, process);
+               return processThread;
+       }
+
+       public ExecutionModuleDescriptor getExecutionModuleDescriptor(
+                       String moduleName, String moduleVersion) {
+               // Get execution module descriptor
+               ExecutionModuleDescriptor emd;
+               try {
+                       modulesManager
+                                       .start(new DefaultNameVersion(moduleName, moduleVersion));
+                       emd = modulesManager.getExecutionModuleDescriptor(moduleName,
+                                       moduleVersion);
+               } catch (SlcException e) {
+                       if (defaultModulePrefix != null) {
+                               moduleName = defaultModulePrefix + "." + moduleName;
+                               modulesManager.start(new DefaultNameVersion(moduleName,
+                                               moduleVersion));
+                               emd = modulesManager.getExecutionModuleDescriptor(moduleName,
+                                               moduleVersion);
+                       } else
+                               throw e;
+               }
+               return emd;
+       }
+
+       public List<ExecutionModuleDescriptor> listExecutionModuleDescriptors() {
+               return modulesManager.listExecutionModules();
+       }
+
+       public boolean ping() {
+               return true;
+       }
+
+       /*
+        * UTILITIES
+        */
+       /**
+        * @param query
+        *            can be null
+        */
+       static Map<String, Object> getQueryMap(String query) {
+               Map<String, Object> map = new LinkedHashMap<String, Object>();
+               if (query == null)
+                       return map;
+               String[] params = query.split("&");
+               for (String param : params) {
+                       String[] arr = param.split("=");
+                       String name = arr[0];
+                       Object value = arr.length > 1 ? param.split("=")[1] : Boolean.TRUE;
+                       try {
+                               map.put(URLDecoder.decode(name, UTF8),
+                                               URLDecoder.decode(value.toString(), UTF8));
+                       } catch (UnsupportedEncodingException e) {
+                               throw new SlcException("Cannot decode '" + param + "'", e);
+                       }
+               }
+               return map;
+       }
+
+       /*
+        * BEAN
+        */
+       public void setModulesManager(ExecutionModulesManager modulesManager) {
+               this.modulesManager = modulesManager;
+       }
+
+       public void setDefaultModulePrefix(String defaultModulePrefix) {
+               this.defaultModulePrefix = defaultModulePrefix;
+       }
+
+       public String getAgentUuid() {
+               return agentUuid;
+       }
+
+       @Override
+       public String toString() {
+               return "Agent #" + getAgentUuid();
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultAgentCli.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultAgentCli.java
new file mode 100644 (file)
index 0000000..e02d50f
--- /dev/null
@@ -0,0 +1,238 @@
+package org.argeo.slc.core.execution;
+
+import java.net.URI;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.argeo.slc.execution.SlcAgent;
+import org.argeo.slc.execution.SlcAgentCli;
+
+/**
+ * Authenticates thread and executes synchronously a command line execution.
+ * Reference implementation of args to URIs algorithm.
+ */
+public class DefaultAgentCli implements SlcAgentCli {
+       private final static Log log = LogFactory.getLog(DefaultAgentCli.class);
+
+       private final static String UTF8 = "UTF-8";
+       private SlcAgent agent;
+//     private AuthenticationManager authenticationManager;
+
+       private Long timeout = 24 * 60 * 60 * 1000l;
+
+       public String process(String[] args) {
+//             if (SecurityContextHolder.getContext().getAuthentication() == null) {
+//                     OsAuthenticationToken oat = new OsAuthenticationToken();
+//                     Authentication authentication = authenticationManager
+//                                     .authenticate(oat);
+//                     SecurityContextHolder.getContext()
+//                                     .setAuthentication(authentication);
+//             }
+
+               if (args.length > 0 && args[0].equals("help")) {
+                       StringBuilder buf = new StringBuilder();
+                       help(args, buf);
+                       log.info("\n" + buf);
+                       return buf.toString();
+               } else {
+                       List<URI> uris = asURIs(args);
+                       String processUuid = agent.process(uris);
+                       agent.waitFor(processUuid, timeout);
+                       return processUuid;
+               }
+       }
+
+       protected void help(String[] rawArgs, StringBuilder buf) {
+               String[] args = Arrays.copyOfRange(rawArgs, 1, rawArgs.length);
+               if (args.length == 0) {// modules
+                       for (ExecutionModuleDescriptor emd : agent
+                                       .listExecutionModuleDescriptors()) {
+                               appendModule(emd, buf);
+                       }
+               } else if (args.length == 1 && !args[0].contains("/")) {// single module
+                       NameVersion nameVersion = new DefaultNameVersion(args[0]);
+                       ExecutionModuleDescriptor emd = agent.getExecutionModuleDescriptor(
+                                       nameVersion.getName(), nameVersion.getVersion());
+                       appendModule(emd, buf);
+
+                       // flows
+                       for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) {
+                               buf.append(" ").append(efd.getName());
+                               if (efd.getDescription() != null
+                                               && !efd.getDescription().trim().equals(""))
+                                       buf.append(" : ").append(" ").append(efd.getDescription());
+                               buf.append('\n');
+                       }
+                       return;
+               } else {
+                       List<URI> uris = asURIs(args);
+                       for (URI uri : uris) {
+                               appendUriHelp(uri, buf);
+                       }
+               }
+       }
+
+       protected void appendUriHelp(URI uri, StringBuilder buf) {
+               String[] path = uri.getPath().split("/");
+               NameVersion nameVersion = new DefaultNameVersion(path[1]);
+               ExecutionModuleDescriptor emd = agent.getExecutionModuleDescriptor(
+                               nameVersion.getName(), nameVersion.getVersion());
+
+               StringBuilder flow = new StringBuilder();
+               for (int i = 2; i < path.length; i++)
+                       flow.append('/').append(path[i]);
+               String flowPath = flow.toString();
+               ExecutionFlowDescriptor efd = findExecutionFlowDescriptor(emd, flowPath);
+               if (efd == null)
+                       throw new SlcException("Flow " + uri + " not found");
+
+               appendModule(emd, buf);
+
+               buf.append(" ").append(efd.getName());
+               if (efd.getDescription() != null
+                               && !efd.getDescription().trim().equals(""))
+                       buf.append(" : ").append(" ").append(efd.getDescription());
+               buf.append('\n');
+               Map<String, Object> values = DefaultAgent.getQueryMap(uri.getQuery());
+               ExecutionSpec spec = efd.getExecutionSpec();
+               for (String attrKey : spec.getAttributes().keySet()) {
+                       ExecutionSpecAttribute esa = spec.getAttributes().get(attrKey);
+                       buf.append("  --").append(attrKey);
+                       if (values.containsKey(attrKey))
+                               buf.append(" ").append(values.get(attrKey));
+                       if (esa.getValue() != null)
+                               buf.append(" (").append(esa.getValue()).append(')');
+                       buf.append('\n');
+               }
+       }
+
+       private void appendModule(ExecutionModuleDescriptor emd, StringBuilder buf) {
+               buf.append("# ").append(emd.getName());
+               if (emd.getDescription() != null
+                               && !emd.getDescription().trim().equals(""))
+                       buf.append(" : ").append(emd.getDescription());
+               if (emd.getVersion() != null)
+                       buf.append(" (v").append(emd.getVersion()).append(")");
+               buf.append('\n');
+       }
+
+       public static List<URI> asURIs(String[] args) {
+               try {
+                       List<URI> uris = new ArrayList<URI>();
+                       List<String> leftOvers = new ArrayList<String>();
+
+                       Boolean hasArgs = false;
+                       String currKey = null;
+                       StringBuilder currUri = null;
+                       Iterator<String> argIt = Arrays.asList(args).iterator();
+                       while (argIt.hasNext()) {
+                               String arg = argIt.next();
+                               if (!arg.startsWith("-")) {
+                                       if (currKey != null) {// value
+                                               currUri.append(URLEncoder.encode(arg, UTF8));
+                                               currKey = null;
+                                       } else { // module
+                                               if (currUri != null) {
+                                                       uris.add(new URI(currUri.toString()));
+                                               }
+                                               currUri = new StringBuilder("flow:");
+
+                                               String currModule = arg;
+                                               currUri.append('/').append(currModule);
+                                               if (!arg.contains("/")) {
+                                                       // flow path not in arg go to next arg
+                                                       if (!argIt.hasNext())
+                                                               throw new SlcException("No flow found");
+                                                       String currFlow = argIt.next();
+                                                       if (!currFlow.startsWith("/"))
+                                                               currFlow = "/" + currFlow;
+                                                       currUri.append(currFlow);
+                                               }
+                                       }
+                               } else {
+                                       if (currUri == null) {// first args
+                                               leftOvers.add(arg);
+                                       } else {
+                                               String key;
+                                               if (arg.startsWith("--"))
+                                                       key = arg.substring(2);
+                                               else if (arg.startsWith("-"))
+                                                       key = arg.substring(1);
+                                               else {
+                                                       throw new SlcException("Cannot intepret key: "
+                                                                       + arg);
+                                               }
+
+                                               if (!hasArgs) {
+                                                       currUri.append('?');
+                                                       hasArgs = true;
+                                               } else {
+                                                       currUri.append('&');
+                                               }
+
+                                               // deal with boolean keys
+                                               if (currKey != null) {// value
+                                                       currUri.append(URLEncoder.encode("true", UTF8));
+                                                       currKey = null;
+                                               }
+
+                                               currKey = key;
+                                               currUri.append(URLEncoder.encode(key, UTF8))
+                                                               .append('=');
+                                       }
+                               }
+                       }
+                       if (currUri != null)
+                               uris.add(new URI(currUri.toString()));
+                       return uris;
+               } catch (Exception e) {
+                       throw new SlcException("Cannot convert " + Arrays.toString(args)
+                                       + " to flow URI", e);
+               }
+       }
+
+       private ExecutionFlowDescriptor findExecutionFlowDescriptor(
+                       ExecutionModuleDescriptor emd, String flowPath) {
+               ExecutionFlowDescriptor flowDescriptor = null;
+               for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) {
+                       String name = efd.getName();
+                       // normalize name as flow path
+                       if (!name.startsWith("/"))
+                               name = "/" + name;
+                       if (name.endsWith("/"))
+                               name = name.substring(0, name.length() - 1);
+                       if (name.equals(flowPath)) {
+                               flowDescriptor = efd;
+                               break;
+                       }
+               }
+               return flowDescriptor;
+       }
+
+       public void setAgent(SlcAgent agent) {
+               this.agent = agent;
+       }
+
+//     public void setAuthenticationManager(
+//                     AuthenticationManager authenticationManager) {
+//             this.authenticationManager = authenticationManager;
+//     }
+
+       public void setTimeout(Long timeout) {
+               this.timeout = timeout;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionFlow.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionFlow.java
new file mode 100644 (file)
index 0000000..bebde75
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.validation.MapBindingResult;
+
+/** Default implementation of an execution flow. */
+public class DefaultExecutionFlow implements ExecutionFlow, InitializingBean,
+               BeanNameAware {
+       private final static Log log = LogFactory
+                       .getLog(DefaultExecutionFlow.class);
+
+       private final ExecutionSpec executionSpec;
+       private String name = null;
+       private Map<String, Object> parameters = new HashMap<String, Object>();
+       private List<Runnable> executables = new ArrayList<Runnable>();
+
+       private String path;
+
+       private Boolean failOnError = true;
+
+       // Only needed if stacked execution flows are used
+       private ExecutionContext executionContext = null;
+
+       public DefaultExecutionFlow() {
+               this.executionSpec = new DefaultExecutionSpec();
+       }
+
+       public DefaultExecutionFlow(ExecutionSpec executionSpec) {
+               this.executionSpec = executionSpec;
+       }
+
+       public DefaultExecutionFlow(ExecutionSpec executionSpec,
+                       Map<String, Object> parameters) {
+               // be sure to have an execution spec
+               this.executionSpec = (executionSpec == null) ? new DefaultExecutionSpec()
+                               : executionSpec;
+
+               // only parameters contained in the executionSpec can be set
+               for (String parameter : parameters.keySet()) {
+                       if (!executionSpec.getAttributes().containsKey(parameter)) {
+                               throw new SlcException("Parameter " + parameter
+                                               + " is not defined in the ExecutionSpec");
+                       }
+               }
+
+               // set the parameters
+               this.parameters.putAll(parameters);
+
+               // check that all the required parameters are defined
+               MapBindingResult errors = new MapBindingResult(parameters, "execution#"
+                               + getName());
+               for (String key : executionSpec.getAttributes().keySet()) {
+                       ExecutionSpecAttribute attr = executionSpec.getAttributes()
+                                       .get(key);
+
+                       if (attr.getIsImmutable() && !isSetAsParameter(key)) {
+                               errors.rejectValue(key, "Immutable but not set");
+                               break;
+                       }
+
+                       if (attr.getIsConstant() && !isSetAsParameter(key)) {
+                               errors.rejectValue(key, "Constant but not set as parameter");
+                               break;
+                       }
+
+                       if (attr.getIsHidden() && !isSetAsParameter(key)) {
+                               errors.rejectValue(key, "Hidden but not set as parameter");
+                               break;
+                       }
+               }
+
+               if (errors.hasErrors())
+                       throw new SlcException("Could not prepare execution flow: "
+                                       + errors.toString());
+
+       }
+
+       public void run() {
+               try {
+                       for (Runnable executable : executables) {
+                               if (Thread.interrupted()) {
+                                       log.error("Flow '" + getName() + "' killed before '"
+                                                       + executable + "'");
+                                       Thread.currentThread().interrupt();
+                                       return;
+                                       // throw new ThreadDeath();
+                               }
+                               this.doExecuteRunnable(executable);
+                       }
+               } catch (RuntimeException e) {
+                       if (Thread.interrupted()) {
+                               log.error("Flow '" + getName()
+                                               + "' killed while receiving an unrelated exception", e);
+                               Thread.currentThread().interrupt();
+                               return;
+                               // throw new ThreadDeath();
+                       }
+                       if (failOnError)
+                               throw e;
+                       else {
+                               log.error("Execution flow failed,"
+                                               + " but process did not fail"
+                                               + " because failOnError property"
+                                               + " is set to false: " + e);
+                               if (log.isTraceEnabled())
+                                       e.printStackTrace();
+                       }
+               }
+       }
+
+       /**
+        * List sub-runnables that would be executed if run() method would be
+        * called.
+        */
+       public Iterator<Runnable> runnables() {
+               return executables.iterator();
+       }
+
+       /**
+        * If there is one and only one runnable wrapped return it, throw an
+        * exeception otherwise.
+        */
+       public Runnable getRunnable() {
+               if (executables.size() == 1)
+                       return executables.get(0);
+               else
+                       throw new SlcException("There are " + executables.size()
+                                       + " runnables in flow " + getName());
+       }
+
+       public void doExecuteRunnable(Runnable runnable) {
+               try {
+                       if (executionContext != null)
+                               if (runnable instanceof ExecutionFlow)
+                                       executionContext.beforeFlow((ExecutionFlow) runnable);
+                       runnable.run();
+               } finally {
+                       if (executionContext != null)
+                               if (runnable instanceof ExecutionFlow)
+                                       executionContext.afterFlow((ExecutionFlow) runnable);
+               }
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               if (path == null) {
+                       if (name.charAt(0) == '/') {
+                               path = name.substring(0, name.lastIndexOf('/'));
+                       }
+               }
+
+               if (path != null) {
+                       for (Runnable executable : executables) {
+                               if (executable instanceof DefaultExecutionFlow) {
+                                       // so we don't need to have DefaultExecutionFlow
+                                       // implementing StructureAware
+                                       // FIXME: probably has side effects
+                                       DefaultExecutionFlow flow = (DefaultExecutionFlow) executable;
+                                       String newPath = path + '/' + flow.getName();
+                                       flow.setPath(newPath);
+                                       log.warn(newPath + " was forcibly set on " + flow);
+                               }
+                       }
+               }
+       }
+
+       public void setBeanName(String name) {
+               this.name = name;
+       }
+
+       public void setExecutables(List<Runnable> executables) {
+               this.executables = executables;
+       }
+
+       public void setParameters(Map<String, Object> attributes) {
+               this.parameters = attributes;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public ExecutionSpec getExecutionSpec() {
+               return executionSpec;
+       }
+
+       public Object getParameter(String parameterName) {
+               // Verify that there is a spec attribute
+               ExecutionSpecAttribute specAttr = null;
+               if (executionSpec.getAttributes().containsKey(parameterName)) {
+                       specAttr = executionSpec.getAttributes().get(parameterName);
+               } else {
+                       throw new SlcException("Key " + parameterName
+                                       + " is not defined in the specifications of " + toString());
+               }
+
+               if (parameters.containsKey(parameterName)) {
+                       Object paramValue = parameters.get(parameterName);
+                       return paramValue;
+               } else {
+                       if (specAttr.getValue() != null) {
+                               return specAttr.getValue();
+                       }
+               }
+               throw new SlcException("Key " + parameterName
+                               + " is not set as parameter in " + toString());
+       }
+
+       public Boolean isSetAsParameter(String key) {
+               return parameters.containsKey(key)
+                               || (executionSpec.getAttributes().containsKey(key) && executionSpec
+                                               .getAttributes().get(key).getValue() != null);
+       }
+
+       @Override
+       public String toString() {
+               return new StringBuffer("Execution flow ").append(name).toString();
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               return ((ExecutionFlow) obj).getName().equals(name);
+       }
+
+       @Override
+       public int hashCode() {
+               return name.hashCode();
+       }
+
+       public String getPath() {
+               return path;
+       }
+
+       public void setPath(String path) {
+               this.path = path;
+       }
+
+       public Boolean getFailOnError() {
+               return failOnError;
+       }
+
+       public void setFailOnError(Boolean failOnError) {
+               this.failOnError = failOnError;
+       }
+
+       public void setExecutionContext(ExecutionContext executionContext) {
+               this.executionContext = executionContext;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java
new file mode 100644 (file)
index 0000000..beac917
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.springframework.aop.scope.ScopedObject;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.util.StringUtils;
+
+/**
+ * Performs conversion in both direction between data exchanged with the agent
+ * and the data in the application context.
+ */
+public class DefaultExecutionFlowDescriptorConverter implements
+               ExecutionFlowDescriptorConverter, ApplicationContextAware {
+       public final static String REF_VALUE_TYPE_BEAN_NAME = "beanName";
+
+       /** Workaround for https://www.spartadn.com/bugzilla/show_bug.cgi?id=206 */
+       private final static String REF_VALUE_INTERNAL = "[internal]";
+
+       private final static Log log = LogFactory
+                       .getLog(DefaultExecutionFlowDescriptorConverter.class);
+
+       private ApplicationContext applicationContext;
+
+       @SuppressWarnings("unused")
+       public Map<String, Object> convertValues(
+                       ExecutionFlowDescriptor executionFlowDescriptor) {
+               Map<String, Object> values = executionFlowDescriptor.getValues();
+               Map<String, Object> convertedValues = new HashMap<String, Object>();
+               ExecutionSpec executionSpec = executionFlowDescriptor
+                               .getExecutionSpec();
+
+               if (executionSpec == null && log.isTraceEnabled())
+                       log.warn("Execution spec is null for " + executionFlowDescriptor);
+
+               if (values != null && executionSpec != null) {
+                       values: for (String key : values.keySet()) {
+                               ExecutionSpecAttribute attribute = executionSpec
+                                               .getAttributes().get(key);
+
+                               if (attribute == null)
+                                       throw new FlowConfigurationException(
+                                                       "No spec attribute defined for '" + key + "'");
+
+                               if (attribute.getIsConstant())
+                                       continue values;
+
+                               Object value = values.get(key);
+                               if (value instanceof PrimitiveValue) {
+                                       PrimitiveValue primitiveValue = (PrimitiveValue) value;
+                                       // TODO: check class <=> type
+                                       convertedValues.put(key, primitiveValue.getValue());
+                               } else if (value instanceof RefValue) {
+                                       RefValue refValue = (RefValue) value;
+                                       String type = refValue.getType();
+                                       if (REF_VALUE_TYPE_BEAN_NAME.equals(type)) {
+                                               // FIXME: UI should send all information about spec
+                                               // - targetClass
+                                               // - name
+                                               // String executionSpecName = executionSpec.getName();
+                                               // ExecutionSpec localSpec = (ExecutionSpec)
+                                               // applicationContext
+                                               // .getBean(executionSpecName);
+                                               // RefSpecAttribute localAttr = (RefSpecAttribute)
+                                               // localSpec
+                                               // .getAttributes().get(key);
+                                               // Class<?> targetClass = localAttr.getTargetClass();
+                                               //
+                                               // String primitiveType = PrimitiveUtils
+                                               // .classAsType(targetClass);
+                                               String primitiveType = null;
+                                               if (primitiveType != null) {
+                                                       // not active
+                                                       String ref = refValue.getRef();
+                                                       Object obj = PrimitiveUtils.convert(primitiveType,
+                                                                       ref);
+                                                       convertedValues.put(key, obj);
+                                               } else {
+                                                       String ref = refValue.getRef();
+                                                       if (ref != null && !ref.equals(REF_VALUE_INTERNAL)) {
+                                                               Object obj = null;
+                                                               if (applicationContext.containsBean(ref)) {
+                                                                       obj = applicationContext.getBean(ref);
+                                                               } else {
+                                                                       // FIXME: hack in order to pass primitive
+                                                                       obj = ref;
+                                                               }
+                                                               convertedValues.put(key, obj);
+                                                       } else {
+                                                               log.warn("Cannot interpret " + refValue);
+                                                       }
+                                               }
+                                       } else if (PrimitiveUtils.typeAsClass(type) != null) {
+                                               String ref = refValue.getRef();
+                                               Object obj = PrimitiveUtils.convert(type, ref);
+                                               convertedValues.put(key, obj);
+                                       } else {
+                                               throw new FlowConfigurationException(
+                                                               "Ref value type not supported: "
+                                                                               + refValue.getType());
+                                       }
+                               } else {
+                                       // default is to take the value as is
+                                       convertedValues.put(key, value);
+                               }
+                       }
+               }
+               return convertedValues;
+       }
+
+       public void addFlowsToDescriptor(ExecutionModuleDescriptor md,
+                       Map<String, ExecutionFlow> executionFlows) {
+               SortedSet<ExecutionFlowDescriptor> set = new TreeSet<ExecutionFlowDescriptor>(
+                               new ExecutionFlowDescriptorComparator());
+               for (String name : executionFlows.keySet()) {
+                       ExecutionFlow executionFlow = executionFlows.get(name);
+
+                       ExecutionFlowDescriptor efd = getExecutionFlowDescriptor(executionFlow);
+                       ExecutionSpec executionSpec = efd.getExecutionSpec();
+
+                       // Add execution spec if necessary
+                       if (!md.getExecutionSpecs().contains(executionSpec))
+                               md.getExecutionSpecs().add(executionSpec);
+
+                       // Add execution flow
+                       set.add(efd);
+                       // md.getExecutionFlows().add(efd);
+               }
+               md.getExecutionFlows().addAll(set);
+       }
+
+       public ExecutionFlowDescriptor getExecutionFlowDescriptor(
+                       ExecutionFlow executionFlow) {
+               if (executionFlow.getName() == null)
+                       throw new FlowConfigurationException("Flow name is null: "
+                                       + executionFlow);
+               String name = executionFlow.getName();
+
+               ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
+               if (executionSpec == null)
+                       throw new FlowConfigurationException("Execution spec is null: "
+                                       + executionFlow);
+               if (executionSpec.getName() == null)
+                       throw new FlowConfigurationException(
+                                       "Execution spec name is null: " + executionSpec);
+
+               Map<String, Object> values = new TreeMap<String, Object>();
+               for (String key : executionSpec.getAttributes().keySet()) {
+                       ExecutionSpecAttribute attribute = executionSpec.getAttributes()
+                                       .get(key);
+
+                       if (attribute instanceof PrimitiveSpecAttribute) {
+                               if (executionFlow.isSetAsParameter(key)) {
+                                       Object value = executionFlow.getParameter(key);
+                                       PrimitiveValue primitiveValue = new PrimitiveValue();
+                                       primitiveValue.setType(((PrimitiveSpecAttribute) attribute)
+                                                       .getType());
+                                       primitiveValue.setValue(value);
+                                       values.put(key, primitiveValue);
+                               } else {
+                                       // no need to add a primitive value if it is not set,
+                                       // all necessary information is in the spec
+                               }
+                       } else if (attribute instanceof RefSpecAttribute) {
+                               if (attribute.getIsConstant()) {
+                                       values.put(key, new RefValue(REF_VALUE_INTERNAL));
+                               } else
+                                       values.put(
+                                                       key,
+                                                       buildRefValue((RefSpecAttribute) attribute,
+                                                                       executionFlow, key));
+                       } else {
+                               throw new FlowConfigurationException(
+                                               "Unkown spec attribute type " + attribute.getClass());
+                       }
+
+               }
+
+               ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name, null,
+                               values, executionSpec);
+               // Takes description from spring
+               BeanFactory bf = getBeanFactory();
+               if (bf != null) {
+                       BeanDefinition bd = getBeanFactory().getBeanDefinition(name);
+                       efd.setDescription(bd.getDescription());
+               }
+               return efd;
+       }
+
+       protected RefValue buildRefValue(RefSpecAttribute rsa,
+                       ExecutionFlow executionFlow, String key) {
+               RefValue refValue = new RefValue();
+               // FIXME: UI should be able to deal with other types
+               refValue.setType(REF_VALUE_TYPE_BEAN_NAME);
+               Class<?> targetClass = rsa.getTargetClass();
+               String primitiveType = PrimitiveUtils.classAsType(targetClass);
+               if (primitiveType != null) {
+                       if (executionFlow.isSetAsParameter(key)) {
+                               Object value = executionFlow.getParameter(key);
+                               refValue.setRef(value.toString());
+                       }
+                       refValue.setType(primitiveType);
+                       return refValue;
+               } else {
+
+                       if (executionFlow.isSetAsParameter(key)) {
+                               String ref = null;
+                               Object value = executionFlow.getParameter(key);
+                               if (applicationContext == null) {
+                                       log.warn("No application context declared, cannot scan ref value.");
+                                       ref = value.toString();
+                               } else {
+
+                                       // look for a ref to the value
+                                       Map<String, ?> beans = getBeanFactory()
+                                                       .getBeansOfType(targetClass, false, false);
+                                       // TODO: also check scoped beans
+                                       beans: for (String beanName : beans.keySet()) {
+                                               Object obj = beans.get(beanName);
+                                               if (value instanceof ScopedObject) {
+                                                       // don't call methods of the target of the scope
+                                                       if (obj instanceof ScopedObject)
+                                                               if (value == obj) {
+                                                                       ref = beanName;
+                                                                       break beans;
+                                                               }
+                                               } else {
+                                                       if (obj.equals(value)) {
+                                                               ref = beanName;
+                                                               break beans;
+                                                       }
+                                               }
+                                       }
+                               }
+                               if (ref == null) {
+                                       if (log.isTraceEnabled())
+                                               log.trace("Cannot define reference for ref spec attribute "
+                                                               + key
+                                                               + " in "
+                                                               + executionFlow
+                                                               + " ("
+                                                               + rsa
+                                                               + ")."
+                                                               + " If it is an inner bean consider put it frozen.");
+                                       ref = REF_VALUE_INTERNAL;
+                               } else {
+                                       if (log.isTraceEnabled())
+                                               log.trace(ref
+                                                               + " is the reference for ref spec attribute "
+                                                               + key + " in " + executionFlow + " (" + rsa
+                                                               + ")");
+                               }
+                               refValue.setRef(ref);
+                       }
+                       return refValue;
+               }
+       }
+
+       /** @return can be null */
+       private ConfigurableListableBeanFactory getBeanFactory() {
+               if (applicationContext == null)
+                       return null;
+               return ((ConfigurableApplicationContext) applicationContext)
+                               .getBeanFactory();
+       }
+
+       /** Must be use within the execution application context */
+       public void setApplicationContext(ApplicationContext applicationContext)
+                       throws BeansException {
+               this.applicationContext = applicationContext;
+       }
+
+       private static class ExecutionFlowDescriptorComparator implements
+                       Comparator<ExecutionFlowDescriptor> {
+               @SuppressWarnings("deprecation")
+               public int compare(ExecutionFlowDescriptor o1,
+                               ExecutionFlowDescriptor o2) {
+                       // TODO: write unit tests for this
+
+                       String name1 = o1.getName();
+                       String name2 = o2.getName();
+
+                       String path1 = o1.getPath();
+                       String path2 = o2.getPath();
+
+                       // Check whether name include path
+                       int lastIndex1 = name1.lastIndexOf('/');
+                       // log.debug(name1+", "+lastIndex1);
+                       if (!StringUtils.hasText(path1) && lastIndex1 >= 0) {
+                               path1 = name1.substring(0, lastIndex1);
+                               name1 = name1.substring(lastIndex1 + 1);
+                       }
+
+                       int lastIndex2 = name2.lastIndexOf('/');
+                       if (!StringUtils.hasText(path2) && lastIndex2 >= 0) {
+                               path2 = name2.substring(0, lastIndex2);
+                               name2 = name2.substring(lastIndex2 + 1);
+                       }
+
+                       // Perform the actual comparison
+                       if (StringUtils.hasText(path1) && StringUtils.hasText(path2)) {
+                               if (path1.equals(path2))
+                                       return name1.compareTo(name2);
+                               else if (path1.startsWith(path2))
+                                       return -1;
+                               else if (path2.startsWith(path1))
+                                       return 1;
+                               else
+                                       return path1.compareTo(path2);
+                       } else if (!StringUtils.hasText(path1)
+                                       && StringUtils.hasText(path2)) {
+                               return 1;
+                       } else if (StringUtils.hasText(path1)
+                                       && !StringUtils.hasText(path2)) {
+                               return -1;
+                       } else if (!StringUtils.hasText(path1)
+                                       && !StringUtils.hasText(path2)) {
+                               return name1.compareTo(name2);
+                       } else {
+                               return 0;
+                       }
+               }
+
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionSpec.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionSpec.java
new file mode 100644 (file)
index 0000000..2bce125
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+
+/** Spring based implementation of execution specifications. */
+public class DefaultExecutionSpec implements ExecutionSpec, BeanNameAware,
+               ApplicationContextAware, InitializingBean, Serializable {
+       private static final long serialVersionUID = 5159882223926926539L;
+       private final static Log log = LogFactory
+                       .getLog(DefaultExecutionSpec.class);
+       private transient ApplicationContext applicationContext;
+
+       private String description;
+       private Map<String, ExecutionSpecAttribute> attributes = new HashMap<String, ExecutionSpecAttribute>();
+
+       private String name = INTERNAL_NAME;
+
+       public Map<String, ExecutionSpecAttribute> getAttributes() {
+               return attributes;
+       }
+
+       public void setAttributes(Map<String, ExecutionSpecAttribute> attributes) {
+               this.attributes = attributes;
+       }
+
+       public void setBeanName(String name) {
+               this.name = name;
+       }
+
+       /**
+        * The Spring bean name (only relevant for specs declared has high-level
+        * beans)
+        */
+       public String getName() {
+               return name;
+       }
+
+       public boolean equals(Object obj) {
+               return ((ExecutionSpec) obj).getName().equals(name);
+       }
+
+       /**
+        * The Spring bean description (only relevant for specs declared has
+        * high-level beans)
+        */
+       public String getDescription() {
+               return description;
+       }
+
+       private ConfigurableListableBeanFactory getBeanFactory() {
+               return ((ConfigurableApplicationContext) applicationContext)
+                               .getBeanFactory();
+       }
+
+       public void setApplicationContext(ApplicationContext applicationContext) {
+               this.applicationContext = applicationContext;
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               if (description == null) {
+                       try {
+                               description = getBeanFactory().getBeanDefinition(name)
+                                               .getDescription();
+                       } catch (NoSuchBeanDefinitionException e) {
+                               // silent
+                       }
+               }
+
+               for (String key : attributes.keySet()) {
+                       ExecutionSpecAttribute attr = attributes.get(key);
+                       if (attr instanceof RefSpecAttribute) {
+                               RefSpecAttribute rsa = (RefSpecAttribute) attr;
+                               if (rsa.getChoices() == null) {
+                                       List<RefValueChoice> choices = buildRefValueChoices(rsa);
+                                       rsa.setChoices(choices);
+                               }
+                               if (log.isTraceEnabled())
+                                       log.debug("Spec attr " + key + " has "
+                                                       + rsa.getChoices().size() + " choices");
+                       }
+               }
+       }
+
+       /**
+        * Generates a list of ref value choices based on the bean available in the
+        * application ocntext.
+        */
+       protected List<RefValueChoice> buildRefValueChoices(RefSpecAttribute rsa) {
+               List<RefValueChoice> choices = new ArrayList<RefValueChoice>();
+               if (applicationContext == null) {
+                       log.warn("No application context declared,"
+                                       + " cannot scan ref value choices.");
+                       return choices;
+               }
+
+               beanNames: for (String beanName : getBeanFactory().getBeanNamesForType(
+                               rsa.getTargetClass(), true, false)) {
+
+                       // Since Spring 3, systemProperties is implicitly defined but has no
+                       // bean definition
+                       if (beanName.equals("systemProperties"))
+                               continue beanNames;
+
+                       BeanDefinition bd = getBeanFactory().getBeanDefinition(beanName);
+                       RefValueChoice choice = new RefValueChoice();
+                       choice.setName(beanName);
+                       choice.setDescription(bd.getDescription());
+                       if (log.isTraceEnabled())
+                               log.debug("Found choice " + beanName + " for " + rsa);
+
+                       choices.add(choice);
+
+               }
+               return choices;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionStack.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultExecutionStack.java
new file mode 100644 (file)
index 0000000..d1d06c6
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+import java.util.UUID;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.argeo.slc.execution.ExecutionStack;
+
+/** Canonical implementation of an execution stack. */
+public class DefaultExecutionStack implements ExecutionStack {
+
+       private final static Log log = LogFactory
+                       .getLog(DefaultExecutionStack.class);
+
+       private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
+
+       public synchronized void enterFlow(ExecutionFlow executionFlow) {
+               ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
+               stack.push(runtime);
+
+               Map<String, ExecutionSpecAttribute> specAttrs = executionFlow
+                               .getExecutionSpec().getAttributes();
+               for (String key : specAttrs.keySet()) {
+                       if (executionFlow.isSetAsParameter(key)) {
+                               runtime.getLocalVariables().put(key,
+                                               executionFlow.getParameter(key));
+                       }
+               }
+       }
+
+       public synchronized String getCurrentStackLevelUuid() {
+               return stack.peek().getUuid();
+       }
+
+       public synchronized Integer getStackSize() {
+               return stack.size();
+       }
+
+       /**
+        * Looks for a set variable in the stack, starting at the upper flows
+        * 
+        * @return the variable or <code>null</code> if not found
+        */
+       public synchronized Object findLocalVariable(String key) {
+               Object obj = null;
+               for (int i = 0; i < stack.size(); i++) {
+                       if (stack.get(i).getLocalVariables().containsKey(key)) {
+                               obj = stack.get(i).getLocalVariables().get(key);
+                               break;
+                       }
+               }
+               return obj;
+       }
+
+       public synchronized void leaveFlow(ExecutionFlow executionFlow) {
+               ExecutionFlowRuntime leftEf = stack.pop();
+
+               if (!leftEf.getExecutionFlow().getName()
+                               .equals(executionFlow.getName()))
+                       throw new SlcException("Asked to leave " + executionFlow
+                                       + " but last is " + leftEf);
+
+               leftEf.getScopedObjects().clear();
+               leftEf.getLocalVariables().clear();
+       }
+
+       public synchronized void addScopedObject(String name, Object obj) {
+               ExecutionFlowRuntime runtime = stack.peek();
+               // TODO: check that the object is not set yet ?
+               if (log.isDebugEnabled()) {
+                       Object existing = findScopedObject(name);
+                       if (existing != null)
+                               log.warn("Scoped object " + name + " of type " + obj.getClass()
+                                               + " already registered in " + runtime);
+               }
+               runtime.getScopedObjects().put(name, obj);
+       }
+
+       /** @return </code>null<code> if not found */
+       public synchronized Object findScopedObject(String name) {
+               Object obj = null;
+               for (int i = stack.size() - 1; i >= 0; i--) {
+                       if (stack.get(i).getScopedObjects().containsKey(name)) {
+                               obj = stack.get(i).getScopedObjects().get(name);
+                               break;
+                       }
+               }
+               return obj;
+       }
+
+       protected static class ExecutionFlowRuntime {
+               private final ExecutionFlow executionFlow;
+               private final Map<String, Object> scopedObjects = new HashMap<String, Object>();
+               private final Map<String, Object> localVariables = new HashMap<String, Object>();
+               private final String uuid = UUID.randomUUID().toString();
+
+               public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
+                       this.executionFlow = executionFlow;
+               }
+
+               public ExecutionFlow getExecutionFlow() {
+                       return executionFlow;
+               }
+
+               public Map<String, Object> getScopedObjects() {
+                       return scopedObjects;
+               }
+
+               public String getUuid() {
+                       return uuid;
+               }
+
+               public Map<String, Object> getLocalVariables() {
+                       return localVariables;
+               }
+
+               @Override
+               public String toString() {
+                       return "Stack Level #" + uuid;
+               }
+
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultProcess.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/DefaultProcess.java
new file mode 100644 (file)
index 0000000..3021180
--- /dev/null
@@ -0,0 +1,55 @@
+package org.argeo.slc.core.execution;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.ExecutionStep;
+import org.argeo.slc.execution.RealizedFlow;
+
+/** Canonical implementation of an {@link ExecutionProcess} as a bean. */
+public class DefaultProcess implements ExecutionProcess {
+       private String uuid = UUID.randomUUID().toString();
+       private String status = ExecutionProcess.NEW;
+
+       private List<ExecutionStep> steps = new ArrayList<ExecutionStep>();
+       private List<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();
+
+       public String getUuid() {
+               return uuid;
+       }
+
+       public String getStatus() {
+               return status;
+       }
+
+       public void setStatus(String status) {
+               this.status = status;
+       }
+
+       public void addSteps(List<ExecutionStep> steps) {
+               steps.addAll(steps);
+       }
+
+       public List<RealizedFlow> getRealizedFlows() {
+               return realizedFlows;
+       }
+
+       public List<ExecutionStep> getSteps() {
+               return steps;
+       }
+
+       public void setSteps(List<ExecutionStep> steps) {
+               this.steps = steps;
+       }
+
+       public void setUuid(String uuid) {
+               this.uuid = uuid;
+       }
+
+       public void setRealizedFlows(List<RealizedFlow> realizedFlows) {
+               this.realizedFlows = realizedFlows;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionAspect.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionAspect.java
new file mode 100644 (file)
index 0000000..b50b78f
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionStack;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+
+@Aspect
+/** Aspect intercepting calls on execution flows and contexts. */
+public class ExecutionAspect {
+       private final static Log log = LogFactory.getLog(ExecutionAspect.class);
+
+       private ExecutionStack executionStack;
+       private ExecutionContext executionContext;
+
+       @Around("flowExecution()")
+       public void aroundFlow(ProceedingJoinPoint pjp) throws Throwable {
+               // IMPORTANT: Make sure that the execution context is called before the
+               // execution stack
+               executionContext.getUuid();
+
+               ExecutionFlow executionFlow = (ExecutionFlow) pjp.getTarget();
+               executionStack.enterFlow(executionFlow);
+               executionContext.setVariable(ExecutionContext.VAR_FLOW_ID,
+                               executionStack.getCurrentStackLevelUuid());
+               executionContext.setVariable(ExecutionContext.VAR_FLOW_NAME,
+                               executionFlow.getName());
+
+               logStackEvent("=> ", executionFlow);
+               try {
+                       // Actually execute the flow
+                       pjp.proceed();
+               } finally {
+                       logStackEvent("<= ", executionFlow);
+                       executionStack.leaveFlow(executionFlow);
+               }
+       }
+
+       @Around("getVariable()")
+       public Object aroundGetVariable(ProceedingJoinPoint pjp) throws Throwable {
+               Object obj = pjp.proceed();
+               // if the variable was not found, look in the stack starting at the
+               // upper flows
+               if (obj == null) {
+                       String key = pjp.getArgs()[0].toString();
+                       obj = executionStack.findLocalVariable(key);
+               }
+               return obj;
+       }
+
+       @Pointcut("execution(void org.argeo.slc.execution.ExecutionFlow.run())")
+       public void flowExecution() {
+       }
+
+       @Pointcut("execution(* org.argeo.slc.execution.ExecutionContext.getVariable(..))")
+       public void getVariable() {
+       }
+
+       public void setExecutionStack(ExecutionStack executionStack) {
+               this.executionStack = executionStack;
+       }
+
+       public void setExecutionContext(ExecutionContext executionContext) {
+               this.executionContext = executionContext;
+       }
+
+       protected void logStackEvent(String symbol, ExecutionFlow executionFlow) {
+               Integer stackSize = executionStack.getStackSize();
+               if (log.isTraceEnabled())
+                       log.debug(depthSpaces(stackSize) + symbol + executionFlow + " #"
+                                       + executionStack.getCurrentStackLevelUuid() + ", depth="
+                                       + stackSize);
+               if (log.isDebugEnabled())
+                       log.debug(depthSpaces(stackSize) + symbol + executionFlow);
+       }
+
+       protected void logRunnableExecution(ExecutionFlow executionFlow,
+                       Runnable runnable) {
+               Integer stackSize = executionStack.getStackSize();
+               if (log.isDebugEnabled())
+                       log.debug(depthSpaces(stackSize + 1)
+                                       + runnable.getClass().getSimpleName() + " in "
+                                       + executionFlow);
+       }
+
+       private String depthSpaces(int depth) {
+               StringBuffer buf = new StringBuffer(depth * 2);
+               for (int i = 0; i < depth; i++)
+                       buf.append("  ");
+               return buf.toString();
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionParameterPostProcessor.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionParameterPostProcessor.java
new file mode 100644 (file)
index 0000000..84c932e
--- /dev/null
@@ -0,0 +1,307 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution;\r
+\r
+import java.beans.PropertyDescriptor;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.execution.ExecutionContext;\r
+import org.argeo.slc.execution.ExecutionFlow;\r
+import org.springframework.beans.BeansException;\r
+import org.springframework.beans.MutablePropertyValues;\r
+import org.springframework.beans.PropertyValue;\r
+import org.springframework.beans.PropertyValues;\r
+import org.springframework.beans.factory.BeanDefinitionStoreException;\r
+import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;\r
+import org.springframework.beans.factory.config.TypedStringValue;\r
+import org.springframework.beans.factory.support.ManagedList;\r
+import org.springframework.beans.factory.support.ManagedMap;\r
+import org.springframework.beans.factory.support.ManagedSet;\r
+import org.springframework.util.ObjectUtils;\r
+import org.springframework.util.StringUtils;\r
+\r
+/**\r
+ * Spring post processor which ensures that execution parameters are properly\r
+ * set. It is used at two levels: first during instantiation for instantiation\r
+ * parameters which allow to implement templates, then at runtime in order to\r
+ * interpret @{} placeholders when object of scope execution are instantiated.\r
+ */\r
+public class ExecutionParameterPostProcessor extends\r
+               InstantiationAwareBeanPostProcessorAdapter {\r
+\r
+       private final static Log log = LogFactory\r
+                       .getLog(ExecutionParameterPostProcessor.class);\r
+\r
+       private ExecutionContext executionContext;\r
+       private InstantiationManager instantiationManager;\r
+\r
+       private String placeholderPrefix = "@{";\r
+       private String placeholderSuffix = "}";\r
+       private String nullValue;\r
+\r
+       @Override\r
+       public PropertyValues postProcessPropertyValues(PropertyValues pvs,\r
+                       PropertyDescriptor[] pds, Object bean, String beanName)\r
+                       throws BeansException {\r
+\r
+               // TODO: resolve at execution only if scope is execution\r
+               // TODO: deal with placeholders in RuntimeBeanReference and\r
+               // RuntimeBeanNameReference\r
+\r
+               MutablePropertyValues newPvs = new MutablePropertyValues();\r
+\r
+               boolean changesOccured = false;\r
+\r
+               for (PropertyValue pv : pvs.getPropertyValues()) {\r
+                       Object convertedValue = resolveValue(beanName, bean, pv.getValue());\r
+                       newPvs.addPropertyValue(new PropertyValue(pv, convertedValue));\r
+                       if (convertedValue != pv.getValue()) {\r
+                               changesOccured = true;\r
+                       }\r
+               }\r
+\r
+               return changesOccured ? newPvs : pvs;\r
+       }\r
+\r
+       @Override\r
+       public boolean postProcessAfterInstantiation(Object bean, String beanName)\r
+                       throws BeansException {\r
+               if (bean instanceof ExecutionFlow)\r
+                       instantiationManager.flowInitializationStarted(\r
+                                       (ExecutionFlow) bean, beanName);\r
+               return true;\r
+       }\r
+\r
+       @Override\r
+       public Object postProcessAfterInitialization(Object bean, String beanName)\r
+                       throws BeansException {\r
+               if (bean instanceof ExecutionFlow)\r
+                       instantiationManager.flowInitializationFinished(\r
+                                       (ExecutionFlow) bean, beanName);\r
+               return bean;\r
+       }\r
+\r
+       protected String resolvePlaceholder(Object bean, String placeholder) {\r
+               if (instantiationManager.isInFlowInitialization())\r
+                       return instantiationManager.getInitializingFlowParameter(\r
+                                       placeholder).toString();\r
+\r
+               else {// execution\r
+                               // next call fail if no execution context available\r
+                       Object obj = executionContext.getVariable(placeholder);\r
+                       if (obj != null) {\r
+                               return obj.toString();\r
+                       }\r
+               }\r
+\r
+               return null;\r
+       }\r
+\r
+       public Object resolveValue(String beanName, Object bean, Object value) {\r
+               if (value instanceof TypedStringValue) {\r
+                       TypedStringValue tsv = (TypedStringValue) value;\r
+                       String originalValue = tsv.getValue();\r
+\r
+                       String convertedValue = resolveString(beanName, bean, originalValue);\r
+                       if (convertedValue == null)\r
+                               return null;\r
+                       return convertedValue.equals(originalValue) ? value\r
+                                       : new TypedStringValue(convertedValue);\r
+               } else if (value instanceof String) {\r
+                       String originalValue = value.toString();\r
+                       String convertedValue = resolveString(beanName, bean, originalValue);\r
+                       if (convertedValue == null)\r
+                               return null;\r
+                       return convertedValue.equals(originalValue) ? value\r
+                                       : convertedValue;\r
+               } else if (value instanceof ManagedMap) {\r
+                       Map<?, ?> mapVal = (Map<?, ?>) value;\r
+\r
+                       Map<Object, Object> newContent = new ManagedMap<Object, Object>();\r
+                       boolean entriesModified = false;\r
+                       for (Iterator<?> it = mapVal.entrySet().iterator(); it.hasNext();) {\r
+                               Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next();\r
+                               Object key = entry.getKey();\r
+                               int keyHash = (key != null ? key.hashCode() : 0);\r
+                               Object newKey = resolveValue(beanName, bean, key);\r
+                               int newKeyHash = (newKey != null ? newKey.hashCode() : 0);\r
+                               Object val = entry.getValue();\r
+                               Object newVal = resolveValue(beanName, bean, val);\r
+                               newContent.put(newKey, newVal);\r
+                               entriesModified = entriesModified\r
+                                               || (newVal != val || newKey != key || newKeyHash != keyHash);\r
+                       }\r
+\r
+                       return entriesModified ? newContent : value;\r
+               } else if (value instanceof ManagedList) {\r
+                       List<?> listVal = (List<?>) value;\r
+                       List<Object> newContent = new ManagedList<Object>();\r
+                       boolean valueModified = false;\r
+\r
+                       for (int i = 0; i < listVal.size(); i++) {\r
+                               Object elem = listVal.get(i);\r
+                               Object newVal = resolveValue(beanName, bean, elem);\r
+                               newContent.add(newVal);\r
+                               if (!ObjectUtils.nullSafeEquals(newVal, elem)) {\r
+                                       valueModified = true;\r
+                               }\r
+                       }\r
+                       return valueModified ? newContent : value;\r
+               } else if (value instanceof ManagedSet) {\r
+                       Set<?> setVal = (Set<?>) value;\r
+                       Set<Object> newContent = new ManagedSet<Object>();\r
+                       boolean entriesModified = false;\r
+                       for (Iterator<?> it = setVal.iterator(); it.hasNext();) {\r
+                               Object elem = it.next();\r
+                               int elemHash = (elem != null ? elem.hashCode() : 0);\r
+                               Object newVal = resolveValue(beanName, bean, elem);\r
+                               int newValHash = (newVal != null ? newVal.hashCode() : 0);\r
+                               newContent.add(newVal);\r
+                               entriesModified = entriesModified\r
+                                               || (newVal != elem || newValHash != elemHash);\r
+                       }\r
+                       return entriesModified ? newContent : value;\r
+               } else {\r
+                       // log.debug(beanName + ": " + value.getClass() + " : " + value);\r
+                       return value;\r
+               }\r
+\r
+       }\r
+\r
+       private String resolveString(String beanName, Object bean, String strVal) {\r
+               // in case <null/> is passed\r
+               if (strVal == null)\r
+                       return null;\r
+\r
+               String value = parseStringValue(bean, strVal, new HashSet<String>());\r
+\r
+               if (value == null)\r
+                       throw new SlcException("Could not resolve placeholder '" + strVal\r
+                                       + "' in bean '" + beanName + "'");\r
+\r
+               return (value.equals(nullValue) ? null : value);\r
+       }\r
+\r
+       public void setPlaceholderPrefix(String placeholderPrefix) {\r
+               this.placeholderPrefix = placeholderPrefix;\r
+       }\r
+\r
+       public void setPlaceholderSuffix(String placeholderSuffix) {\r
+               this.placeholderSuffix = placeholderSuffix;\r
+       }\r
+\r
+       public void setNullValue(String nullValue) {\r
+               this.nullValue = nullValue;\r
+       }\r
+\r
+       public void setInstantiationManager(\r
+                       InstantiationManager instantiationManager) {\r
+               this.instantiationManager = instantiationManager;\r
+       }\r
+\r
+       public void setExecutionContext(ExecutionContext executionContext) {\r
+               this.executionContext = executionContext;\r
+       }\r
+\r
+       //\r
+       // Following methods hacked from the internals of\r
+       // PropertyPlaceholderConfigurer\r
+       //\r
+\r
+       protected String parseStringValue(Object bean, String strVal,\r
+                       Set<String> visitedPlaceholders)\r
+                       throws BeanDefinitionStoreException {\r
+\r
+               // in case <null/> is passed\r
+               if (strVal == null)\r
+                       return null;\r
+\r
+               StringBuffer buf = new StringBuffer(strVal);\r
+\r
+               int startIndex = strVal.indexOf(placeholderPrefix);\r
+               while (startIndex != -1) {\r
+                       int endIndex = findPlaceholderEndIndex(buf, startIndex);\r
+                       if (endIndex != -1) {\r
+                               String placeholder = buf.substring(startIndex\r
+                                               + placeholderPrefix.length(), endIndex);\r
+                               if (!visitedPlaceholders.add(placeholder)) {\r
+                                       throw new BeanDefinitionStoreException(\r
+                                                       "Circular placeholder reference '" + placeholder\r
+                                                                       + "' in property definitions");\r
+                               }\r
+                               // Recursive invocation, parsing placeholders contained in\r
+                               // the placeholder key.\r
+                               placeholder = parseStringValue(bean, placeholder,\r
+                                               visitedPlaceholders);\r
+                               // Now obtain the value for the fully resolved key...\r
+                               String propVal = resolvePlaceholder(bean, placeholder);\r
+                               if (propVal != null) {\r
+                                       // Recursive invocation, parsing placeholders contained\r
+                                       // in the\r
+                                       // previously resolved placeholder value.\r
+                                       propVal = parseStringValue(bean, propVal,\r
+                                                       visitedPlaceholders);\r
+                                       buf.replace(startIndex,\r
+                                                       endIndex + placeholderSuffix.length(), propVal);\r
+                                       if (log.isTraceEnabled()) {\r
+                                               log.trace("Resolved placeholder '" + placeholder + "'");\r
+                                       }\r
+                                       startIndex = buf.indexOf(placeholderPrefix, startIndex\r
+                                                       + propVal.length());\r
+                               } else {\r
+                                       throw new BeanDefinitionStoreException(\r
+                                                       "Could not resolve placeholder '" + placeholder\r
+                                                                       + "'");\r
+                               }\r
+                               visitedPlaceholders.remove(placeholder);\r
+                       } else {\r
+                               startIndex = -1;\r
+                       }\r
+               }\r
+\r
+               return buf.toString();\r
+       }\r
+\r
+       private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {\r
+               int index = startIndex + placeholderPrefix.length();\r
+               int withinNestedPlaceholder = 0;\r
+               while (index < buf.length()) {\r
+                       if (StringUtils.substringMatch(buf, index, placeholderSuffix)) {\r
+                               if (withinNestedPlaceholder > 0) {\r
+                                       withinNestedPlaceholder--;\r
+                                       index = index + placeholderSuffix.length();\r
+                               } else {\r
+                                       return index;\r
+                               }\r
+                       } else if (StringUtils\r
+                                       .substringMatch(buf, index, placeholderPrefix)) {\r
+                               withinNestedPlaceholder++;\r
+                               index = index + placeholderPrefix.length();\r
+                       } else {\r
+                               index++;\r
+                       }\r
+               }\r
+               return -1;\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionResources.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionResources.java
new file mode 100644 (file)
index 0000000..759a125
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+
+import org.springframework.core.io.Resource;
+
+/** Provides write access to resources during execution */
+public interface ExecutionResources {
+       /** The base directory where this execution can write */
+       public File getWritableBaseDir();
+
+       /** Allocates a local file in the writable area and return it as a resource. */
+       public Resource getWritableResource(String relativePath);
+
+       /**
+        * Allocates a local file in the writable area and return it as a fully
+        * qualified OS path.
+        */
+       public String getWritableOsPath(String relativePath);
+
+       /**
+        * Allocates a local file in the writable area and return it as a
+        * {@link File}.
+        */
+       public File getWritableOsFile(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/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionResourcesFactoryBean.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionResourcesFactoryBean.java
new file mode 100644 (file)
index 0000000..0b887da
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.core.io.Resource;
+import org.springframework.util.Assert;
+
+/** Workaround when execution placedholders needs to be passed. */
+public class ExecutionResourcesFactoryBean implements FactoryBean<Resource> {
+       private ExecutionResources executionResources;
+       private String relativePath;
+
+       public Resource getObject() throws Exception {
+               Assert.notNull(executionResources, "executionResources is null");
+               Assert.notNull(relativePath, "relativePath is null");
+               return executionResources.getWritableResource(relativePath);
+       }
+
+       public Class<? extends Object> getObjectType() {
+               return Resource.class;
+       }
+
+       public boolean isSingleton() {
+               return true;
+       }
+
+       public void setExecutionResources(ExecutionResources executionResources) {
+               this.executionResources = executionResources;
+       }
+
+       public void setRelativePath(String relativePath) {
+               this.relativePath = relativePath;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionScope.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionScope.java
new file mode 100644 (file)
index 0000000..4ac0de2
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+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.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionStack;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.beans.factory.config.Scope;
+
+/**
+ * When Spring beans are instantiated with this scope, the same instance is
+ * reused across an execution.
+ */
+public class ExecutionScope implements Scope {
+       private final static Log log = LogFactory.getLog(ExecutionScope.class);
+
+       private final ThreadLocal<ExecutionStack> executionStack = new ThreadLocal<ExecutionStack>();
+       public final ThreadLocal<String> executionStackBeanName = new ThreadLocal<String>();
+
+       private final ThreadLocal<ExecutionContext> executionContext = new ThreadLocal<ExecutionContext>();
+       private final ThreadLocal<String> executionContextBeanName = new ThreadLocal<String>();
+
+       public Object get(String name, ObjectFactory<?> objectFactory) {
+               if (log.isTraceEnabled())
+                       log.debug("Get execution scoped bean " + name);
+
+               // shortcuts
+               if (executionStackBeanName.get() != null
+                               && name.equals(executionStackBeanName.get())) {
+                       return executionStack.get();
+               }
+
+               if (executionContextBeanName.get() != null
+                               && name.equals(executionContextBeanName.get())) {
+                       return executionContext.get();
+               }
+
+               // execution context must be defined first
+               if (executionContext.get() == null) {
+                       Object obj = objectFactory.getObject();
+                       if (obj instanceof ExecutionContext) {
+                               return dealWithSpecialScopedObject(name, executionContext,
+                                               executionContextBeanName, (ExecutionContext) obj);
+                       } else {
+                               // TODO: use execution context wrapper
+                               throw new SlcException("No execution context has been defined.");
+                       }
+               }
+
+               // for other scoped objects, an executions stack must be available
+               if (executionStack.get() == null) {
+                       Object obj = objectFactory.getObject();
+                       if (obj instanceof ExecutionStack) {
+                               return dealWithSpecialScopedObject(name, executionStack,
+                                               executionStackBeanName, (ExecutionStack) obj);
+                       } else {
+                               throw new SlcException("No execution stack has been defined.");
+                       }
+               }
+
+               // see if the execution stack already knows the object
+               Object obj = executionStack.get().findScopedObject(name);
+               if (obj == null) {
+                       obj = objectFactory.getObject();
+                       if (obj instanceof ExecutionContext)
+                               throw new SlcException(
+                                               "Only one execution context can be defined per thread");
+                       if (obj instanceof ExecutionStack)
+                               throw new SlcException(
+                                               "Only one execution stack can be defined per thread");
+
+                       checkForbiddenClasses(obj);
+
+                       executionStack.get().addScopedObject(name, obj);
+               }
+               return obj;
+
+       }
+
+       protected <T> T dealWithSpecialScopedObject(String name,
+                       ThreadLocal<T> threadLocal,
+                       ThreadLocal<String> threadLocalBeanName, T newObj) {
+
+               T obj = threadLocal.get();
+               if (obj == null) {
+                       obj = newObj;
+                       threadLocal.set(obj);
+                       threadLocalBeanName.set(name);
+                       if (log.isTraceEnabled()) {
+                               log.debug(obj.getClass() + " instantiated. (beanName=" + name
+                                               + ")");
+                       }
+                       return obj;
+               } else {
+                       throw new SlcException("Only one scoped " + obj.getClass()
+                                       + " can be defined per thread");
+               }
+
+       }
+
+       protected void checkForbiddenClasses(Object obj) {
+               Class<?> clss = obj.getClass();
+               if (ExecutionFlow.class.isAssignableFrom(clss)
+                               || ExecutionSpec.class.isAssignableFrom(clss)) {
+                       throw new UnsupportedException("Execution scoped object", clss);
+               }
+       }
+
+       public String getConversationId() {
+               // TODO: is it the most relevant?
+               return executionContext.get().getUuid();
+       }
+
+       public void registerDestructionCallback(String name, Runnable callback) {
+               if (Thread.currentThread() instanceof ExecutionThread) {
+                       ExecutionThread executionThread = (ExecutionThread) Thread
+                                       .currentThread();
+                       executionThread.registerDestructionCallback(name, callback);
+               }
+       }
+
+       public Object remove(String name) {
+               if (log.isDebugEnabled())
+                       log.debug("Remove object " + name);
+               throw new UnsupportedOperationException();
+       }
+
+       public Object resolveContextualObject(String key) {
+               return executionContext.get().getVariable(key);
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionThread.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ExecutionThread.java
new file mode 100644 (file)
index 0000000..31e952d
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.security.auth.Subject;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionStep;
+import org.argeo.slc.execution.RealizedFlow;
+
+/** Thread of a single execution */
+public class ExecutionThread extends Thread {
+       public final static String SYSPROP_EXECUTION_AUTO_UPGRADE = "slc.execution.autoupgrade";
+       private final static Log log = LogFactory.getLog(ExecutionThread.class);
+
+       private ExecutionModulesManager executionModulesManager;
+       private final RealizedFlow realizedFlow;
+       private final AccessControlContext accessControlContext;
+
+       private List<Runnable> destructionCallbacks = new ArrayList<Runnable>();
+
+       public ExecutionThread(ProcessThreadGroup processThreadGroup, ExecutionModulesManager executionModulesManager,
+                       RealizedFlow realizedFlow) {
+               super(processThreadGroup, "Flow " + realizedFlow.getFlowDescriptor().getName());
+               this.realizedFlow = realizedFlow;
+               this.executionModulesManager = executionModulesManager;
+               accessControlContext = AccessController.getContext();
+       }
+
+       public void run() {
+               // authenticate thread
+               // Authentication authentication = getProcessThreadGroup()
+               // .getAuthentication();
+               // if (authentication == null)
+               // throw new SlcException("Can only execute authenticated threads");
+               // SecurityContextHolder.getContext().setAuthentication(authentication);
+
+               // Retrieve execution flow descriptor
+               ExecutionFlowDescriptor executionFlowDescriptor = realizedFlow.getFlowDescriptor();
+               String flowName = executionFlowDescriptor.getName();
+
+               getProcessThreadGroup().dispatchAddStep(
+                               new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.PHASE_START, "Flow " + flowName));
+
+               try {
+                       Subject subject = Subject.getSubject(accessControlContext);
+                       try {
+                               Subject.doAs(subject, new PrivilegedExceptionAction<Void>() {
+
+                                       @Override
+                                       public Void run() throws Exception {
+                                               String autoUpgrade = System.getProperty(SYSPROP_EXECUTION_AUTO_UPGRADE);
+                                               if (autoUpgrade != null && autoUpgrade.equals("true"))
+                                                       executionModulesManager.upgrade(realizedFlow.getModuleNameVersion());
+                                               executionModulesManager.start(realizedFlow.getModuleNameVersion());
+                                               //
+                                               // START FLOW
+                                               //
+                                               executionModulesManager.execute(realizedFlow);
+                                               // END FLOW
+                                               return null;
+                                       }
+
+                               });
+                       } catch (PrivilegedActionException privilegedActionException) {
+                               throw (Exception) privilegedActionException.getCause();
+                       }
+               } catch (FlowConfigurationException e) {
+                       String msg = "Configuration problem with flow " + flowName + ":\n" + e.getMessage();
+                       log.error(msg);
+                       getProcessThreadGroup().dispatchAddStep(
+                                       new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.ERROR, msg + " " + e.getMessage()));
+               } catch (Exception e) {
+                       // TODO: re-throw exception ?
+                       String msg = "Execution of flow " + flowName + " failed.";
+                       log.error(msg, e);
+                       getProcessThreadGroup().dispatchAddStep(
+                                       new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.ERROR, msg + " " + e.getMessage()));
+               } finally {
+                       getProcessThreadGroup().dispatchAddStep(
+                                       new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.PHASE_END, "Flow " + flowName));
+                       processDestructionCallbacks();
+               }
+       }
+
+       private synchronized void processDestructionCallbacks() {
+               for (int i = destructionCallbacks.size() - 1; i >= 0; i--) {
+                       try {
+                               destructionCallbacks.get(i).run();
+                       } catch (Exception e) {
+                               log.warn("Could not process destruction callback " + i + " in thread " + getName(), e);
+                       }
+               }
+       }
+
+       /**
+        * Gather object destruction callback to be called in reverse order at the
+        * end of the thread
+        */
+       synchronized void registerDestructionCallback(String name, Runnable callback) {
+               destructionCallbacks.add(callback);
+       }
+
+       protected ProcessThreadGroup getProcessThreadGroup() {
+               return (ProcessThreadGroup) getThreadGroup();
+       }
+}
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/FileExecutionResources.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/FileExecutionResources.java
new file mode 100644 (file)
index 0000000..d225cd1
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionContext;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.Resource;
+import org.springframework.util.Assert;
+
+/** Implements write access to resources based on standard Java {@link File} */
+public class FileExecutionResources implements ExecutionResources {
+       private final static Log log = LogFactory
+                       .getLog(FileExecutionResources.class);
+       protected final static String DEFAULT_EXECUTION_RESOURCES_DIRNAME = "executionResources";
+       public final static String DEFAULT_EXECUTION_RESOURCES_TMP_PATH = System
+                       .getProperty("java.io.tmpdir")
+                       + File.separator
+                       + System.getProperty("user.name")
+                       + File.separator
+                       + "slc"
+                       + File.separator + DEFAULT_EXECUTION_RESOURCES_DIRNAME;
+
+       private File baseDir;
+       private ExecutionContext executionContext;
+       private String prefixDatePattern = "yyMMdd_HHmmss_SSS";
+       private SimpleDateFormat sdf = null;
+
+       private Boolean withExecutionSubdirectory = true;
+
+       public FileExecutionResources() {
+               // Default base directory
+               String osgiInstanceArea = System.getProperty("osgi.instance.area");
+               String osgiInstanceAreaDefault = System
+                               .getProperty("osgi.instance.area.default");
+
+               if (osgiInstanceArea != null) {
+                       // within OSGi with -data specified
+                       osgiInstanceArea = removeFilePrefix(osgiInstanceArea);
+                       baseDir = new File(osgiInstanceArea + File.separator
+                                       + DEFAULT_EXECUTION_RESOURCES_DIRNAME);
+               } else if (osgiInstanceAreaDefault != null) {
+                       // within OSGi without -data specified
+                       osgiInstanceAreaDefault = removeFilePrefix(osgiInstanceAreaDefault);
+                       baseDir = new File(osgiInstanceAreaDefault + File.separator
+                                       + DEFAULT_EXECUTION_RESOURCES_DIRNAME);
+               } else {// outside OSGi
+                       baseDir = new File(DEFAULT_EXECUTION_RESOURCES_TMP_PATH);
+               }
+       }
+
+       protected SimpleDateFormat sdf() {
+               // Lazy init in case prefix has been externally set
+               if (sdf == null)
+                       sdf = new SimpleDateFormat(prefixDatePattern);
+               return sdf;
+       }
+
+       public Resource getWritableResource(String relativePath) {
+               File file = getFile(relativePath);
+               File parentDir = file.getParentFile();
+
+               if (!parentDir.exists()) {
+                       // Creates if necessary
+                       if (log.isTraceEnabled())
+                               log.trace("Creating parent directory " + parentDir);
+                       parentDir.mkdirs();
+               }
+               Resource resource = new FileSystemResource(file);
+
+               if (log.isTraceEnabled())
+                       log.trace("Returns writable resource " + resource);
+               return resource;
+       }
+
+       public String getWritableOsPath(String relativePath) {
+               try {
+                       return getFile(relativePath).getCanonicalPath();
+               } catch (IOException e) {
+                       throw new SlcException("Cannot find canonical path", e);
+               }
+       }
+
+       public File getWritableOsFile(String relativePath) {
+               return getFile(relativePath);
+       }
+
+       public String getAsOsPath(Resource resource, Boolean overwrite) {
+               File file = fileFromResource(resource);
+               if (file != null)
+                       try {
+                               if (log.isTraceEnabled())
+                                       log.debug("Directly interpret " + resource + " as OS file "
+                                                       + file);
+                               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;
+               try {
+                       String path = resource.getURL().getPath();
+                       file = getFile(path);
+                       if (file.exists() && !overwrite)
+                               return file.getCanonicalPath();
+
+                       file.getParentFile().mkdirs();
+                       in = resource.getInputStream();
+                       out = new FileOutputStream(file);
+                       IOUtils.copy(in, out);
+                       if (log.isDebugEnabled())
+                               log.debug("Retrieved " + resource + " to OS file " + file);
+                       return file.getCanonicalPath();
+               } catch (IOException e) {
+                       throw new SlcException("Could not make resource " + resource
+                                       + " an OS file.", e);
+               } finally {
+                       IOUtils.closeQuietly(in);
+                       IOUtils.closeQuietly(out);
+               }
+       }
+
+       /**
+        * 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;
+               }
+
+       }
+
+       protected File getFile(String relativePath) {
+               File writableBaseDir = getWritableBaseDir();
+               return new File(writableBaseDir.getPath() + File.separator
+                               + relativePath.replace('/', File.separatorChar));
+       }
+
+       public File getWritableBaseDir() {
+               if (withExecutionSubdirectory) {
+                       Date executionContextCreationDate = (Date) executionContext
+                                       .getVariable(ExecutionContext.VAR_EXECUTION_CONTEXT_CREATION_DATE);
+                       Assert.notNull(executionContext, "execution context is null");
+                       String path = baseDir.getPath() + File.separator
+                                       + sdf().format(executionContextCreationDate);
+                       // TODO write execution id somewhere? like in a txt file
+                       return new File(path);
+               } else {
+                       return baseDir;
+               }
+       }
+
+       protected String removeFilePrefix(String url) {
+               if (url.startsWith("file:"))
+                       return url.substring("file:".length());
+               else if (url.startsWith("reference:file:"))
+                       return url.substring("reference:file:".length());
+               else
+                       return url;
+       }
+
+       public void setBaseDir(File baseDir) {
+               this.baseDir = baseDir;
+       }
+
+       public void setExecutionContext(ExecutionContext executionContext) {
+               this.executionContext = executionContext;
+       }
+
+       public void setPrefixDatePattern(String prefixDatePattern) {
+               this.prefixDatePattern = prefixDatePattern;
+       }
+
+       public File getBaseDir() {
+               return baseDir;
+       }
+
+       public ExecutionContext getExecutionContext() {
+               return executionContext;
+       }
+
+       public String getPrefixDatePattern() {
+               return prefixDatePattern;
+       }
+
+       /** Default is true. */
+       public void setWithExecutionSubdirectory(Boolean withExecutionSubdirectory) {
+               this.withExecutionSubdirectory = withExecutionSubdirectory;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/FlowConfigurationException.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/FlowConfigurationException.java
new file mode 100644 (file)
index 0000000..aeda5ac
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.slc.core.execution;
+
+import org.argeo.slc.SlcException;
+
+/** The stack trace of such exceptions does not need to be displayed */
+public class FlowConfigurationException extends SlcException {
+       private static final long serialVersionUID = 8456260596346797321L;
+
+       public FlowConfigurationException(String message) {
+               super(message);
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/InstantiationManager.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/InstantiationManager.java
new file mode 100644 (file)
index 0000000..60e93ec
--- /dev/null
@@ -0,0 +1,120 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution;\r
+\r
+import java.util.Stack;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.execution.ExecutionFlow;\r
+import org.argeo.slc.execution.ExecutionSpecAttribute;\r
+\r
+/** Manage parameters that need to be set during the instantiation of a flow */\r
+public class InstantiationManager {\r
+\r
+       private final static Log log = LogFactory\r
+                       .getLog(InstantiationManager.class);\r
+\r
+       private ThreadLocal<Stack<ExecutionFlow>> flowStack = new ThreadLocal<Stack<ExecutionFlow>>();\r
+\r
+       public Object createRef(String name) {\r
+\r
+               if ((flowStack.get() == null) || flowStack.get().empty()) {\r
+                       throw new SlcException("No flow is currently initializing."\r
+                                       + " Declare ParameterRef as inner beans or prototypes.");\r
+               }\r
+\r
+               return getInitializingFlowParameter(name);\r
+       }\r
+\r
+       public void flowInitializationStarted(ExecutionFlow flow, String flowName) {\r
+               // set the flow name if it is DefaultExecutionFlow\r
+               if (flow instanceof DefaultExecutionFlow) {\r
+                       ((DefaultExecutionFlow) flow).setBeanName(flowName);\r
+               }\r
+\r
+               if (log.isTraceEnabled())\r
+                       log.trace("Start initialization of " + flow.hashCode() + " ("\r
+                                       + flow + " - " + flow.getClass() + ")");\r
+\r
+               // log.info("# flowInitializationStarted " + flowName);\r
+               // create a stack for this thread if there is none\r
+               if (flowStack.get() == null) {\r
+                       flowStack.set(new Stack<ExecutionFlow>());\r
+               }\r
+               flowStack.get().push(flow);\r
+       }\r
+\r
+       public void flowInitializationFinished(ExecutionFlow flow, String flowName) {\r
+               if (log.isTraceEnabled())\r
+                       log.trace("Finish initialization of " + flow.hashCode() + " ("\r
+                                       + flow + " - " + flow.getClass() + ")");\r
+\r
+               if (flowStack.get() != null) {\r
+                       ExecutionFlow registeredFlow = flowStack.get().pop();\r
+                       if (registeredFlow != null) {\r
+                               if (!flow.getName().equals(registeredFlow.getName()))\r
+                                       throw new SlcException("Current flow is " + flow);\r
+                               // log.info("# flowInitializationFinished " + flowName);\r
+                               // initializingFlow.set(null);\r
+                       }\r
+               } else {\r
+                       // happens for flows imported as services\r
+                       log.warn("flowInitializationFinished - Flow Stack is null");\r
+               }\r
+       }\r
+\r
+       protected ExecutionFlow findInitializingFlowWithParameter(String key) {\r
+               if ((flowStack.get() == null) || flowStack.get().empty())\r
+                       throw new SlcException("No initializing flow available.");\r
+\r
+               // first look in the outer flow (that may override parameters)\r
+               for (int i = 0; i < flowStack.get().size(); i++) {\r
+                       if (flowStack.get().elementAt(i).isSetAsParameter(key)) {\r
+                               return flowStack.get().elementAt(i);\r
+                       }\r
+               }\r
+               throw new SlcException("Key " + key + " is not set as parameter in "\r
+                               + flowStack.get().firstElement().toString() + " (stack size="\r
+                               + flowStack.get().size() + ")");\r
+\r
+       }\r
+\r
+       public Object getInitializingFlowParameter(String key) {\r
+               return findInitializingFlowWithParameter(key).getParameter(key);\r
+       }\r
+\r
+       public Class<?> getInitializingFlowParameterClass(String key) {\r
+               ExecutionSpecAttribute attr = findInitializingFlowWithParameter(key)\r
+                               .getExecutionSpec().getAttributes().get(key);\r
+               if (attr instanceof RefSpecAttribute)\r
+                       return ((RefSpecAttribute) attr).getTargetClass();\r
+               else if (attr instanceof PrimitiveSpecAttribute) {\r
+                       String type = ((PrimitiveSpecAttribute) attr).getType();\r
+                       Class<?> clss = PrimitiveUtils.typeAsClass(type);\r
+                       if (clss == null)\r
+                               throw new SlcException("Cannot convert type " + type\r
+                                               + " to class.");\r
+                       return clss;\r
+               } else\r
+                       return null;\r
+       }\r
+\r
+       public Boolean isInFlowInitialization() {\r
+               return (flowStack.get() != null) && !flowStack.get().empty();\r
+       }\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/MapExecutionContext.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/MapExecutionContext.java
new file mode 100644 (file)
index 0000000..324f973
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionStack;
+import org.springframework.beans.BeanWrapper;
+import org.springframework.beans.BeanWrapperImpl;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+public class MapExecutionContext implements ExecutionContext,
+               ApplicationContextAware {
+       private final Map<String, Object> variables = Collections
+                       .synchronizedMap(new HashMap<String, Object>());
+
+       private final String uuid;
+
+       private ApplicationContext applicationContext;
+       private ExecutionStack executionStack;
+
+       public MapExecutionContext() {
+               uuid = UUID.randomUUID().toString();
+               variables.put(VAR_EXECUTION_CONTEXT_ID, uuid);
+               variables.put(VAR_EXECUTION_CONTEXT_CREATION_DATE, new Date());
+       }
+
+       public void setVariable(String key, Object value) {
+               // check if we do not refer to a bean
+               int lastInd = key.lastIndexOf('.');
+               if (applicationContext != null && lastInd > 0) {
+                       String beanName = key.substring(0, lastInd);
+                       String propertyName = key.substring(lastInd + 1);
+                       if (applicationContext.containsBean(beanName)) {
+                               BeanWrapper beanWrapper = new BeanWrapperImpl(
+                                               applicationContext.getBean(beanName));
+                               if (!beanWrapper.isWritableProperty(propertyName))
+                                       throw new SlcException("No writable property "
+                                                       + propertyName + " in bean " + beanName);
+                               beanWrapper.setPropertyValue(propertyName, value);
+                       }
+               }
+
+               variables.put(key, value);
+       }
+
+       public Object getVariable(String key) {
+               // check if we do not refer to a bean
+               int lastInd = key.lastIndexOf('.');
+               if (applicationContext != null && lastInd > 0) {
+                       String beanName = key.substring(0, lastInd);
+                       String propertyName = key.substring(lastInd + 1);
+                       if (applicationContext.containsBean(beanName)) {
+                               BeanWrapper beanWrapper = new BeanWrapperImpl(
+                                               applicationContext.getBean(beanName));
+                               if (!beanWrapper.isReadableProperty(propertyName))
+                                       throw new SlcException("No readable property "
+                                                       + propertyName + " in bean " + beanName);
+                               Object obj = beanWrapper.getPropertyValue(propertyName);
+                               return obj;
+                       }
+               }
+
+               Object value = variables.get(key);
+               // try system property in last resort
+               if (value == null)
+                       value = System.getProperty(key);
+
+               // if the variable was not found, look in the stack starting at the
+               // upper flows
+               if (value == null) {
+                       value = executionStack.findLocalVariable(key);
+               }
+               return value;
+       }
+
+       public String getUuid() {
+               return uuid;
+       }
+
+       @Override
+       public void beforeFlow(ExecutionFlow executionFlow) {
+               // getUuid();
+               executionStack.enterFlow(executionFlow);
+               setVariable(ExecutionContext.VAR_FLOW_ID,
+                               executionStack.getCurrentStackLevelUuid());
+               setVariable(ExecutionContext.VAR_FLOW_NAME, executionFlow.getName());
+       }
+
+       @Override
+       public void afterFlow(ExecutionFlow executionFlow) {
+               executionStack.leaveFlow(executionFlow);
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof ExecutionContext)
+                       return uuid.equals(((ExecutionContext) obj).getUuid());
+               return false;
+       }
+
+       @Override
+       public String toString() {
+               return getClass().getSimpleName() + "#" + uuid;
+       }
+
+       public void setApplicationContext(ApplicationContext applicationContext)
+                       throws BeansException {
+               this.applicationContext = applicationContext;
+       }
+
+       public void setExecutionStack(ExecutionStack executionStack) {
+               this.executionStack = executionStack;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/OsFileFactoryBean.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/OsFileFactoryBean.java
new file mode 100644 (file)
index 0000000..e524970
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.core.io.Resource;
+import org.springframework.util.Assert;
+
+/** Retrieve an OS File from the given resource. */
+public class OsFileFactoryBean implements FactoryBean<String> {
+       private ExecutionResources executionResources;
+       private Resource resource;
+       private Boolean overwrite = false;
+
+       /** Return an existing file on the file system. */
+       public String getObject() throws Exception {
+               Assert.notNull(executionResources, "executionResources is null");
+               Assert.notNull(resource, "resource is null");
+               return executionResources.getAsOsPath(resource, overwrite);
+       }
+
+       /** Return {@link Object} because CGLIB is unable to proxy {@link File}. */
+       public Class<? extends Object> getObjectType() {
+               return CharSequence.class;
+       }
+
+       public boolean isSingleton() {
+               return false;
+       }
+
+       /** The execution resources object. */
+       public void setExecutionResources(ExecutionResources executionResources) {
+               this.executionResources = executionResources;
+       }
+
+       /** The resource to access. */
+       public void setResource(Resource resource) {
+               this.resource = resource;
+       }
+
+       /**
+        * Whether to overwrite the resource if it already exists. Default is
+        * <code>false</code>.
+        */
+       public void setOverwrite(Boolean overwrite) {
+               this.overwrite = overwrite;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ParameterRef.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ParameterRef.java
new file mode 100644 (file)
index 0000000..45dd096
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.FactoryBean;
+
+public class ParameterRef implements FactoryBean<Object> {
+       private final static Log log = LogFactory.getLog(ParameterRef.class);
+
+       private InstantiationManager instantiationManager;
+       private String name;
+
+       /** Cached object. */
+       private Object object;
+
+       public ParameterRef() {
+       }
+
+       public ParameterRef(String name) {
+               this.name = name;
+       }
+
+       public Object getObject() throws Exception {
+               if (log.isTraceEnabled())
+                       log.debug("Parameter ref called for " + name);
+
+               if (object == null)
+                       object = instantiationManager.getInitializingFlowParameter(name);
+               return object;
+       }
+
+       public Class<?> getObjectType() {
+               if (object == null)
+                       return instantiationManager.getInitializingFlowParameterClass(name);
+               else
+                       return object.getClass();
+       }
+
+       public boolean isSingleton() {
+               return true;
+       }
+
+       public void setInstantiationManager(
+                       InstantiationManager instantiationManager) {
+               this.instantiationManager = instantiationManager;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveAccessor.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveAccessor.java
new file mode 100644 (file)
index 0000000..18d1b98
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+/** Abstraction of access to primitive values */
+public interface PrimitiveAccessor {
+       public final static String TYPE_STRING = "string";
+       /**
+        * As of Argeo 1, passwords are NOT stored encrypted, just hidden in the UI,
+        * but stored in plain text in JCR. Use keyring instead.
+        */
+       public final static String TYPE_PASSWORD = "password";
+       public final static String TYPE_INTEGER = "integer";
+       public final static String TYPE_LONG = "long";
+       public final static String TYPE_FLOAT = "float";
+       public final static String TYPE_DOUBLE = "double";
+       public final static String TYPE_BOOLEAN = "boolean";
+
+       public String getType();
+
+       public Object getValue();
+
+       public void setValue(Object value);
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveSpecAttribute.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveSpecAttribute.java
new file mode 100644 (file)
index 0000000..fe8412c
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.argeo.slc.SlcException;
+
+/**
+ * A spec attribute wrapping a primitive value.
+ * 
+ * @see PrimitiveAccessor
+ */
+public class PrimitiveSpecAttribute extends AbstractSpecAttribute implements
+               PrimitiveAccessor {
+       private static final long serialVersionUID = -566676381839825483L;
+       private String type = "string";
+       private Object value = null;
+
+       public PrimitiveSpecAttribute() {
+       }
+
+       public PrimitiveSpecAttribute(String type, Object value) {
+               this.type = type;
+               this.value = value;
+       }
+
+       public Object getValue() {
+               return value;
+       }
+
+       public void setValue(Object value) {
+               this.value = value;
+       }
+
+       public String getType() {
+               return type;
+       }
+
+       public void setType(String type) {
+               // check whether type is recognized.
+               if (PrimitiveUtils.typeAsClass(type) == null)
+                       throw new SlcException("Unrecognized type " + type);
+               this.type = type;
+
+       }
+
+       @Override
+       public String toString() {
+               return "Primitive spec attribute [" + type + "]"
+                               + (value != null ? "=" + value : "");
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveUtils.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveUtils.java
new file mode 100644 (file)
index 0000000..4268b8b
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+/** Converts to and from primitive types. */
+public class PrimitiveUtils {
+       /**
+        * @deprecated Use {@link PrimitiveAccessor#TYPE_STRING} instead
+        */
+       public final static String TYPE_STRING = PrimitiveAccessor.TYPE_STRING;
+       /**
+        * @deprecated Use {@link PrimitiveAccessor#TYPE_INTEGER} instead
+        */
+       public final static String TYPE_INTEGER = PrimitiveAccessor.TYPE_INTEGER;
+       /**
+        * @deprecated Use {@link PrimitiveAccessor#TYPE_LONG} instead
+        */
+       public final static String TYPE_LONG = PrimitiveAccessor.TYPE_LONG;
+       /**
+        * @deprecated Use {@link PrimitiveAccessor#TYPE_FLOAT} instead
+        */
+       public final static String TYPE_FLOAT = PrimitiveAccessor.TYPE_FLOAT;
+       /**
+        * @deprecated Use {@link PrimitiveAccessor#TYPE_DOUBLE} instead
+        */
+       public final static String TYPE_DOUBLE = PrimitiveAccessor.TYPE_DOUBLE;
+       /**
+        * @deprecated Use {@link PrimitiveAccessor#TYPE_BOOLEAN} instead
+        */
+       public final static String TYPE_BOOLEAN = PrimitiveAccessor.TYPE_BOOLEAN;
+
+       private PrimitiveUtils() {
+
+       }
+
+       /** @return the class or null if the provided type is not a primitive */
+       public static Class<?> typeAsClass(String type) {
+               if (PrimitiveAccessor.TYPE_STRING.equals(type))
+                       return String.class;
+               else if (PrimitiveAccessor.TYPE_PASSWORD.equals(type))
+                       return char[].class;
+               else if (PrimitiveAccessor.TYPE_INTEGER.equals(type))
+                       return Integer.class;
+               else if (PrimitiveAccessor.TYPE_LONG.equals(type))
+                       return Long.class;
+               else if (PrimitiveAccessor.TYPE_FLOAT.equals(type))
+                       return Float.class;
+               else if (PrimitiveAccessor.TYPE_DOUBLE.equals(type))
+                       return Double.class;
+               else if (PrimitiveAccessor.TYPE_BOOLEAN.equals(type))
+                       return Boolean.class;
+               else
+                       return null;
+       }
+
+       /** @return the type or null if the provided class is not a primitive */
+       public static String classAsType(Class<?> clss) {
+               if (String.class.isAssignableFrom(clss))
+                       return PrimitiveAccessor.TYPE_STRING;
+               else if (char[].class.isAssignableFrom(clss))
+                       return PrimitiveAccessor.TYPE_PASSWORD;
+               else if (Integer.class.isAssignableFrom(clss))
+                       return PrimitiveAccessor.TYPE_INTEGER;
+               else if (Long.class.isAssignableFrom(clss))
+                       return PrimitiveAccessor.TYPE_LONG;
+               else if (Float.class.isAssignableFrom(clss))
+                       return PrimitiveAccessor.TYPE_FLOAT;
+               else if (Double.class.isAssignableFrom(clss))
+                       return PrimitiveAccessor.TYPE_DOUBLE;
+               else if (Boolean.class.isAssignableFrom(clss))
+                       return PrimitiveAccessor.TYPE_BOOLEAN;
+               else
+                       return null;
+       }
+
+       /** Parse string as an object. Passwords are returned as String.*/
+       public static Object convert(String type, String str) {
+               if (PrimitiveAccessor.TYPE_STRING.equals(type)) {
+                       return str;
+               } else if (PrimitiveAccessor.TYPE_PASSWORD.equals(type)) {
+                       return str;
+               } else if (PrimitiveAccessor.TYPE_INTEGER.equals(type)) {
+                       return (Integer.parseInt(str));
+               } else if (PrimitiveAccessor.TYPE_LONG.equals(type)) {
+                       return (Long.parseLong(str));
+               } else if (PrimitiveAccessor.TYPE_FLOAT.equals(type)) {
+                       return (Float.parseFloat(str));
+               } else if (PrimitiveAccessor.TYPE_DOUBLE.equals(type)) {
+                       return (Double.parseDouble(str));
+               } else if (PrimitiveAccessor.TYPE_BOOLEAN.equals(type)) {
+                       return (Boolean.parseBoolean(str));
+               } else {
+                       return str;
+               }
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveValue.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/PrimitiveValue.java
new file mode 100644 (file)
index 0000000..3dedb9c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+/** Primitive value to be used by an execution. */
+public class PrimitiveValue extends AbstractExecutionValue implements
+               PrimitiveAccessor {
+       private static final long serialVersionUID = 533414290998374166L;
+
+       private String type;
+
+       private Object value;
+
+       public PrimitiveValue() {
+       }
+
+       public PrimitiveValue(String type, Object value) {
+               super();
+               this.type = type;
+               this.value = value;
+       }
+
+       public String getType() {
+               return type;
+       }
+
+       public void setType(String type) {
+               this.type = type;
+       }
+
+       public Object getValue() {
+               return value;
+       }
+
+       public void setValue(Object value) {
+               this.value = value;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ProcessThread.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ProcessThread.java
new file mode 100644 (file)
index 0000000..9267896
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.ExecutionStep;
+import org.argeo.slc.execution.RealizedFlow;
+
+/**
+ * Main thread coordinating an {@link ExecutionProcess}, launching parallel or
+ * sequential {@link ExecutionThread}s.
+ */
+public class ProcessThread extends Thread {
+       private final static Log log = LogFactory.getLog(ProcessThread.class);
+
+       private final ExecutionModulesManager executionModulesManager;
+       private final ExecutionProcess process;
+       private final ProcessThreadGroup processThreadGroup;
+
+       private Set<ExecutionThread> executionThreads = Collections.synchronizedSet(new HashSet<ExecutionThread>());
+
+       // private Boolean hadAnError = false;
+       private Boolean killed = false;
+
+       private final AccessControlContext accessControlContext;
+
+       public ProcessThread(ThreadGroup processesThreadGroup, ExecutionModulesManager executionModulesManager,
+                       ExecutionProcess process) {
+               super(processesThreadGroup, "SLC Process #" + process.getUuid());
+               this.executionModulesManager = executionModulesManager;
+               this.process = process;
+               processThreadGroup = new ProcessThreadGroup(process);
+               accessControlContext = AccessController.getContext();
+       }
+
+       public final void run() {
+               // authenticate thread
+               // Authentication authentication = getProcessThreadGroup()
+               // .getAuthentication();
+               // if (authentication == null)
+               // throw new SlcException("Can only execute authenticated threads");
+               // SecurityContextHolder.getContext().setAuthentication(authentication);
+
+               log.info("\n##\n## SLC Process #" + process.getUuid() + " STARTED\n##\n");
+
+               // Start logging
+               new LoggingThread().start();
+
+               process.setStatus(ExecutionProcess.RUNNING);
+               try {
+                       Subject subject = Subject.getSubject(accessControlContext);
+                       try {
+                               Subject.doAs(subject, new PrivilegedExceptionAction<Void>() {
+
+                                       @Override
+                                       public Void run() throws Exception {
+                                               process();
+                                               return null;
+                                       }
+
+                               });
+                       } catch (PrivilegedActionException privilegedActionException) {
+                               Throwable cause = privilegedActionException.getCause();
+                               if (cause instanceof InterruptedException)
+                                       throw (InterruptedException) cause;
+                               else
+                                       throw new SlcException("Cannot process", cause);
+                       }
+                       // process();
+               } catch (InterruptedException e) {
+                       die();
+                       return;
+               } catch (Exception e) {
+                       String msg = "Process " + getProcess().getUuid() + " failed unexpectedly.";
+                       log.error(msg, e);
+                       getProcessThreadGroup()
+                                       .dispatchAddStep(new ExecutionStep("Process", ExecutionStep.ERROR, msg + " " + e.getMessage()));
+               }
+
+               // waits for all execution threads to complete (in case they were
+               // started asynchronously)
+               for (ExecutionThread executionThread : executionThreads) {
+                       if (executionThread.isAlive()) {
+                               try {
+                                       executionThread.join();
+                               } catch (InterruptedException e) {
+                                       die();
+                                       return;
+                               }
+                       }
+               }
+
+               computeFinalStatus();
+       }
+
+       /** Make sure this is called BEFORE all the threads are interrupted. */
+       private void computeFinalStatus() {
+               // String oldStatus = process.getStatus();
+               // TODO: error management at flow level?
+               if (killed)
+                       process.setStatus(ExecutionProcess.KILLED);
+               else if (processThreadGroup.hadAnError())
+                       process.setStatus(ExecutionProcess.ERROR);
+               else
+                       process.setStatus(ExecutionProcess.COMPLETED);
+               // executionModulesManager.dispatchUpdateStatus(process, oldStatus,
+               // process.getStatus());
+               log.info("\n## SLC Process #" + process.getUuid() + " " + process.getStatus() + "\n");
+       }
+
+       /** Called when being killed */
+       private synchronized void die() {
+               killed = true;
+               computeFinalStatus();
+               for (ExecutionThread executionThread : executionThreads) {
+                       try {
+                               executionThread.interrupt();
+                       } catch (Exception e) {
+                               log.error("Cannot interrupt " + executionThread);
+                       }
+               }
+               processThreadGroup.interrupt();
+       }
+
+       /**
+        * Implementation specific execution. To be overridden in order to deal with
+        * custom process types. Default expects an {@link SlcExecution}.
+        */
+       protected void process() throws InterruptedException {
+               List<RealizedFlow> flowsToProcess = new ArrayList<RealizedFlow>();
+               flowsToProcess.addAll(process.getRealizedFlows());
+               while (flowsToProcess.size() > 0) {
+                       RealizedFlow realizedFlow = flowsToProcess.remove(0);
+                       execute(realizedFlow, true);
+               }
+       }
+
+       /** @return the (distinct) thread used for this execution */
+       protected final void execute(RealizedFlow realizedFlow, Boolean synchronous) throws InterruptedException {
+               if (killed)
+                       return;
+
+               ExecutionThread thread = new ExecutionThread(processThreadGroup, executionModulesManager, realizedFlow);
+               executionThreads.add(thread);
+               thread.start();
+
+               if (synchronous)
+                       thread.join();
+
+               return;
+       }
+
+       // public void notifyError() {
+       // hadAnError = true;
+       // }
+       //
+       // public synchronized void flowCompleted() {
+       // // notifyAll();
+       // }
+
+       public ExecutionProcess getProcess() {
+               return process;
+       }
+
+       public ProcessThreadGroup getProcessThreadGroup() {
+               return processThreadGroup;
+       }
+
+       public ExecutionModulesManager getExecutionModulesManager() {
+               return executionModulesManager;
+       }
+
+       private class LoggingThread extends Thread {
+
+               public LoggingThread() {
+                       super("SLC Process Logger #" + process.getUuid());
+               }
+
+               public void run() {
+                       boolean run = true;
+                       while (run) {
+                               List<ExecutionStep> newSteps = new ArrayList<ExecutionStep>();
+                               processThreadGroup.getSteps().drainTo(newSteps);
+                               if (newSteps.size() > 0) {
+                                       // System.out.println(steps.size() + " steps");
+                                       process.addSteps(newSteps);
+                               }
+
+                               try {
+                                       Thread.sleep(1000);
+                               } catch (InterruptedException e) {
+                                       break;
+                               }
+
+                               if (!ProcessThread.this.isAlive() && processThreadGroup.getSteps().size() == 0)
+                                       run = false;
+                       }
+               }
+
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ProcessThreadGroup.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/ProcessThreadGroup.java
new file mode 100644 (file)
index 0000000..17dbff8
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.ExecutionStep;
+
+/** The thread group attached to a given {@link SlcExecution}. */
+public class ProcessThreadGroup extends ThreadGroup {
+//     private final Authentication authentication;
+       private final static Integer STEPS_BUFFER_CAPACITY = 5000;
+
+       private BlockingQueue<ExecutionStep> steps = new ArrayBlockingQueue<ExecutionStep>(
+                       STEPS_BUFFER_CAPACITY);
+
+       private Boolean hadAnError = false;
+
+       public ProcessThreadGroup(ExecutionProcess executionProcess) {
+               super("SLC Process #" + executionProcess.getUuid() + " thread group");
+//             this.authentication = SecurityContextHolder.getContext()
+//                             .getAuthentication();
+       }
+
+//     public Authentication getAuthentication() {
+//             return authentication;
+//     }
+
+       public void dispatchAddStep(ExecutionStep step) {
+               // ExecutionProcess slcProcess = processThread.getProcess();
+               // List<ExecutionStep> steps = new ArrayList<ExecutionStep>();
+               // steps.add(step);
+               // TODO clarify why we don't dispatch steps, must be a reason
+               // dispatchAddSteps(steps);
+               // slcProcess.addSteps(steps);
+               if (step.getType().equals(ExecutionStep.ERROR))
+                       hadAnError = true;
+               this.steps.add(step);
+       }
+
+       // public void dispatchAddSteps(List<ExecutionStep> steps) {
+       // ExecutionProcess slcProcess = processThread.getProcess();
+       // executionModulesManager.dispatchAddSteps(slcProcess, steps);
+       // }
+
+       public BlockingQueue<ExecutionStep> getSteps() {
+               return steps;
+       }
+
+       public Boolean hadAnError() {
+               return hadAnError;
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/RefSpecAttribute.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/RefSpecAttribute.java
new file mode 100644 (file)
index 0000000..8e4f617
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.List;
+
+/** A spec attribute whose value is a reference to a full fledged object. */
+public class RefSpecAttribute extends AbstractSpecAttribute implements
+               Cloneable {
+       private static final long serialVersionUID = -3427797452955753574L;
+       private transient Class<?> targetClass = String.class;
+       /** Read only. */
+       private String targetClassName;
+       private transient Object value = null;
+
+       /** List to be chosen from */
+       private List<RefValueChoice> choices = null;
+
+       public Object getValue() {
+               return value;
+       }
+
+       public void setValue(Object value) {
+               this.value = value;
+       }
+
+       /** Default is {@link String} */
+       public Class<?> getTargetClass() {
+               return targetClass;
+       }
+
+       public void setTargetClass(Class<?> targetClass) {
+               this.targetClass = targetClass;
+               this.targetClassName = targetClass.getName();
+       }
+
+       public String getTargetClassName() {
+               return targetClassName;
+       }
+
+       /** @return can be null */
+       public List<RefValueChoice> getChoices() {
+               return choices;
+       }
+
+       public void setChoices(List<RefValueChoice> choices) {
+               this.choices = choices;
+       }
+
+       @Override
+       protected Object clone() throws CloneNotSupportedException {
+               RefSpecAttribute rsa = new RefSpecAttribute();
+               rsa.setTargetClass(targetClass);
+               rsa.setChoices(choices);
+               return rsa;
+       }
+
+       @Override
+       public String toString() {
+               return "Ref spec attribute [" + targetClass + "]"
+                               + (value != null ? "=" + value : "");
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/RefValue.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/RefValue.java
new file mode 100644 (file)
index 0000000..0a24bc4
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+/** Reference value to be used by an execution */
+public class RefValue extends AbstractExecutionValue {
+       private static final long serialVersionUID = -8951231456757181687L;
+       private String ref;
+       private String type;
+
+       public RefValue() {
+       }
+
+       public RefValue(String ref) {
+               super();
+               this.ref = ref;
+       }
+
+       public String getRef() {
+               return ref;
+       }
+
+       public void setRef(String ref) {
+               this.ref = ref;
+       }
+
+       public String getType() {
+               return type;
+       }
+
+       public void setType(String type) {
+               this.type = type;
+       }
+
+       @Override
+       public String toString() {
+               return "Ref Value [" + type + "=" + ref + "]";
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/RefValueChoice.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/RefValueChoice.java
new file mode 100644 (file)
index 0000000..5e1f9c2
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.Serializable;
+
+/** A choice of ref value to be shown to the end user. */
+public class RefValueChoice implements Serializable {
+       private static final long serialVersionUID = -1133645722307507774L;
+       private String name;
+       private String description;
+
+       public RefValueChoice() {
+       }
+
+       public RefValueChoice(String name, String description) {
+               this.name = name;
+               this.description = description;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getDescription() {
+               return description;
+       }
+
+       public void setDescription(String description) {
+               this.description = description;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/SedFilteredResource.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/SedFilteredResource.java
new file mode 100644 (file)
index 0000000..c793f49
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.core.io.Resource;
+
+/** Experimental and suboptimal */
+public class SedFilteredResource implements FactoryBean<Resource>,
+               InitializingBean {
+       private Resource source;
+
+       private List<String> filters = new ArrayList<String>();
+       private Map<Pattern, String> patterns = new HashMap<Pattern, String>();
+
+       private String charset = "UTF-8";
+       private Charset cs;
+       private CharsetDecoder decoder;
+
+       // private CharsetEncoder encoder;
+
+       public Resource getObject() throws Exception {
+               if (filters.size() == 0)
+                       return source;
+
+               // int capacity = 100 * 1024;// 100 KB
+               ByteBuffer bb;
+               if (source instanceof ByteArrayResource) {
+                       bb = ByteBuffer.wrap(((ByteArrayResource) source).getByteArray());
+               } else {
+                       FileInputStream fis = null;
+                       try {
+                               File file = source.getFile();
+                               fis = new FileInputStream(file);
+                               FileChannel fc = fis.getChannel();
+
+                               // Get the file's size and then map it into memory
+                               int sz = (int) fc.size();
+                               bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
+                       } catch (IOException e) {
+                               // ReadableByteChannel channel = Channels.newChannel(source
+                               // .getInputStream());
+                               // bb = ByteBuffer.allocateDirect(capacity);
+                               // int read = 0;
+                               // do {
+                               // read = channel.read(bb);
+                               // } while (read > 0);
+                               // FIXME : use nio to parse the stream as it goes
+                               bb = ByteBuffer.wrap(IOUtils.toByteArray(source
+                                               .getInputStream()));
+                       } finally {
+                               IOUtils.closeQuietly(fis);
+                       }
+               }
+               CharBuffer cb = decoder.decode(bb);
+               for (Pattern pattern : patterns.keySet()) {
+                       Matcher matcher = pattern.matcher(cb);
+                       String output = matcher.replaceAll(patterns.get(pattern));
+                       cb = CharBuffer.wrap(output);
+               }
+               // ByteBuffer bbout = encoder.encode(cb);
+               // ByteArrayOutputStream out = new ByteArrayOutputStream(capacity);
+               // WritableByteChannel wchannel = Channels.newChannel(out);
+               // wchannel.write(bbout);
+               ByteArrayResource res = new ByteArrayResource(cb.toString().getBytes());
+               return res;
+       }
+
+       public Class<?> getObjectType() {
+               return Resource.class;
+       }
+
+       public boolean isSingleton() {
+               return true;
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               cs = Charset.forName(charset);
+               decoder = cs.newDecoder();
+               // encoder = cs.newEncoder();
+
+               for (String sedStr : filters) {
+                       sedStr = sedStr.trim();
+                       if (sedStr.length() < 4)
+                               throw new SlcException(sedStr + " not properly formatted.");
+                       if (sedStr.charAt(0) != 's')
+                               throw new SlcException(sedStr + " not properly formatted.");
+                       Character sep = sedStr.charAt(1);
+                       List<String> tokens = new ArrayList<String>(4);
+                       StringTokenizer st = new StringTokenizer(sedStr, sep.toString());
+                       while (st.hasMoreTokens())
+                               tokens.add(st.nextToken());
+                       if (tokens.size() != 3 && tokens.size() != 4)
+                               throw new SlcException(sedStr + " not properly formatted.");
+                       patterns.put(Pattern.compile(tokens.get(1)), tokens.get(2));
+               }
+       }
+
+       public void setSource(Resource source) {
+               this.source = source;
+       }
+
+       public void setFilters(List<String> filters) {
+               this.filters = filters;
+       }
+
+       public void setCharset(String charset) {
+               this.charset = charset;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/defaults.xml b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/defaults.xml
new file mode 100644 (file)
index 0000000..d84ba10
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (C) 2007-2012 Argeo GmbH
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+            http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+       <bean id="slcDefault.executionResources" parent="slcTemplate.fileResources"
+               scope="execution" lazy-init="true">
+               <aop:scoped-proxy proxy-target-class="false" />
+               <property name="executionContext" ref="executionContext" />
+       </bean>
+
+       <bean id="slcDefault.writableResource" parent="slcTemplate.writableResource"
+               abstract="true">
+               <property name="executionResources" ref="slcDefault.executionResources" />
+       </bean>
+
+       <bean id="slcDefault.osFile" parent="slcTemplate.osFile" abstract="true">
+               <property name="executionResources" ref="slcDefault.executionResources" />
+       </bean>
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/doc/ConsoleContextDescriber.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/doc/ConsoleContextDescriber.java
new file mode 100644 (file)
index 0000000..6504a3d
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.doc;
+
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+
+public class ConsoleContextDescriber implements ContextDescriber {
+       public void describeContext(BeanDefinitionRegistry registry) {
+               String[] beanNames = registry.getBeanDefinitionNames();
+               for (String beanName : beanNames) {
+                       log("\n## BEAN: " + beanName);
+                       describeBean(registry.getBeanDefinition(beanName));
+               }
+       }
+
+       public void describeBean(BeanDefinition beanDefinition) {
+               log("BeanDefinition class: "+beanDefinition.getClass());
+               log("# ATTRIBUTES");
+               for(String attr:beanDefinition.attributeNames()){
+                       log(attr+"="+beanDefinition.getAttribute(attr));
+               }
+               log("# PROPERTIES");
+               MutablePropertyValues pValues = beanDefinition.getPropertyValues();
+               for (PropertyValue pv : pValues.getPropertyValues()) {
+                       log(pv.getName() + "= (" + pv.getValue().getClass() + ") "
+                                       + pv.getValue());
+               }
+       }
+
+       protected void log(Object obj){
+               System.out.println(obj);
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/doc/ContextDescriber.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/doc/ContextDescriber.java
new file mode 100644 (file)
index 0000000..713019b
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.doc;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+
+public interface ContextDescriber {
+       public void describeContext(BeanDefinitionRegistry registry);
+       public void describeBean(BeanDefinition bd);
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/CompositeRunnableFactory.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/CompositeRunnableFactory.java
new file mode 100644 (file)
index 0000000..f1e80d3
--- /dev/null
@@ -0,0 +1,77 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.Map;\r
+\r
+import org.argeo.slc.SlcException;\r
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
+\r
+/**\r
+ * Composite <code>RunnableFactory</code>, redirecting the Runnable \r
+ * creation to on of the configured <code>RunnableFactory</code> depending\r
+ * on an entry of the data of the <code>RunnableDataNode</code>.\r
+ */\r
+public class CompositeRunnableFactory implements RunnableFactory {\r
+\r
+       /**\r
+        * Key used to access factory ID in the data of the <code>RunnableDataNode</code>\r
+        */\r
+       private String factoryKey;\r
+\r
+       /**\r
+        * Maps a factory ID to an ExecutionFlowFactory\r
+        */\r
+       private Map<String, RunnableFactory> factories;\r
+\r
+       public void createAndRegisterRunnable(RunnableDataNode node,\r
+                       BeanDefinitionRegistry beanDefinitionRegistry) {\r
+               findFactory(node).createAndRegisterRunnable(node, beanDefinitionRegistry);\r
+       }       \r
+       \r
+       /**\r
+        * Finds the <code>RunnableFactory</code> to use for a <code>RunnableDataNode</code>\r
+        * @param node\r
+        * @return the <code>RunnableFactory</code> to use for the <code>RunnableDataNode</code>\r
+        */\r
+       private RunnableFactory findFactory(RunnableDataNode node) {\r
+               // get the factory ID from the data of the RunnableDescriptor\r
+               Map<String, Object> data = node.getData();\r
+               if (!data.containsKey(factoryKey)) {\r
+                       throw new SlcException("No data value for key '" + factoryKey + "'");\r
+               }\r
+               String factoryId = data.get(factoryKey).toString();\r
+               \r
+               // see if we have a factory for the factory ID\r
+               if ((factories != null) && factories.containsKey(factoryId)) {\r
+                       return factories.get(factoryId);\r
+               }\r
+               // if not, look for a bean of name equals to the factory ID\r
+               else {\r
+                       throw new SlcException("Not implemented");\r
+               }               \r
+       }\r
+       \r
+       public void setFactoryKey(String factoryKey) {\r
+               this.factoryKey = factoryKey;\r
+       }\r
+\r
+       public void setFactories(Map<String, RunnableFactory> factories) {\r
+               this.factories = factories;\r
+       }\r
+\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/DefaultRunnableDataNode.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/DefaultRunnableDataNode.java
new file mode 100644 (file)
index 0000000..daed350
--- /dev/null
@@ -0,0 +1,104 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+/**\r
+ * Default implementation of <code>RunnableDataNode</code>\r
+ *\r
+ */\r
+public class DefaultRunnableDataNode implements RunnableDataNode {\r
+\r
+       private List<RunnableDataNode> children = new ArrayList<RunnableDataNode>();\r
+       \r
+       private RunnableDataNode parent;\r
+       \r
+       /**\r
+        * Data of the RunnableDataNode. Does not contain\r
+        * parent data.\r
+        */\r
+       private Map<String, Object> properData = new HashMap<String, Object>();\r
+       \r
+       private String path;\r
+       \r
+       private String beanName;\r
+\r
+       public boolean isLeaf() {\r
+               return children.size() == 0;\r
+       }\r
+       \r
+       public List<RunnableDataNode> getChildren() {\r
+               return children;\r
+       }\r
+\r
+       public void addChild(RunnableDataNode child) {\r
+               child.setParent(this);\r
+               children.add(child);\r
+       }\r
+       \r
+       public Map<String, Object> getData() {\r
+               Map<String, Object> data = new HashMap<String, Object>();\r
+               if(parent != null) {\r
+                       Map<String, Object> parentData = parent.getData();\r
+                       if(parentData != null) {\r
+                               data.putAll(parentData);\r
+                       }\r
+               }\r
+               // entries defined in parentData can be overridden\r
+               // in properData\r
+               if(properData != null) {\r
+                       data.putAll(properData);\r
+               }\r
+               return data;\r
+       }\r
+\r
+       public Map<String, Object> getProperData() {\r
+               return properData;\r
+       }\r
+\r
+       public void setProperData(Map<String, Object> properData) {\r
+               this.properData = properData;\r
+       }\r
+\r
+       public String getPath() {\r
+               return path;\r
+       }\r
+\r
+       public void setPath(String path) {\r
+               this.path = path;\r
+       }\r
+\r
+       public String getBeanName() {\r
+               return beanName;\r
+       }\r
+\r
+       public void setBeanName(String beanName) {\r
+               this.beanName = beanName;\r
+       }\r
+\r
+       public void setParent(RunnableDataNode parent) {\r
+               this.parent = parent;\r
+       }\r
+\r
+       public RunnableDataNode getParent() {\r
+               return parent;\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/ExecutionFlowGenerator.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/ExecutionFlowGenerator.java
new file mode 100644 (file)
index 0000000..d9400e4
--- /dev/null
@@ -0,0 +1,181 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.SlcException;\r
+import org.springframework.aop.scope.ScopedProxyUtils;\r
+import org.springframework.beans.BeansException;\r
+import org.springframework.beans.MutablePropertyValues;\r
+import org.springframework.beans.factory.config.BeanDefinitionHolder;\r
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;\r
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;\r
+import org.springframework.beans.factory.config.RuntimeBeanReference;\r
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
+import org.springframework.beans.factory.support.GenericBeanDefinition;\r
+import org.springframework.core.Ordered;\r
+\r
+/**\r
+ * Generates <code>ExecutionFlows</code> and <code>Runnables</code> as\r
+ * beans in the Spring Application Context.\r
+ * Called by the Application Context as a <code>BeanFactoryPostProcessor</code>.\r
+ * Two kinds of beans are generated:\r
+ * <code>RunnableCallFlow</code>, calling a list of <code>Runnables</code> from the\r
+ * Application Context after configuring the <code>ExecutionContext</code>, \r
+ * and outputs of a <code>RunnableFactory</code>.\r
+ */\r
+public class ExecutionFlowGenerator implements BeanFactoryPostProcessor,\r
+               Ordered {\r
+       \r
+       private final Log log = LogFactory.getLog(getClass());\r
+\r
+       /**\r
+        * Source providing a list of <code>RunnableCallFlowDescriptor</code> \r
+        * used to create <code>RunnableCallFlow</code> and a list of \r
+        * <code>RunnableDataNode</code> used to create any kind of flow via a factory\r
+        */\r
+       protected ExecutionFlowGeneratorSource source;\r
+       \r
+       /**\r
+        * Factory used to create Runnables in the Application context from\r
+        * the <code>RunnableDataNode</code> provided from the source.\r
+        */\r
+       protected RunnableFactory runnableFactory;\r
+       \r
+       /**\r
+        * Bean name of the <code>ExecutionContext</code>.\r
+        * Used to provide the created <code>RunnableCallFlow</code> beans \r
+        * with a <code>RuntimeBeanReference</code> to\r
+        * the <code>ExecutionContext</code>\r
+        */\r
+       private String executionContextBeanName = "executionContext";\r
+       \r
+       /**\r
+        * Bean name of the context values Map.\r
+        * A bean of class HashMap is created with this name, and a \r
+        * <code>RuntimeBeanReference</code> is provided to the created\r
+        * <code>RunnableCallFlow</code> beans.\r
+        */\r
+       private String contextValuesBeanName = "executionFlowGenerator.contextValues";\r
+       \r
+       /**\r
+        * Prefix added to the bean names defined in each \r
+        * <code>RunnableCallFlowDescriptor</code>\r
+        */\r
+       private String flowBeanNamesPrefix = "";\r
+       \r
+       private int order = Ordered.HIGHEST_PRECEDENCE;\r
+               \r
+       public void postProcessBeanFactory(\r
+                       ConfigurableListableBeanFactory beanFactory) throws BeansException {\r
+\r
+               // assert that the beanFactory is a BeanDefinitionRegistry\r
+               if (!(beanFactory instanceof BeanDefinitionRegistry)) {\r
+                       throw new SlcException("Can only work on "\r
+                                       + BeanDefinitionRegistry.class);\r
+               } \r
+               \r
+               // add bean for the Context Values Map\r
+               createAndRegisterContextValuesBean((BeanDefinitionRegistry) beanFactory);\r
+               \r
+               // add beans for each RunnableDataNode\r
+               for(RunnableDataNode node : source.getRunnableDataNodes()) {\r
+                       runnableFactory.createAndRegisterRunnable(node, (BeanDefinitionRegistry) beanFactory);\r
+               }\r
+               \r
+               // add beans for each RunnableCallFlowDescriptor of the source to the application context\r
+               for (RunnableCallFlowDescriptor descriptor : source\r
+                               .getRunnableCallFlowDescriptors()) {\r
+                       createAndRegisterFlowFor(descriptor, (BeanDefinitionRegistry) beanFactory);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Creates a <code>RunnableCallFlow</code> bean\r
+        * for a <code>RunnableCallFlowDescriptor</code> and registers \r
+        * it in the <code>BeanDefinitionRegistry</code>\r
+        * @param flowDescriptor\r
+        * @param registry\r
+        */\r
+       private void createAndRegisterFlowFor(RunnableCallFlowDescriptor flowDescriptor, BeanDefinitionRegistry registry) {\r
+               // create the flow bean\r
+               GenericBeanDefinition flowBean = new GenericBeanDefinition();\r
+               flowBean.setBeanClass(RunnableCallFlow.class);\r
+               \r
+               String beanName = flowBeanNamesPrefix + flowDescriptor.getBeanName();\r
+               \r
+               MutablePropertyValues mpv = new MutablePropertyValues();                \r
+               mpv.addPropertyValue("runnableCalls", flowDescriptor.getRunnableCalls());\r
+               mpv.addPropertyValue("sharedContextValuesMap", new RuntimeBeanReference(contextValuesBeanName));\r
+               \r
+               mpv.addPropertyValue("name", beanName);\r
+               mpv.addPropertyValue("path", flowDescriptor.getPath());\r
+\r
+               mpv.addPropertyValue("executionContext", new RuntimeBeanReference(executionContextBeanName));\r
+               \r
+               flowBean.setPropertyValues(mpv);\r
+               \r
+               // register it\r
+               if(log.isDebugEnabled()) {\r
+                       log.debug("Registering bean definition for RunnableCallFlow " + beanName);\r
+               }\r
+               registry.registerBeanDefinition(beanName, flowBean);\r
+       }\r
+       \r
+       /**\r
+        * Creates the Context Values bean and register it in the\r
+        * <code>BeanDefinitionRegistry</code>\r
+        * @param registry\r
+        */\r
+       private void createAndRegisterContextValuesBean(BeanDefinitionRegistry registry) {\r
+               GenericBeanDefinition contextValuesBean = new GenericBeanDefinition();\r
+               contextValuesBean.setBeanClass(HashMap.class);\r
+               \r
+               BeanDefinitionHolder bdh = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(contextValuesBean, contextValuesBeanName), registry, true);                                                                                                                      \r
+               registry.registerBeanDefinition(contextValuesBeanName, bdh.getBeanDefinition());                \r
+       }\r
+       \r
+       public int getOrder() {\r
+               return order;\r
+       }\r
+\r
+       public void setOrder(int order) {\r
+               this.order = order;\r
+       }\r
+\r
+       public void setSource(ExecutionFlowGeneratorSource source) {\r
+               this.source = source;\r
+       }\r
+\r
+       public void setRunnableFactory(RunnableFactory runnableFactory) {\r
+               this.runnableFactory = runnableFactory;\r
+       }\r
+\r
+       public void setExecutionContextBeanName(String executionContextBeanName) {\r
+               this.executionContextBeanName = executionContextBeanName;\r
+       }\r
+\r
+       public void setContextValuesBeanName(String contextValuesBeanName) {\r
+               this.contextValuesBeanName = contextValuesBeanName;\r
+       }\r
+\r
+       public void setFlowBeanNamesPrefix(String flowBeanNamesPrefix) {\r
+               this.flowBeanNamesPrefix = flowBeanNamesPrefix;\r
+       }\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/ExecutionFlowGeneratorSource.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/ExecutionFlowGeneratorSource.java
new file mode 100644 (file)
index 0000000..8d699c6
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Provides 2 types of information required by an <code>ExecutionFlowGenerator</code>: \r
+ * a list of <code>RunnableCallFlowDescriptor</code> used to create <code>RunnableCallFlow</code>\r
+ * and a list of <code>RunnableDataNode</code> used to create any kind of flow via a factory.\r
+ */\r
+public interface ExecutionFlowGeneratorSource {\r
+       \r
+       /**\r
+        * @return a list of <code>RunnableCallFlowDescriptor</code> used \r
+        * by a <code>ExecutionFlowGenerator</code> to create <code>RunnableCallFlow</code>\r
+        */\r
+       public List<RunnableCallFlowDescriptor> getRunnableCallFlowDescriptors();\r
+       \r
+       /**\r
+        * @return a list of <code>RunnableDataNode</code> used \r
+        * by a <code>ExecutionFlowGenerator</code> to create any kind of flow via a factory\r
+        */\r
+       public List<RunnableDataNode> getRunnableDataNodes();\r
+       \r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableCall.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableCall.java
new file mode 100644 (file)
index 0000000..c3fd5f2
--- /dev/null
@@ -0,0 +1,70 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.Map;\r
+\r
+/**\r
+ * Storage class for information required to call a flow \r
+ * of the Spring execution context: \r
+ * bean name of the flow,\r
+ * variables to add to the Execution Context before the call \r
+ * and variables (context values) to add to a Map \r
+ * potentially referenced by the called flow \r
+ */\r
+public class RunnableCall {\r
+       \r
+       /**\r
+        * Bean name of the flow to call\r
+        */\r
+       private String beanName;\r
+       \r
+       /**\r
+        * Variables to add to the execution context before the call\r
+        */\r
+       private Map<String, Object> executionVariables;\r
+       \r
+       /**\r
+        * Variables to add to the Map potentially referenced by\r
+        * the called flow\r
+        */\r
+       private Map<String, Object> contextValues;\r
+\r
+       public String getBeanName() {\r
+               return beanName;\r
+       }\r
+\r
+       public void setBeanName(String beanName) {\r
+               this.beanName = beanName;\r
+       }\r
+\r
+       public Map<String, Object> getExecutionVariables() {\r
+               return executionVariables;\r
+       }\r
+\r
+       public void setExecutionVariables(Map<String, Object> executionVariables) {\r
+               this.executionVariables = executionVariables;\r
+       }\r
+\r
+       public Map<String, Object> getContextValues() {\r
+               return contextValues;\r
+       }\r
+\r
+       public void setContextValues(Map<String, Object> contextValues) {\r
+               this.contextValues = contextValues;\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableCallFlow.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableCallFlow.java
new file mode 100644 (file)
index 0000000..695606c
--- /dev/null
@@ -0,0 +1,243 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.core.execution.DefaultExecutionSpec;\r
+import org.argeo.slc.execution.ExecutionContext;\r
+import org.argeo.slc.execution.ExecutionFlow;\r
+import org.argeo.slc.execution.ExecutionSpec;\r
+import org.springframework.context.ApplicationContext;\r
+import org.springframework.context.ApplicationContextAware;\r
+\r
+/**\r
+ * Execution Flow calling a list of <code>Runnable</code> (identified by their\r
+ * bean name in the Spring Application Context) after configuring the Execution\r
+ * context and a Map potentially shared by the called <code>Runnable</code>\r
+ * \r
+ */\r
+public class RunnableCallFlow implements ExecutionFlow, ApplicationContextAware {\r
+\r
+       private final static Log log = LogFactory.getLog(RunnableCallFlow.class);\r
+\r
+       /**\r
+        * Key in the execution context for the index of the call (e.g. 0 for the\r
+        * first runnable called, ...)\r
+        */\r
+       public final static String VAR_CALL_INDEX = "slcVar.runnableCallFlow.callIndex";\r
+\r
+       /**\r
+        * Name of the flow. Also bean name\r
+        */\r
+       private String name;\r
+\r
+       /**\r
+        * Path of the flow\r
+        */\r
+       private String path;\r
+\r
+       /**\r
+        * Whether an exception in a <code>Runnable</code> shall stop the execution\r
+        * of the flow\r
+        */\r
+       private Boolean failOnError = true;\r
+\r
+       /**\r
+        * List of <code>Runnable</code> to call, with bean name, execution\r
+        * variables and context values\r
+        */\r
+       private List<RunnableCall> runnableCalls;\r
+\r
+       /**\r
+        * Map potentially referenced by called flows. Updated with the context\r
+        * values of a Runnable before calling it.\r
+        */\r
+       private Map<String, Object> sharedContextValuesMap;\r
+\r
+       /**\r
+        * ExecutionSpec of the flow. Does not contain any attribute.\r
+        */\r
+       private ExecutionSpec executionSpec = new DefaultExecutionSpec();\r
+\r
+       /**\r
+        * Reference to the ExecutionContext\r
+        */\r
+       private ExecutionContext executionContext;\r
+\r
+       /**\r
+        * Reference to the Spring <code>ApplicationContext</code>. Set via\r
+        * <code>setApplicationContext</code>, the class implementing\r
+        * <code>ApplicationContextAware</code>\r
+        */\r
+       private ApplicationContext applicationContext;\r
+\r
+       /**\r
+        * Runs a <code>Runnable</code> after configuring the Execution Context and\r
+        * <code>sharedContextValuesMap</code>\r
+        * \r
+        * @param runnable\r
+        *            the <code>Runnable</code> to call\r
+        * @param executionVariables\r
+        *            the variables to add to the <code>ExecutionContext</code>\r
+        * @param contextValues\r
+        *            the variables to add to <code>sharedContextValuesMap</code>\r
+        * @param callIndex\r
+        *            index of the call (0 for the first called\r
+        *            <code>Runnable</code>) set as variable of the\r
+        *            <code>ExecutionContext</code>\r
+        */\r
+       private void run(Runnable runnable, Map<String, Object> executionVariables,\r
+                       Map<String, Object> contextValues, int callIndex) {\r
+               // add all variables to the Execution Context\r
+               for (Map.Entry<String, Object> entry : executionVariables.entrySet()) {\r
+                       executionContext.setVariable(entry.getKey(), entry.getValue());\r
+               }\r
+\r
+               // add call Index Variable\r
+               executionContext.setVariable(VAR_CALL_INDEX, callIndex);\r
+\r
+               // clear sharedContextValues and add all values of contextValues\r
+               if (sharedContextValuesMap != null) {\r
+                       sharedContextValuesMap.clear();\r
+                       sharedContextValuesMap.putAll(contextValues);\r
+               }\r
+\r
+               // then run the runnable\r
+               doExecuteRunnable(runnable);\r
+       }\r
+\r
+       public void doExecuteRunnable(Runnable runnable) {\r
+               runnable.run();\r
+       }\r
+\r
+       /**\r
+        * Executes the flow. For each <code>RunnableCall</code>, the corresponding\r
+        * flow is retrieved from the Spring Application Context, the\r
+        * <code>ExecutionContext</code> and <code>sharedContextValuesMap</code> are\r
+        * configured and the <code>Runnable</code> is called.\r
+        */\r
+       public void run() {\r
+               if (applicationContext == null) {\r
+                       throw new SlcException("No ApplicationContext defined");\r
+               }\r
+\r
+               try {\r
+                       for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
+                               RunnableCall runnableCall = runnableCalls.get(callIndex);\r
+                               Object bean = applicationContext.getBean(\r
+                                               runnableCall.getBeanName(), Runnable.class);\r
+                               if (log.isDebugEnabled())\r
+                                       log.debug("Running flow '" + runnableCall.getBeanName()\r
+                                                       + "'");\r
+                               run((Runnable) bean, runnableCall.getExecutionVariables(),\r
+                                               runnableCall.getContextValues(), callIndex);\r
+                       }\r
+               } catch (RuntimeException e) {\r
+                       if (failOnError)\r
+                               throw e;\r
+                       else {\r
+                               log.error("Execution flow failed,"\r
+                                               + " but process did not fail"\r
+                                               + " because failOnError property"\r
+                                               + " is set to false: " + e);\r
+                               if (log.isTraceEnabled())\r
+                                       e.printStackTrace();\r
+                       }\r
+               }\r
+       }\r
+\r
+       public Iterator<Runnable> runnables() {\r
+               List<Runnable> runnables = new ArrayList<Runnable>();\r
+               for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
+                       RunnableCall runnableCall = runnableCalls.get(callIndex);\r
+                       Object bean = applicationContext.getBean(\r
+                                       runnableCall.getBeanName(), Runnable.class);\r
+                       runnables.add((Runnable) bean);\r
+               }\r
+               return runnables.iterator();\r
+       }\r
+\r
+       public Runnable getRunnable() {\r
+               if (runnableCalls.size() == 1)\r
+                       return runnables().next();\r
+               else\r
+                       throw new SlcException("There are " + runnableCalls.size()\r
+                                       + " runnables in flow " + getName());\r
+       }\r
+\r
+       @Override\r
+       public String toString() {\r
+               return new StringBuffer("RunnableCallFlow ").append(name).toString();\r
+       }\r
+\r
+       public ExecutionSpec getExecutionSpec() {\r
+               return executionSpec;\r
+       }\r
+\r
+       public String getName() {\r
+               return name;\r
+       }\r
+\r
+       public Object getParameter(String key) {\r
+               throw new SlcException("RunnableCallFlow have no parameters");\r
+       }\r
+\r
+       public String getPath() {\r
+               return path;\r
+       }\r
+\r
+       public Boolean isSetAsParameter(String key) {\r
+               // The ExecutionSpec having no attribute,\r
+               // always return false\r
+               return false;\r
+       }\r
+\r
+       public void setName(String name) {\r
+               this.name = name;\r
+       }\r
+\r
+       public void setPath(String path) {\r
+               this.path = path;\r
+       }\r
+\r
+       public void setExecutionContext(ExecutionContext executionContext) {\r
+               this.executionContext = executionContext;\r
+       }\r
+\r
+       public void setRunnableCalls(List<RunnableCall> runnableCalls) {\r
+               this.runnableCalls = runnableCalls;\r
+       }\r
+\r
+       public void setApplicationContext(ApplicationContext applicationContext) {\r
+               this.applicationContext = applicationContext;\r
+       }\r
+\r
+       public void setSharedContextValuesMap(Map<String, Object> contextValues) {\r
+               this.sharedContextValuesMap = contextValues;\r
+       }\r
+\r
+       public void setFailOnError(Boolean failOnError) {\r
+               this.failOnError = failOnError;\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableCallFlowDescriptor.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableCallFlowDescriptor.java
new file mode 100644 (file)
index 0000000..e0bbbdd
--- /dev/null
@@ -0,0 +1,70 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+/**\r
+ * Storage Class for information required to\r
+ * instantiate a <code>RunnableCallFlow</code>:\r
+ * bean name of the flow, \r
+ * path of the flow \r
+ * and list of <code>RunnableCall</code>. \r
+ *\r
+ */\r
+public class RunnableCallFlowDescriptor {\r
+       \r
+       /**\r
+        * Bean name of the flow to instantiate\r
+        */\r
+       private String beanName;\r
+       \r
+       /**\r
+        * Path of the flow to instantiate\r
+        */\r
+       private String path;\r
+       \r
+       /**\r
+        * List of <code>RunnableCall</code> \r
+        */\r
+       private List<RunnableCall> runnableCalls = new ArrayList<RunnableCall>();\r
+\r
+       public String getBeanName() {\r
+               return beanName;\r
+       }\r
+\r
+       public void setBeanName(String beanName) {\r
+               this.beanName = beanName;\r
+       }\r
+\r
+       public String getPath() {\r
+               return path;\r
+       }\r
+\r
+       public void setPath(String path) {\r
+               this.path = path;\r
+       }\r
+\r
+       public List<RunnableCall> getRunnableCalls() {\r
+               return runnableCalls;\r
+       }\r
+\r
+       public void setRunnableCalls(List<RunnableCall> runnableCalls) {\r
+               this.runnableCalls = runnableCalls;\r
+       }\r
+       \r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableDataNode.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableDataNode.java
new file mode 100644 (file)
index 0000000..51843dc
--- /dev/null
@@ -0,0 +1,74 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+/**\r
+ * Stores information relative to a Runnable.\r
+ * Allows to structure the information as a tree, each node\r
+ * storing data as a Map.\r
+ */\r
+public interface RunnableDataNode {\r
+\r
+       /**\r
+        * @return a Map containing the data associated with this node.\r
+        * Data associated with parent nodes are expected\r
+        * to be contained in the returned Map\r
+        */\r
+       public Map<String, Object> getData();   \r
+\r
+       /**\r
+        * @return the name of the bean to create.\r
+        * Can be null if no bean shall be created for the \r
+        * <code>RunnableDataNode</code> (e.g. is is a sub-node)\r
+        */\r
+       public String getBeanName();\r
+       \r
+       /**\r
+        * @return the path of the flow bean to create.\r
+        * Can be null if the bean to created is not an\r
+        * <code>ExecutionFlow</code> or if no bean shall be created for the \r
+        * <code>RunnableDataNode</code> (e.g. is is a sub-node)\r
+        */\r
+       public String getPath();\r
+               \r
+       /**\r
+        * @return whether the <code>RunnableDataNode</code> has\r
+        * children or not.\r
+        * Expected to be equivalent to <code>getChildren().empty()</code>\r
+        */\r
+       public boolean isLeaf();\r
+\r
+       /**\r
+        * @return the list of <code>RunnableDataNode</code> children.\r
+        * Can be empty. Shall not be null.\r
+        */\r
+       public List<RunnableDataNode> getChildren();\r
+       \r
+       /**\r
+        * @return the <code>RunnableDataNode</code> parent.\r
+        * Can be null if no parent is defined (top node).\r
+        */\r
+       public RunnableDataNode getParent();\r
+       \r
+       /**\r
+        * Sets the <code>RunnableDataNode</code> parent\r
+        * @param parent\r
+        */\r
+       public void setParent(RunnableDataNode parent); \r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableFactory.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/generator/RunnableFactory.java
new file mode 100644 (file)
index 0000000..2b37028
--- /dev/null
@@ -0,0 +1,29 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
+\r
+/**\r
+ * Interprets a <code>RunnableDataNode</code> by creating corresponding\r
+ * beans and registering them in a <code>BeanDefinitionRegistry</code>\r
+ *\r
+ */\r
+public interface RunnableFactory {\r
+\r
+       public void createAndRegisterRunnable(RunnableDataNode node,\r
+                       BeanDefinitionRegistry beanDefinitionRegistry);\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/runtime.xml b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/runtime.xml
new file mode 100644 (file)
index 0000000..33542ee
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007-2012 Argeo GmbH Licensed under the Apache License, 
+       Version 2.0 (the "License"); you may not use this file except in compliance 
+       with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
+       Unless required by applicable law or agreed to in writing, software distributed 
+       under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
+       OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
+       the specific language governing permissions and limitations under the License. -->
+<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under 
+       the Apache License, Version 2.0 (the "License"); you may not use this file 
+       except in compliance with the License. You may obtain a copy of the License 
+       at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
+       law or agreed to in writing, software distributed under the License is distributed 
+       on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
+       express or implied. See the License for the specific language governing permissions 
+       and limitations under the License. -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+       <description>Bare minimal runtime configuration. In general you will
+               want to use simple.xml instead.
+       </description>
+
+       <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
+               <property name="scopes">
+                       <map>
+                               <entry key="execution">
+                                       <bean class="org.argeo.slc.core.execution.ExecutionScope" />
+                               </entry>
+                       </map>
+               </property>
+       </bean>
+
+
+       <bean id="executionStack" class="org.argeo.slc.core.execution.DefaultExecutionStack"
+               scope="execution">
+               <aop:scoped-proxy proxy-target-class="false" />
+       </bean>
+
+       <bean id="instantiationManager" class="org.argeo.slc.core.execution.InstantiationManager" />
+
+       <bean class="org.argeo.slc.core.execution.ExecutionParameterPostProcessor">
+               <property name="executionContext" ref="executionContext" />
+               <property name="instantiationManager" ref="instantiationManager" />
+       </bean>
+
+       <!-- <bean class="org.argeo.slc.core.execution.ExecutionAspect"> -->
+       <!-- <property name="executionStack" ref="executionStack" /> -->
+       <!-- <property name="executionContext" ref="executionContext" /> -->
+       <!-- </bean> -->
+
+       <aop:aspectj-autoproxy />
+
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/simple.xml b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/simple.xml
new file mode 100644 (file)
index 0000000..ff243ba
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007-2012 Argeo GmbH Licensed under the Apache License, 
+       Version 2.0 (the "License"); you may not use this file except in compliance 
+       with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
+       Unless required by applicable law or agreed to in writing, software distributed 
+       under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
+       OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
+       the specific language governing permissions and limitations under the License. -->
+<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under 
+       the Apache License, Version 2.0 (the "License"); you may not use this file 
+       except in compliance with the License. You may obtain a copy of the License 
+       at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
+       law or agreed to in writing, software distributed under the License is distributed 
+       on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
+       express or implied. See the License for the specific language governing permissions 
+       and limitations under the License. -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+       <description>Default Capabilities</description>
+
+       <import resource="runtime.xml" />
+
+       <bean id="executionContext" class="org.argeo.slc.core.execution.MapExecutionContext"
+               scope="execution">
+               <aop:scoped-proxy proxy-target-class="false" />
+               <property name="executionStack" ref="executionStack" />
+       </bean>
+
+       <bean id="executionFlowDescriptorConverter"
+               class="org.argeo.slc.core.execution.DefaultExecutionFlowDescriptorConverter"></bean>
+
+       <bean
+               class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+               <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
+               <property name="ignoreUnresolvablePlaceholders" value="true" />
+       </bean>
+
+       <bean id="parameterRef" class="org.argeo.slc.core.execution.ParameterRef"
+               abstract="true">
+               <property name="instantiationManager" ref="instantiationManager" />
+       </bean>
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/specs.xml b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/specs.xml
new file mode 100644 (file)
index 0000000..7cc9604
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (C) 2007-2012 Argeo GmbH
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+            http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+       <bean id="specAttr.primitive" class="org.argeo.slc.core.execution.PrimitiveSpecAttribute"
+               abstract="true" />
+       <bean id="specAttr.resource" class="org.argeo.slc.core.execution.ResourceSpecAttribute"
+               abstract="true" />
+       <bean id="specAttr.ref" class="org.argeo.slc.core.execution.RefSpecAttribute"
+               abstract="true" />
+
+       <bean id="slcTemplate.simpleFlow" class="org.argeo.slc.core.execution.DefaultExecutionFlow"
+               abstract="true" />
+       <bean id="slcTemplate.simpleSpec" class="org.argeo.slc.core.execution.DefaultExecutionSpec"
+               abstract="true" />
+
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/spring.xml b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/spring.xml
new file mode 100644 (file)
index 0000000..de1c06b
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (C) 2007-2012 Argeo GmbH
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+            http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under 
+       the Apache License, Version 2.0 (the "License"); you may not use this file 
+       except in compliance with the License. You may obtain a copy of the License 
+       at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
+       law or agreed to in writing, software distributed under the License is distributed 
+       on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
+       express or implied. See the License for the specific language governing permissions 
+       and limitations under the License. -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+       <description>
+               Simple runtime enriched with defaults and templates used
+               to simplify XML files. These templates have been deprecated by the
+               custom XML namespace and will be removed in SLC 2.x. Use the XML
+               namespace instead.
+       </description>
+
+       <import resource="simple.xml" />
+
+       <import resource="specs.xml" />
+       <import resource="templates.xml" />
+       <import resource="defaults.xml" />
+       <import resource="utils.xml" />
+       <import resource="tasks/core.xml" />
+
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/CloseTestResult.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/CloseTestResult.java
new file mode 100644 (file)
index 0000000..43b2961
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import org.argeo.slc.test.TestResult;
+
+public class CloseTestResult implements Runnable {
+       private TestResult testResult;
+
+       public void run() {
+               testResult.close();
+       }
+
+       public void setTestResult(TestResult testResult) {
+               this.testResult = testResult;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/Echo.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/Echo.java
new file mode 100644 (file)
index 0000000..d47149b
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.core.io.Resource;
+
+public class Echo implements Runnable {
+       private final static Log defaultLog = LogFactory.getLog(Echo.class);
+       private Resource writeTo = null;
+
+       private Log log;
+       private Object message;
+
+       public void run() {
+               log().info(message);
+
+               if (writeTo != null) {
+                       try {
+                               File file = writeTo.getFile();
+                               if (log().isDebugEnabled())
+                                       log().debug("Write to " + file);
+                               if (message != null)
+                                       FileUtils.writeStringToFile(file, message.toString());
+                       } catch (IOException e) {
+                               throw new SlcException("Could not write to " + writeTo, e);
+                       }
+               }
+       }
+
+       private Log log() {
+               return log != null ? log : defaultLog;
+       }
+
+       public void setMessage(Object message) {
+               this.message = message;
+       }
+
+       public void setWriteTo(Resource writeTo) {
+               this.writeTo = writeTo;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/If.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/If.java
new file mode 100644 (file)
index 0000000..0d22e43
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import org.argeo.slc.SlcException;
+
+/** Conditional execution */
+public class If implements Runnable {
+       private Boolean is;
+       private Boolean not;
+       private Runnable then;
+       private Runnable els;
+
+       public void run() {
+               if (is == null && not == null)
+                       throw new SlcException("No condition set");
+               if (is != null && not != null)
+                       throw new SlcException("Both is and not cannot be set");
+
+               boolean bool = (is != null ? is : !not);
+               if (bool) {
+                       if (then != null)
+                               then.run();
+               } else {
+                       if (els != null)
+                               els.run();
+               }
+
+       }
+
+       public void setIs(Boolean bool) {
+               this.is = bool;
+       }
+
+       public void setThen(Runnable then) {
+               this.then = then;
+       }
+
+       public void setEls(Runnable els) {
+               this.els = els;
+       }
+
+       public Boolean getNot() {
+               return not;
+       }
+
+       public void setNot(Boolean not) {
+               this.not = not;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/JvmProcess.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/JvmProcess.java
new file mode 100644 (file)
index 0000000..01f1101
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.io.Resource;
+
+/** A Java Virtual Machine process. */
+public class JvmProcess extends SystemCall implements InitializingBean {
+       private Properties systemProperties = new Properties();
+       private List<Resource> classpath = new ArrayList<Resource>();
+       private List<Resource> pBootClasspath = new ArrayList<Resource>();
+       private Resource jvm = null;
+       private String mainClass;
+       private String mainJar;
+       private List<String> jvmArgs = new ArrayList<String>();
+       private List<String> args = new ArrayList<String>();
+
+       private String systemPropertiesFileProperty = null;
+       private String systemPropertiesFileDir = null;
+       private String systemPropertiesFileName = null;
+
+       public void afterPropertiesSet() throws Exception {
+               List<Object> command = new ArrayList<Object>();
+               if (jvm != null)
+                       command.add(asFile(jvm).getPath());
+               else
+                       command.add("java");
+
+               if (pBootClasspath.size() > 0) {
+                       StringBuffer buf = new StringBuffer("-Xbootclasspath/p:");
+                       Boolean first = true;
+                       for (Resource res : pBootClasspath) {
+                               if (first)
+                                       first = false;
+                               else
+                                       buf.append(File.pathSeparatorChar);
+
+                               buf.append(asFile(res));
+                       }
+                       command.add(buf.toString());
+               }
+
+               for (String jvmArg : jvmArgs) {
+                       command.add(jvmArg);
+               }
+
+               if (classpath.size() > 0) {
+                       command.add("-cp");
+                       StringBuffer buf = new StringBuffer("");
+                       for (Resource res : classpath) {
+                               if (buf.length() != 0)
+                                       buf.append(File.pathSeparatorChar);
+                               buf.append(asFile(res));
+                       }
+                       command.add(buf.toString());
+               }
+
+               if (systemPropertiesFileProperty == null) {
+                       // pass system properties as argument
+                       for (Map.Entry<Object, Object> entry : systemProperties.entrySet()) {
+                               command.add("-D" + entry.getKey() + "=" + entry.getValue());
+                       }
+               } else {
+                       // write system properties in a file to work around OS limitations
+                       // with command line (e.g. Win XP)
+                       String dir = systemPropertiesFileDir;
+                       if (dir == null)
+                               dir = getExecDirToUse();
+                       String fileName = systemPropertiesFileName;
+                       if (fileName == null)
+                               fileName = systemPropertiesFileProperty + ".properties";
+
+                       // Write file
+                       FileOutputStream fos = null;
+                       File file = new File(dir + File.separator + fileName);
+                       try {
+
+                               if (!file.getParentFile().exists())
+                                       file.getParentFile().mkdirs();
+                               fos = new FileOutputStream(file);
+                               systemProperties.store(fos, "Automatically generated by "
+                                               + getClass());
+                               command.add("-D" + systemPropertiesFileProperty + "="
+                                               + file.getCanonicalPath());
+                       } catch (IOException e) {
+                               throw new SlcException("Cannot write to system properties to "
+                                               + file, e);
+                       } finally {
+                               IOUtils.closeQuietly(fos);
+                       }
+               }
+
+               // Program
+               if (mainClass != null) {
+                       command.add(mainClass);
+               } else if (mainJar != null) {
+                       command.add("-jar");
+                       command.add(mainJar);
+               } else {
+                       throw new SlcException("No main class or jar defined");
+               }
+
+               for (String arg : args) {
+                       command.add(arg);
+               }
+
+               setCommand(command);
+       }
+
+       protected File asFile(Resource res) {
+               try {
+                       return res.getFile();
+               } catch (FileNotFoundException e) {
+                       return copyToTempFile(res);
+               } catch (IOException e) {
+                       throw new SlcException("Cannot convert resource to file", e);
+               }
+
+       }
+
+       protected File copyToTempFile(Resource res) {
+               File tempFile;
+               FileOutputStream fos;
+               try {
+                       tempFile = File.createTempFile("slcJvmProcess-", res.getFilename());
+                       tempFile.deleteOnExit();
+                       fos = new FileOutputStream(tempFile);
+                       IOUtils.copy(res.getInputStream(), fos);
+               } catch (IOException e) {
+                       throw new SlcException("Cannot copy " + res + " to temp file.", e);
+               }
+               IOUtils.closeQuietly(fos);
+               return tempFile;
+       }
+
+       /** Append the argument (for chaining) */
+       @Override
+       public SystemCall arg(String arg) {
+               args.add(arg);
+               return this;
+       }
+
+       /** Append the argument (for chaining) */
+       @Override
+       public SystemCall arg(String arg, String value) {
+               args.add(arg);
+               args.add(value);
+               return this;
+       }
+
+       public Properties getSystemProperties() {
+               return systemProperties;
+       }
+
+       public void setSystemProperties(Properties systemProperties) {
+               this.systemProperties = systemProperties;
+       }
+
+       public List<Resource> getClasspath() {
+               return classpath;
+       }
+
+       public void setClasspath(List<Resource> classpath) {
+               this.classpath = classpath;
+       }
+
+       public List<Resource> getPBootClasspath() {
+               return pBootClasspath;
+       }
+
+       public void setPBootClasspath(List<Resource> bootClasspath) {
+               pBootClasspath = bootClasspath;
+       }
+
+       public Resource getJvm() {
+               return jvm;
+       }
+
+       public void setJvm(Resource jvm) {
+               this.jvm = jvm;
+       }
+
+       public String getMainClass() {
+               return mainClass;
+       }
+
+       public void setMainClass(String mainClass) {
+               this.mainClass = mainClass;
+       }
+
+       public String getMainJar() {
+               return mainJar;
+       }
+
+       public void setMainJar(String mainJar) {
+               this.mainJar = mainJar;
+       }
+
+       public List<String> getJvmArgs() {
+               return jvmArgs;
+       }
+
+       public void setJvmArgs(List<String> jvmArgs) {
+               this.jvmArgs = jvmArgs;
+       }
+
+       public List<String> getArgs() {
+               return args;
+       }
+
+       public void setArgs(List<String> args) {
+               this.args = args;
+       }
+
+       public void setSystemPropertiesFileProperty(
+                       String systemPropertiesFilePropertyName) {
+               this.systemPropertiesFileProperty = systemPropertiesFilePropertyName;
+       }
+
+       public void setSystemPropertiesFileDir(String systemPropertiesFileDir) {
+               this.systemPropertiesFileDir = systemPropertiesFileDir;
+       }
+
+       public void setSystemPropertiesFileName(String systemPropertiesFileName) {
+               this.systemPropertiesFileName = systemPropertiesFileName;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/MergedLists.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/MergedLists.java
new file mode 100644 (file)
index 0000000..e1740e6
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.FactoryBean;
+
+/** Merge the provided lists in one single list, in the order provided. */
+public class MergedLists implements FactoryBean<List<Object>> {
+       private List<List<Object>> lists = new ArrayList<List<Object>>();
+
+       public void setLists(List<List<Object>> lists) {
+               this.lists = lists;
+       }
+
+       public List<Object> getObject() throws Exception {
+               List<Object> merged = new ArrayList<Object>();
+               for (List<Object> lst : lists) {
+                       merged.addAll(lst);
+               }
+               return merged;
+       }
+
+       public Class<?> getObjectType() {
+               return List.class;
+       }
+
+       public boolean isSingleton() {
+               return false;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/MethodCall.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/MethodCall.java
new file mode 100644 (file)
index 0000000..e4fa772
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.util.Assert;
+import org.springframework.util.ReflectionUtils;
+
+public class MethodCall implements Runnable {
+       private Object target;
+       private String method;
+       private List<Object> args = new ArrayList<Object>();
+
+       public void run() {
+               Assert.notNull(target, "target");
+               Assert.notNull(method, "method");
+               Method methodRef = ReflectionUtils
+                               .findMethod(target.getClass(), method);
+               if (args.size() == 0)
+                       ReflectionUtils.invokeMethod(methodRef, target);
+               else
+                       ReflectionUtils.invokeMethod(methodRef, methodRef, args.toArray());
+       }
+
+       public void setTarget(Object target) {
+               this.target = target;
+       }
+
+       public void setMethod(String method) {
+               this.method = method;
+       }
+
+       public void setArgs(List<Object> args) {
+               this.args = args;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/OverrideContextAware.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/OverrideContextAware.java
new file mode 100644 (file)
index 0000000..9afa846
--- /dev/null
@@ -0,0 +1,72 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.tasks;\r
+\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.core.test.context.SimpleContextAware;\r
+import org.argeo.slc.test.context.ContextAware;\r
+\r
+/**\r
+ * Overrides Values and Expected values of a target \r
+ * <code>SimpleContextAware</code> with the corresponding\r
+ * values and expected values of a source <code>ContextAware</code>\r
+ *\r
+ */\r
+public class OverrideContextAware implements Runnable {\r
+\r
+       private ContextAware source;\r
+\r
+       private SimpleContextAware target;\r
+       \r
+       /**\r
+        * Whether an exception shall be thrown if a value\r
+        * or expected value of the source is not defined\r
+        * in the target\r
+        */\r
+       private Boolean failIfUndefinedInSource = true;\r
+       \r
+       public void run() {\r
+               // override values\r
+               if(source.getValues() != null)\r
+                       for(String key : source.getValues().keySet()) {\r
+                               if(failIfUndefinedInSource && !target.getValues().containsKey(key)) {\r
+                                       throw new SlcException("No entry in target values for key '" + key + "'");\r
+                               }\r
+                               target.getValues().put(key, source.getValues().get(key));\r
+                       }\r
+               \r
+               // override expected values\r
+               if(source.getExpectedValues() != null)\r
+                       for(String key : source.getExpectedValues().keySet()) {\r
+                               if(failIfUndefinedInSource && !target.getExpectedValues().containsKey(key)) {\r
+                                       throw new SlcException("No entry in target expected values for key '" + key + "'");\r
+                               }\r
+                               target.getExpectedValues().put(key, source.getExpectedValues().get(key));\r
+                       }               \r
+       }       \r
+       \r
+       public void setSource(ContextAware source) {\r
+               this.source = source;\r
+       }\r
+\r
+       public void setTarget(SimpleContextAware target) {\r
+               this.target = target;\r
+       }\r
+\r
+       public void setFailIfUndefinedInSource(Boolean failIfUndefinedInSource) {\r
+               this.failIfUndefinedInSource = failIfUndefinedInSource;\r
+       }       \r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/SystemCall.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/SystemCall.java
new file mode 100644 (file)
index 0000000..27cc59d
--- /dev/null
@@ -0,0 +1,782 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteException;
+import org.apache.commons.exec.ExecuteResultHandler;
+import org.apache.commons.exec.ExecuteStreamHandler;
+import org.apache.commons.exec.ExecuteWatchdog;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.LogOutputStream;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.apache.commons.exec.ShutdownHookProcessDestroyer;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+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.test.SimpleResultPart;
+import org.argeo.slc.test.TestResult;
+import org.argeo.slc.test.TestStatus;
+import org.springframework.core.io.Resource;
+
+/** Execute an OS specific system call. */
+public class SystemCall implements Runnable {
+       public final static String LOG_STDOUT = "System.out";
+
+       private final Log log = LogFactory.getLog(getClass());
+
+       private String execDir;
+
+       private String cmd = null;
+       private List<Object> command = null;
+
+       private Executor executor = new DefaultExecutor();
+       private Boolean synchronous = true;
+
+       private String stdErrLogLevel = "ERROR";
+       private String stdOutLogLevel = "INFO";
+
+       private Resource stdOutFile = null;
+       private Resource stdErrFile = null;
+
+       private Resource stdInFile = null;
+       /**
+        * If no {@link #stdInFile} provided, writing to this stream will write to
+        * the stdin of the process.
+        */
+       private OutputStream stdInSink = null;
+
+       private Boolean redirectStdOut = false;
+
+       private List<SystemCallOutputListener> outputListeners = Collections
+                       .synchronizedList(new ArrayList<SystemCallOutputListener>());
+
+       private Map<String, List<Object>> osCommands = new HashMap<String, List<Object>>();
+       private Map<String, String> osCmds = new HashMap<String, String>();
+       private Map<String, String> environmentVariables = new HashMap<String, String>();
+
+       private Boolean logCommand = false;
+       private Boolean redirectStreams = true;
+       private Boolean exceptionOnFailed = true;
+       private Boolean mergeEnvironmentVariables = true;
+
+//     private Authentication authentication;
+
+       private String osConsole = null;
+       private String generateScript = null;
+
+       /** 24 hours */
+       private Long watchdogTimeout = 24 * 60 * 60 * 1000l;
+
+       private TestResult testResult;
+
+       private ExecutionResources executionResources;
+
+       /** Sudo the command, as root if empty or as user if not. */
+       private String sudo = null;
+       // TODO make it more secure and robust, test only once
+       private final String sudoPrompt = UUID.randomUUID().toString();
+       private String askPassProgram = "/usr/libexec/openssh/ssh-askpass";
+       @SuppressWarnings("unused")
+       private boolean firstLine = true;
+       @SuppressWarnings("unused")
+       private CallbackHandler callbackHandler;
+       /** Chroot to the this path (must not be empty) */
+       private String chroot = null;
+
+       // Current
+       /** Current watchdog, null if process is completed */
+       ExecuteWatchdog currentWatchdog = null;
+
+       /** Empty constructor */
+       public SystemCall() {
+
+       }
+
+       /**
+        * Constructor based on the provided command list.
+        * 
+        * @param command
+        *            the command list
+        */
+       public SystemCall(List<Object> command) {
+               this.command = command;
+       }
+
+       /**
+        * Constructor based on the provided command.
+        * 
+        * @param cmd
+        *            the command. If the provided string contains no space a
+        *            command list is initialized with the argument as first
+        *            component (useful for chained construction)
+        */
+       public SystemCall(String cmd) {
+               if (cmd.indexOf(' ') < 0) {
+                       command = new ArrayList<Object>();
+                       command.add(cmd);
+               } else {
+                       this.cmd = cmd;
+               }
+       }
+
+       /** Executes the system call. */
+       public void run() {
+//             authentication = SecurityContextHolder.getContext().getAuthentication();
+
+               // Manage streams
+               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, true);
+               } else {
+                       if (stdOutFile != null && !redirectStdOut)
+                               stdErrWriter = createWriter(stdOutFile, true);
+               }
+
+               try {
+                       if (stdInFile != null)
+                               stdInStream = stdInFile.getInputStream();
+                       else {
+                               stdInStream = new PipedInputStream();
+                               stdInSink = new PipedOutputStream(
+                                               (PipedInputStream) stdInStream);
+                       }
+               } catch (IOException e2) {
+                       throw new SlcException("Cannot open a stream for " + stdInFile, e2);
+               }
+
+               if (log.isTraceEnabled()) {
+                       log.debug("os.name=" + System.getProperty("os.name"));
+                       log.debug("os.arch=" + System.getProperty("os.arch"));
+                       log.debug("os.version=" + System.getProperty("os.version"));
+               }
+
+               // Execution directory
+               File dir = new File(getExecDirToUse());
+               // if (!dir.exists())
+               // dir.mkdirs();
+
+               // Watchdog to check for lost processes
+               Executor executorToUse;
+               if (executor != null)
+                       executorToUse = executor;
+               else
+                       executorToUse = new DefaultExecutor();
+               executorToUse.setWatchdog(createWatchdog());
+
+               if (redirectStreams) {
+                       // Redirect standard streams
+                       executorToUse.setStreamHandler(createExecuteStreamHandler(
+                                       stdOutWriter, stdOutputStream, stdErrWriter, stdInStream));
+               } else {
+                       // Dummy stream handler (otherwise pump is used)
+                       executorToUse.setStreamHandler(new DummyexecuteStreamHandler());
+               }
+
+               executorToUse.setProcessDestroyer(new ShutdownHookProcessDestroyer());
+               executorToUse.setWorkingDirectory(dir);
+
+               // Command line to use
+               final CommandLine commandLine = createCommandLine();
+               if (logCommand)
+                       log.info("Execute command:\n" + commandLine
+                                       + "\n in working directory: \n" + dir + "\n");
+
+               // Env variables
+               Map<String, String> environmentVariablesToUse = null;
+               environmentVariablesToUse = new HashMap<String, String>();
+               if (mergeEnvironmentVariables)
+                       environmentVariablesToUse.putAll(System.getenv());
+               if (environmentVariables.size() > 0)
+                       environmentVariablesToUse.putAll(environmentVariables);
+
+               // Execute
+               ExecuteResultHandler executeResultHandler = createExecuteResultHandler(commandLine);
+
+               //
+               // THE EXECUTION PROPER
+               //
+               try {
+                       if (synchronous)
+                               try {
+                                       int exitValue = executorToUse.execute(commandLine,
+                                                       environmentVariablesToUse);
+                                       executeResultHandler.onProcessComplete(exitValue);
+                               } catch (ExecuteException e1) {
+                                       if (e1.getExitValue() == Executor.INVALID_EXITVALUE) {
+                                               Thread.currentThread().interrupt();
+                                               return;
+                                       }
+                                       // Sleep 1s in order to make sure error logs are flushed
+                                       Thread.sleep(1000);
+                                       executeResultHandler.onProcessFailed(e1);
+                               }
+                       else
+                               executorToUse.execute(commandLine, environmentVariablesToUse,
+                                               executeResultHandler);
+               } catch (SlcException e) {
+                       throw e;
+               } catch (Exception e) {
+                       throw new SlcException("Could not execute command " + commandLine,
+                                       e);
+               } finally {
+                       IOUtils.closeQuietly(stdOutWriter);
+                       IOUtils.closeQuietly(stdErrWriter);
+                       IOUtils.closeQuietly(stdInStream);
+                       IOUtils.closeQuietly(stdInSink);
+               }
+
+       }
+
+       public synchronized String function() {
+               final StringBuffer buf = new StringBuffer("");
+               SystemCallOutputListener tempOutputListener = new SystemCallOutputListener() {
+                       private Long lineCount = 0l;
+
+                       public void newLine(SystemCall systemCall, String line,
+                                       Boolean isError) {
+                               if (!isError) {
+                                       if (lineCount != 0l)
+                                               buf.append('\n');
+                                       buf.append(line);
+                                       lineCount++;
+                               }
+                       }
+               };
+               addOutputListener(tempOutputListener);
+               run();
+               removeOutputListener(tempOutputListener);
+               return buf.toString();
+       }
+
+       public String asCommand() {
+               return createCommandLine().toString();
+       }
+
+       @Override
+       public String toString() {
+               return asCommand();
+       }
+
+       /**
+        * Build a command line based on the properties. Can be overridden by
+        * specific command wrappers.
+        */
+       protected CommandLine createCommandLine() {
+               // Check if an OS specific command overrides
+               String osName = System.getProperty("os.name");
+               List<Object> commandToUse = null;
+               if (osCommands.containsKey(osName))
+                       commandToUse = osCommands.get(osName);
+               else
+                       commandToUse = command;
+               String cmdToUse = null;
+               if (osCmds.containsKey(osName))
+                       cmdToUse = osCmds.get(osName);
+               else
+                       cmdToUse = cmd;
+
+               CommandLine commandLine = null;
+
+               // Which command definition to use
+               if (commandToUse == null && cmdToUse == null)
+                       throw new SlcException("Please specify a command.");
+               else if (commandToUse != null && cmdToUse != null)
+                       throw new SlcException(
+                                       "Specify the command either as a line or as a list.");
+               else if (cmdToUse != null) {
+                       if (chroot != null && !chroot.trim().equals(""))
+                               cmdToUse = "chroot \"" + chroot + "\" " + cmdToUse;
+                       if (sudo != null) {
+                               environmentVariables.put("SUDO_ASKPASS", askPassProgram);
+                               if (!sudo.trim().equals(""))
+                                       cmdToUse = "sudo -p " + sudoPrompt + " -u " + sudo + " "
+                                                       + cmdToUse;
+                               else
+                                       cmdToUse = "sudo -p " + sudoPrompt + " " + cmdToUse;
+                       }
+
+                       // GENERATE COMMAND LINE
+                       commandLine = CommandLine.parse(cmdToUse);
+               } else if (commandToUse != null) {
+                       if (commandToUse.size() == 0)
+                               throw new SlcException("Command line is empty.");
+
+                       if (chroot != null && sudo != null) {
+                               commandToUse.add(0, "chroot");
+                               commandToUse.add(1, chroot);
+                       }
+
+                       if (sudo != null) {
+                               environmentVariables.put("SUDO_ASKPASS", askPassProgram);
+                               commandToUse.add(0, "sudo");
+                               commandToUse.add(1, "-p");
+                               commandToUse.add(2, sudoPrompt);
+                               if (!sudo.trim().equals("")) {
+                                       commandToUse.add(3, "-u");
+                                       commandToUse.add(4, sudo);
+                               }
+                       }
+
+                       // GENERATE COMMAND LINE
+                       commandLine = new CommandLine(commandToUse.get(0).toString());
+
+                       for (int i = 1; i < commandToUse.size(); i++) {
+                               if (log.isTraceEnabled())
+                                       log.debug(commandToUse.get(i));
+                               commandLine.addArgument(commandToUse.get(i).toString());
+                       }
+               } else {
+                       // all cases covered previously
+                       throw new UnsupportedException();
+               }
+
+               if (generateScript != null) {
+                       File scriptFile = new File(getExecDirToUse() + File.separator
+                                       + generateScript);
+                       try {
+                               FileUtils.writeStringToFile(scriptFile,
+                                               (osConsole != null ? osConsole + " " : "")
+                                                               + commandLine.toString());
+                       } catch (IOException e) {
+                               throw new SlcException("Could not generate script "
+                                               + scriptFile, e);
+                       }
+                       commandLine = new CommandLine(scriptFile);
+               } else {
+                       if (osConsole != null)
+                               commandLine = CommandLine.parse(osConsole + " "
+                                               + commandLine.toString());
+               }
+
+               return commandLine;
+       }
+
+       /**
+        * Creates a {@link PumpStreamHandler} which redirects streams to the custom
+        * logging mechanism.
+        */
+       protected ExecuteStreamHandler createExecuteStreamHandler(
+                       final Writer stdOutWriter, final OutputStream stdOutputStream,
+                       final Writer stdErrWriter, final InputStream stdInStream) {
+
+               // Log writers
+               OutputStream stdout = stdOutputStream != null ? stdOutputStream
+                               : new LogOutputStream() {
+                                       protected void processLine(String line, int level) {
+                                               // if (firstLine) {
+                                               // if (sudo != null && callbackHandler != null
+                                               // && line.startsWith(sudoPrompt)) {
+                                               // try {
+                                               // PasswordCallback pc = new PasswordCallback(
+                                               // "sudo password", false);
+                                               // Callback[] cbs = { pc };
+                                               // callbackHandler.handle(cbs);
+                                               // char[] pwd = pc.getPassword();
+                                               // char[] arr = Arrays.copyOf(pwd,
+                                               // pwd.length + 1);
+                                               // arr[arr.length - 1] = '\n';
+                                               // IOUtils.write(arr, stdInSink);
+                                               // stdInSink.flush();
+                                               // } catch (Exception e) {
+                                               // throw new SlcException(
+                                               // "Cannot retrieve sudo password", e);
+                                               // }
+                                               // }
+                                               // firstLine = false;
+                                               // }
+
+                                               if (line != null && !line.trim().equals(""))
+                                                       logStdOut(line);
+
+                                               if (stdOutWriter != null)
+                                                       appendLineToFile(stdOutWriter, line);
+                                       }
+                               };
+
+               OutputStream stderr = new LogOutputStream() {
+                       protected void processLine(String line, int level) {
+                               if (line != null && !line.trim().equals(""))
+                                       logStdErr(line);
+                               if (stdErrWriter != null)
+                                       appendLineToFile(stdErrWriter, line);
+                       }
+               };
+
+               PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(stdout,
+                               stderr, stdInStream) {
+
+                       @Override
+                       public void stop() throws IOException {
+                               // prevents the method to block when joining stdin
+                               if (stdInSink != null)
+                                       IOUtils.closeQuietly(stdInSink);
+
+                               super.stop();
+                       }
+               };
+               return pumpStreamHandler;
+       }
+
+       /** Creates the default {@link ExecuteResultHandler}. */
+       protected ExecuteResultHandler createExecuteResultHandler(
+                       final CommandLine commandLine) {
+               return new ExecuteResultHandler() {
+
+                       public void onProcessComplete(int exitValue) {
+                               String msg = "System call '" + commandLine
+                                               + "' properly completed.";
+                               if (log.isTraceEnabled())
+                                       log.trace(msg);
+                               if (testResult != null) {
+                                       forwardPath(testResult);
+                                       testResult.addResultPart(new SimpleResultPart(
+                                                       TestStatus.PASSED, msg));
+                               }
+                               releaseWatchdog();
+                       }
+
+                       public void onProcessFailed(ExecuteException e) {
+
+                               String msg = "System call '" + commandLine + "' failed.";
+                               if (testResult != null) {
+                                       forwardPath(testResult);
+                                       testResult.addResultPart(new SimpleResultPart(
+                                                       TestStatus.ERROR, msg, e));
+                               } else {
+                                       if (exceptionOnFailed)
+                                               throw new SlcException(msg, e);
+                                       else
+                                               log.error(msg, e);
+                               }
+                               releaseWatchdog();
+                       }
+               };
+       }
+
+       @Deprecated
+       protected void forwardPath(TestResult testResult) {
+               // TODO: allocate a TreeSPath
+       }
+
+       /**
+        * Shortcut method getting the execDir to use
+        */
+       protected String getExecDirToUse() {
+               try {
+                       if (execDir != null) {
+                               return execDir;
+                       }
+                       return System.getProperty("user.dir");
+               } catch (Exception e) {
+                       throw new SlcException("Cannot find exec dir", e);
+               }
+       }
+
+       protected void logStdOut(String line) {
+               for (SystemCallOutputListener outputListener : outputListeners)
+                       outputListener.newLine(this, line, false);
+               log(stdOutLogLevel, line);
+       }
+
+       protected void logStdErr(String line) {
+               for (SystemCallOutputListener outputListener : outputListeners)
+                       outputListener.newLine(this, line, true);
+               log(stdErrLogLevel, line);
+       }
+
+       /** Log from the underlying streams. */
+       protected void log(String logLevel, String line) {
+               // TODO optimize
+//             if (SecurityContextHolder.getContext().getAuthentication() == null) {
+//                     SecurityContextHolder.getContext()
+//                                     .setAuthentication(authentication);
+//             }
+
+               if ("ERROR".equals(logLevel))
+                       log.error(line);
+               else if ("WARN".equals(logLevel))
+                       log.warn(line);
+               else if ("INFO".equals(logLevel))
+                       log.info(line);
+               else if ("DEBUG".equals(logLevel))
+                       log.debug(line);
+               else if ("TRACE".equals(logLevel))
+                       log.trace(line);
+               else if (LOG_STDOUT.equals(logLevel))
+                       System.out.println(line);
+               else if ("System.err".equals(logLevel))
+                       System.err.println(line);
+               else
+                       throw new SlcException("Unknown log level " + logLevel);
+       }
+
+       /** Append line to a log file. */
+       protected void appendLineToFile(Writer writer, String line) {
+               try {
+                       writer.append(line).append('\n');
+               } catch (IOException e) {
+                       log.error("Cannot write to log file", e);
+               }
+       }
+
+       /** Creates the writer for the output/err files. */
+       protected Writer createWriter(Resource target, Boolean append) {
+               FileWriter writer = null;
+               try {
+
+                       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 get file for " + target, e);
+                       IOUtils.closeQuietly(writer);
+               }
+               return writer;
+       }
+
+       /** Creates an outputstream for the output/err files. */
+       protected OutputStream createOutputStream(Resource target) {
+               FileOutputStream out = null;
+               try {
+
+                       final File file;
+                       if (executionResources != null)
+                               file = new File(executionResources.getAsOsPath(target, true));
+                       else
+                               file = target.getFile();
+                       out = new FileOutputStream(file, false);
+               } catch (IOException e) {
+                       log.error("Cannot get file for " + target, e);
+                       IOUtils.closeQuietly(out);
+               }
+               return out;
+       }
+
+       /** Append the argument (for chaining) */
+       public SystemCall arg(String arg) {
+               if (command == null)
+                       command = new ArrayList<Object>();
+               command.add(arg);
+               return this;
+       }
+
+       /** Append the argument (for chaining) */
+       public SystemCall arg(String arg, String value) {
+               if (command == null)
+                       command = new ArrayList<Object>();
+               command.add(arg);
+               command.add(value);
+               return this;
+       }
+
+       // CONTROL
+       public synchronized Boolean isRunning() {
+               return currentWatchdog != null;
+       }
+
+       private synchronized ExecuteWatchdog createWatchdog() {
+//             if (currentWatchdog != null)
+//                     throw new SlcException("A process is already being monitored");
+               currentWatchdog = new ExecuteWatchdog(watchdogTimeout);
+               return currentWatchdog;
+       }
+
+       private synchronized void releaseWatchdog() {
+               currentWatchdog = null;
+       }
+
+       public synchronized void kill() {
+               if (currentWatchdog != null)
+                       currentWatchdog.destroyProcess();
+       }
+
+       /** */
+       public void setCmd(String command) {
+               this.cmd = command;
+       }
+
+       public void setCommand(List<Object> command) {
+               this.command = command;
+       }
+
+       public void setExecDir(String execdir) {
+               this.execDir = execdir;
+       }
+
+       public void setStdErrLogLevel(String stdErrLogLevel) {
+               this.stdErrLogLevel = stdErrLogLevel;
+       }
+
+       public void setStdOutLogLevel(String stdOutLogLevel) {
+               this.stdOutLogLevel = stdOutLogLevel;
+       }
+
+       public void setSynchronous(Boolean synchronous) {
+               this.synchronous = synchronous;
+       }
+
+       public void setOsCommands(Map<String, List<Object>> osCommands) {
+               this.osCommands = osCommands;
+       }
+
+       public void setOsCmds(Map<String, String> osCmds) {
+               this.osCmds = osCmds;
+       }
+
+       public void setEnvironmentVariables(Map<String, String> environmentVariables) {
+               this.environmentVariables = environmentVariables;
+       }
+
+       public Map<String, String> getEnvironmentVariables() {
+               return environmentVariables;
+       }
+
+       public void setWatchdogTimeout(Long watchdogTimeout) {
+               this.watchdogTimeout = watchdogTimeout;
+       }
+
+       public void setStdOutFile(Resource stdOutFile) {
+               this.stdOutFile = stdOutFile;
+       }
+
+       public void setStdErrFile(Resource stdErrFile) {
+               this.stdErrFile = stdErrFile;
+       }
+
+       public void setStdInFile(Resource stdInFile) {
+               this.stdInFile = stdInFile;
+       }
+
+       public void setTestResult(TestResult testResult) {
+               this.testResult = testResult;
+       }
+
+       public void setLogCommand(Boolean logCommand) {
+               this.logCommand = logCommand;
+       }
+
+       public void setRedirectStreams(Boolean redirectStreams) {
+               this.redirectStreams = redirectStreams;
+       }
+
+       public void setExceptionOnFailed(Boolean exceptionOnFailed) {
+               this.exceptionOnFailed = exceptionOnFailed;
+       }
+
+       public void setMergeEnvironmentVariables(Boolean mergeEnvironmentVariables) {
+               this.mergeEnvironmentVariables = mergeEnvironmentVariables;
+       }
+
+       public void setOsConsole(String osConsole) {
+               this.osConsole = osConsole;
+       }
+
+       public void setGenerateScript(String generateScript) {
+               this.generateScript = generateScript;
+       }
+
+       public void setExecutionResources(ExecutionResources executionResources) {
+               this.executionResources = executionResources;
+       }
+
+       public void setRedirectStdOut(Boolean redirectStdOut) {
+               this.redirectStdOut = redirectStdOut;
+       }
+
+       public void addOutputListener(SystemCallOutputListener outputListener) {
+               outputListeners.add(outputListener);
+       }
+
+       public void removeOutputListener(SystemCallOutputListener outputListener) {
+               outputListeners.remove(outputListener);
+       }
+
+       public void setOutputListeners(
+                       List<SystemCallOutputListener> outputListeners) {
+               this.outputListeners = outputListeners;
+       }
+
+       public void setExecutor(Executor executor) {
+               this.executor = executor;
+       }
+
+       public void setSudo(String sudo) {
+               this.sudo = sudo;
+       }
+
+       public void setCallbackHandler(CallbackHandler callbackHandler) {
+               this.callbackHandler = callbackHandler;
+       }
+
+       public void setChroot(String chroot) {
+               this.chroot = chroot;
+       }
+
+       private class DummyexecuteStreamHandler implements ExecuteStreamHandler {
+
+               public void setProcessErrorStream(InputStream is) throws IOException {
+               }
+
+               public void setProcessInputStream(OutputStream os) throws IOException {
+               }
+
+               public void setProcessOutputStream(InputStream is) throws IOException {
+               }
+
+               public void start() throws IOException {
+               }
+
+               public void stop() {
+               }
+
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/SystemCallOutputListener.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/SystemCallOutputListener.java
new file mode 100644 (file)
index 0000000..b28f1ad
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+public interface SystemCallOutputListener {
+       public void newLine(SystemCall systemCall, String line, Boolean isError);
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/UploadAttachments.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/UploadAttachments.java
new file mode 100644 (file)
index 0000000..13cc519
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.attachment.Attachment;
+import org.argeo.slc.core.attachment.AttachmentUploader;
+import org.argeo.slc.core.attachment.AttachmentsEnabled;
+import org.springframework.core.io.Resource;
+
+public class UploadAttachments implements Runnable {
+       private AttachmentUploader attachmentUploader;
+       private Attachment attachment = null;
+       private Resource resource = null;
+       private Map<Attachment, Resource> attachments = new HashMap<Attachment, Resource>();
+       private List<AttachmentsEnabled> attachTo = new ArrayList<AttachmentsEnabled>();
+       private Boolean newUuidPerExecution = true;
+
+       public void run() {
+               if (attachment != null) {
+                       if (resource == null)
+                               throw new SlcException("A resource must be specified.");
+                       uploadAndAdd(attachment, resource);
+               }
+
+               for (Attachment attachmentT : attachments.keySet()) {
+                       Resource resourceT = attachments.get(attachmentT);
+                       uploadAndAdd(attachmentT, resourceT);
+               }
+
+       }
+
+       protected void uploadAndAdd(Attachment attachment, Resource resource) {
+               if (newUuidPerExecution)
+                       attachment.setUuid(UUID.randomUUID().toString());
+               attachmentUploader.upload(attachment, resource);
+               for (AttachmentsEnabled attachmentsEnabled : attachTo) {
+                       attachmentsEnabled.addAttachment(attachment);
+               }
+       }
+
+       public void setAttachmentUploader(AttachmentUploader attachmentUploader) {
+               this.attachmentUploader = attachmentUploader;
+       }
+
+       public void setAttachments(Map<Attachment, Resource> attachments) {
+               this.attachments = attachments;
+       }
+
+       public void setAttachTo(List<AttachmentsEnabled> attachTo) {
+               this.attachTo = attachTo;
+       }
+
+       public void setAttachment(Attachment attachment) {
+               this.attachment = attachment;
+       }
+
+       public void setResource(Resource resource) {
+               this.resource = resource;
+       }
+
+       public void setNewUuidPerExecution(Boolean newUuidPerExecution) {
+               this.newUuidPerExecution = newUuidPerExecution;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/core.xml b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/tasks/core.xml
new file mode 100644 (file)
index 0000000..df35944
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (C) 2007-2012 Argeo GmbH
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+            http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+       <bean id="task.echo" class="org.argeo.slc.core.execution.tasks.Echo"
+               abstract="true" />
+       <bean id="task.systemCall" class="org.argeo.slc.core.execution.tasks.SystemCall"
+               abstract="true" />
+       <bean id="task.closeTestResult" class="org.argeo.slc.core.execution.tasks.CloseTestResult"
+               abstract="true" />
+       <bean id="task.slcManager" class="org.argeo.slc.core.execution.tasks.SlcManager"
+               abstract="true" />
+       <bean id="task.overrideContextAware" class="org.argeo.slc.core.execution.tasks.OverrideContextAware"
+               abstract="true" />
+       <bean id="task.uploadAttachments" class="org.argeo.slc.core.execution.tasks.UploadAttachments"
+               abstract="true" />
+
+       <bean id="taskArg.attachment" class="org.argeo.slc.core.attachment.SimpleAttachment"
+               abstract="true" />
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/templates.xml b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/templates.xml
new file mode 100644 (file)
index 0000000..28b742a
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (C) 2007-2012 Argeo GmbH
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+            http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+       <bean id="slcTemplate.fileResources" class="org.argeo.slc.core.execution.FileExecutionResources"
+               abstract="true" />
+
+       <bean id="slcTemplate.resourcesFactoryBean" parent="slcTemplate.writableResource"
+               abstract="true" />
+
+       <bean id="slcTemplate.writableResource"
+               class="org.argeo.slc.core.execution.ExecutionResourcesFactoryBean"
+               abstract="true" />
+
+       <bean id="slcTemplate.osFile" class="org.argeo.slc.core.execution.OsFileFactoryBean"
+               abstract="true" />
+
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/utils.xml b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/utils.xml
new file mode 100644 (file)
index 0000000..527e701
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (C) 2007-2012 Argeo GmbH
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+            http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+       <bean id="mergedLists" class="org.argeo.slc.core.execution.tasks.MergedLists"
+               abstract="true">
+       </bean>
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/AsFlowDecorator.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/AsFlowDecorator.java
new file mode 100644 (file)
index 0000000..dceec1c
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.DefaultExecutionFlow;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.springframework.beans.BeanMetadataElement;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+
+/** Publishes a {@link Runnable} as an {@link ExecutionFlow} */
+public class AsFlowDecorator implements BeanDefinitionDecorator {
+       private Log log = LogFactory.getLog(AsFlowDecorator.class);
+
+       public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder bean,
+                       ParserContext ctx) {
+               String attrValue = ((Attr) node).getValue();
+               if (attrValue.charAt(attrValue.length() - 1) == '/')
+                       throw new SlcException(attrValue + " cannot end with a path");
+               final String flowBeanName = attrValue;
+
+               if (log.isTraceEnabled())
+                       log.trace("flowBeanName=" + flowBeanName);
+
+               if (ctx.getRegistry().containsBeanDefinition(flowBeanName))
+                       throw new SlcException("A bean named " + flowBeanName
+                                       + " is already defined.");
+               BeanDefinitionBuilder flow = BeanDefinitionBuilder
+                               .rootBeanDefinition(DefaultExecutionFlow.class);
+               ManagedList<BeanMetadataElement> executables = new ManagedList<BeanMetadataElement>(
+                               1);
+
+               String beanName = bean.getBeanName();
+               if (beanName == null)
+                       executables.add(bean.getBeanDefinition());
+               else
+                       executables.add(new RuntimeBeanReference(beanName));
+
+               // if (path != null)
+               // flow.addPropertyValue("path", path);
+               flow.addPropertyValue("executables", executables);
+
+               if (beanName != null)
+                       ctx.getRegistry().registerBeanDefinition(flowBeanName,
+                                       flow.getBeanDefinition());
+               return bean;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/ExecutionScopeDecorator.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/ExecutionScopeDecorator.java
new file mode 100644 (file)
index 0000000..dfca9d5
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.xml;\r
+\r
+import org.springframework.aop.scope.ScopedProxyUtils;\r
+import org.springframework.beans.factory.config.BeanDefinitionHolder;\r
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;\r
+import org.springframework.beans.factory.xml.BeanDefinitionDecorator;\r
+import org.springframework.beans.factory.xml.ParserContext;\r
+import org.w3c.dom.Element;\r
+import org.w3c.dom.Node;\r
+\r
+/**\r
+ * Inspired by org.springframework.aop.config.ScopedProxyBeanDefinitionDecorator\r
+ */\r
+public class ExecutionScopeDecorator implements BeanDefinitionDecorator {      \r
+       private static final String PROXY_TARGET_CLASS = "proxy-target-class";  \r
+       \r
+       public BeanDefinitionHolder decorate(Node node,\r
+                       BeanDefinitionHolder definition, ParserContext parserContext) {\r
+               \r
+               definition.getBeanDefinition().setScope("execution");\r
+               \r
+               // Default: CGLib not used\r
+               boolean proxyTargetClass = false;\r
+               if (node instanceof Element) {\r
+                       Element ele = (Element) node;\r
+                       if (ele.hasAttribute(PROXY_TARGET_CLASS)) {\r
+                               proxyTargetClass = Boolean.valueOf(ele.getAttribute(PROXY_TARGET_CLASS)).booleanValue();\r
+                       }\r
+               }\r
+               \r
+               // Register the original bean definition as it will be referenced by the scoped proxy and is relevant for tooling (validation, navigation).\r
+               String targetBeanName = ScopedProxyUtils.getTargetBeanName(definition.getBeanName());\r
+               parserContext.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(definition.getBeanDefinition(), targetBeanName));\r
+               \r
+               return ScopedProxyUtils.createScopedProxy(definition, parserContext.getRegistry(), proxyTargetClass);           \r
+       }\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/FlowBeanDefinitionParser.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/FlowBeanDefinitionParser.java
new file mode 100644 (file)
index 0000000..7d2ab49
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.DefaultExecutionFlow;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.support.ManagedMap;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+import org.springframework.util.xml.DomUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/** Interprets the <flow:flow> tag */
+public class FlowBeanDefinitionParser extends
+               AbstractSingleBeanDefinitionParser {
+       private Log log = LogFactory.getLog(FlowBeanDefinitionParser.class);
+
+       /** Whether the user has already be warned on path attribute usage. */
+       private Boolean warnedAboutPathAttribute = false;
+
+       @Override
+       protected void doParse(Element element, ParserContext parserContext,
+                       BeanDefinitionBuilder builder) {
+               String path = element.getAttribute("path");
+               if (StringUtils.hasText(path)) {
+                       builder.addPropertyValue("path", path);
+
+                       // warns user only once
+                       if (!warnedAboutPathAttribute)
+                               log.warn("The path=\"\" attribute is deprecated"
+                                               + " and will be removed in a later release."
+                                               + " Use <flow:flow name=\"/my/path/flowName\">.");
+                       warnedAboutPathAttribute = true;
+               }
+
+               String spec = element.getAttribute("spec");
+               if (StringUtils.hasText(spec))
+                       builder.getBeanDefinition().getConstructorArgumentValues()
+                                       .addGenericArgumentValue(new RuntimeBeanReference(spec));
+
+               String abstrac = element.getAttribute("abstract");
+               if (StringUtils.hasText(abstrac))
+                       builder.setAbstract(Boolean.parseBoolean(abstrac));
+
+               String parent = element.getAttribute("parent");
+               if (StringUtils.hasText(parent))
+                       builder.setParentName(parent);
+
+               builder.getBeanDefinition().setDescription(
+                               DomUtils.getChildElementValueByTagName(element, "description"));
+
+               List<Element> argsElems = new ArrayList<Element>();
+               List<Element> execElems = new ArrayList<Element>();
+               List<Element> specElems = new ArrayList<Element>();
+               NodeList nodeList = element.getChildNodes();
+               for (int i = 0; i < nodeList.getLength(); i++) {
+                       Node node = nodeList.item(i);
+                       if (node instanceof Element) {
+                               if (DomUtils.nodeNameEquals(node, "arg"))
+                                       argsElems.add((Element) node);
+                               else if (DomUtils.nodeNameEquals(node, "spec"))
+                                       specElems.add((Element) node);
+                               else if (!DomUtils.nodeNameEquals(node, "description"))
+                                       execElems.add((Element) node);
+                       }
+               }
+
+               // Arguments
+               if (argsElems.size() != 0) {
+                       ManagedMap<String, Object> args = new ManagedMap<String, Object>(
+                                       argsElems.size());
+                       for (Element argElem : argsElems) {
+                               Object value = NamespaceUtils.parseValue(argElem,
+                                               parserContext, builder.getBeanDefinition(), null);
+                               if (value != null)
+                                       args.put(argElem.getAttribute("name"), value);
+                               else
+                                       throw new SlcException("No value defined.");
+                       }
+                       builder.getBeanDefinition().getConstructorArgumentValues()
+                                       .addGenericArgumentValue(args);
+               }
+
+               // Execution specs
+               if (StringUtils.hasText(spec) && specElems.size() != 0)
+                       throw new SlcException("A flow cannot have multiple specs");
+               if (specElems.size() == 1) {
+                       Object specObj = NamespaceUtils.parseBeanOrReference(
+                                       specElems.get(0), parserContext,
+                                       builder.getBeanDefinition());
+                       builder.getBeanDefinition().getConstructorArgumentValues()
+                                       .addGenericArgumentValue(specObj);
+               } else if (specElems.size() > 1)
+                       throw new SlcException("A flow cannot have multiple specs");
+
+               // Executables
+               if (execElems.size() != 0) {
+                       ManagedList<Object> executables = new ManagedList<Object>(
+                                       execElems.size());
+                       for (Element child : execElems) {
+                               // child validity check is performed in xsd
+                               executables.add(NamespaceUtils.parseBeanOrReference(child,
+                                               parserContext, builder.getBeanDefinition()));
+                       }
+                       if (executables.size() > 0)
+                               builder.addPropertyValue("executables", executables);
+               }
+       }
+
+       @SuppressWarnings("unchecked")
+       @Override
+       protected Class<? extends ExecutionFlow> getBeanClass(Element element) {
+               String clss = element.getAttribute("class");
+               if (StringUtils.hasText(clss))
+                       // TODO: check that it actually works
+                       try {
+                               return (Class<? extends ExecutionFlow>) getClass()
+                                               .getClassLoader().loadClass(clss);
+                       } catch (ClassNotFoundException e) {
+                               try {
+                                       return (Class<? extends ExecutionFlow>) Thread
+                                                       .currentThread().getContextClassLoader()
+                                                       .loadClass(clss);
+                               } catch (ClassNotFoundException e1) {
+                                       throw new SlcException("Cannot load class " + clss, e);
+                               }
+                       }
+               else
+                       return DefaultExecutionFlow.class;
+       }
+
+       // parse nested bean definition
+       // private Object parseBeanReference(Element element,
+       // ParserContext parserContext, BeanDefinitionBuilder builder) {
+       // return parserContext.getDelegate().parsePropertySubElement(element,
+       // builder.getBeanDefinition());
+       // }
+
+       @Override
+       protected String resolveId(Element element,
+                       AbstractBeanDefinition definition, ParserContext parserContext)
+                       throws BeanDefinitionStoreException {
+               String name = element.getAttribute("name");
+               if (StringUtils.hasText(name)) {
+                       return name;
+               } else {
+                       return super.resolveId(element, definition, parserContext);
+               }
+       }
+
+       protected boolean shouldGenerateIdAsFallback() {
+               return true;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/FlowNamespaceHandler.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/FlowNamespaceHandler.java
new file mode 100644 (file)
index 0000000..2deba8b
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+
+public class FlowNamespaceHandler extends NamespaceHandlerSupport {
+
+       public void init() {
+               registerBeanDefinitionParser("flow", new FlowBeanDefinitionParser());
+               registerBeanDefinitionParser("spec", new SpecBeanDefinitionParser());
+               registerBeanDefinitionDecoratorForAttribute("as-flow",
+                               new AsFlowDecorator());
+               registerBeanDefinitionParser("param", new ParamDecorator());
+                
+               // The objective was to replace
+               // - attribute scope="execution"
+               // - and element "aop:scoped-proxy" 
+               // by a single attribute, using an attribute decorator 
+               // this does not work correctly with other attribute decorators (e.g. 
+               // p namespace) since this decorator needs to be called after all
+               // properties have been set on target bean. 
+               // It works properly with element decorators (called after all attribute
+               // decorators
+               registerBeanDefinitionDecorator("variable", new ExecutionScopeDecorator());
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/NamespaceUtils.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/NamespaceUtils.java
new file mode 100644 (file)
index 0000000..ccf94f1
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.xml.DomUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Utilities to simplify common tasks when interpreting a custom namespace and
+ * converting it into bean definitions.
+ */
+public class NamespaceUtils {
+       // private final static Log log = LogFactory.getLog(NamespaceUtils.class);
+
+       /**
+        * Returns the value defined either: directly by the the 'value' attribute,
+        * as reference by the 'ref' attribute or as a nested bean.
+        */
+       public static Object parseValue(Element element,
+                       ParserContext parserContext,
+                       BeanDefinition containingBeanDefintion, String valueTagName) {
+               Object value = null;
+               if (element.hasAttribute("value")) {
+                       value = element.getAttribute("value");
+               }
+
+               if (element.hasAttribute("ref")) {
+                       if (value != null)
+                               throw new SlcException("Multiple value definition for "
+                                               + element);
+                       value = new RuntimeBeanReference(element.getAttribute("ref"));
+               }
+
+               Element uniqueSubElem = null;
+               if (valueTagName != null) {
+                       Element valueElem = DomUtils.getChildElementByTagName(element,
+                                       valueTagName);
+                       if (valueElem != null) {
+                               uniqueSubElem = findUniqueSubElement(valueElem);
+                               if (uniqueSubElem == null)
+                                       throw new SlcException("No subelement found under "
+                                                       + valueElem);
+                       }
+               } else {// no intermediary tag
+                       uniqueSubElem = findUniqueSubElement(element);
+               }
+
+               if (uniqueSubElem != null) {
+                       if (value != null)
+                               throw new SlcException("Multiple value definition for "
+                                               + element);
+                       value = parseBeanOrReference(uniqueSubElem, parserContext,
+                                       containingBeanDefintion);
+               }
+               return value;
+       }
+
+       public static Element findUniqueSubElement(Element element) {
+               NodeList childNodes = element.getChildNodes();
+
+               Element uniqueSubElem = null;
+               for (int i = 0; i < childNodes.getLength(); i++) {
+                       Node node = childNodes.item(i);
+                       if (node != null && node instanceof Element) {
+                               if (uniqueSubElem == null)
+                                       uniqueSubElem = (Element) node;
+                               else
+                                       throw new SlcException(
+                                                       "There are more than one sub element under "
+                                                                       + element);
+                       }
+               }
+               return uniqueSubElem;
+       }
+
+       public static Object parseBeanOrReference(Element element,
+                       ParserContext parserContext, BeanDefinition beanDefinition) {
+               // return parserContext.getDelegate().parsePropertySubElement(element,
+               // beanDefinition);
+
+               BeanDefinitionParserDelegate deleg = parserContext.getDelegate();
+               // if ("bean".equals(element.getNodeName()))
+               // return deleg.parseBeanDefinitionElement(element, beanDefinition);
+               // else
+               return deleg.parsePropertySubElement(element, beanDefinition);
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/ParamDecorator.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/ParamDecorator.java
new file mode 100644 (file)
index 0000000..16839c0
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import org.argeo.slc.core.execution.ParameterRef;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+
+public class ParamDecorator extends AbstractSingleBeanDefinitionParser {
+
+       // public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder
+       // bean,
+       // ParserContext ctx) {
+       // String paramName = ((Element) node).getAttribute("name");
+       // String propertyName = ((Element) node.getParentNode())
+       // .getAttribute("name");
+       // BeanDefinitionBuilder parameterRef = BeanDefinitionBuilder
+       // .genericBeanDefinition(ParameterRef.class);
+       // parameterRef.addPropertyReference("instantiationManager",
+       // "instantiationManager");
+       // parameterRef.addConstructorArgValue(paramName);
+       // bean.getBeanDefinition().getPropertyValues().addPropertyValue(
+       // propertyName, parameterRef.getBeanDefinition());
+       // return bean;
+       // }
+
+       @Override
+       protected void doParse(Element element, ParserContext parserContext,
+                       BeanDefinitionBuilder builder) {
+               String paramName = element.getAttribute("name");
+
+               String instantationManagerRef = element
+                               .getAttribute("instantiationManager");
+               if (!StringUtils.hasText(instantationManagerRef))
+                       instantationManagerRef = "instantiationManager";
+               builder.addPropertyReference("instantiationManager",
+                               instantationManagerRef);
+               builder.addConstructorArgValue(paramName);
+       }
+
+       @Override
+       protected Class<ParameterRef> getBeanClass(Element element) {
+               return ParameterRef.class;
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/SpecBeanDefinitionParser.java b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/SpecBeanDefinitionParser.java
new file mode 100644 (file)
index 0000000..761e26d
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.core.execution.DefaultExecutionSpec;
+import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
+import org.argeo.slc.core.execution.RefSpecAttribute;
+import org.argeo.slc.core.execution.RefValueChoice;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.support.ManagedMap;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+import org.springframework.util.xml.DomUtils;
+import org.w3c.dom.Element;
+
+/** Interprets the <flow:spec> tag */
+public class SpecBeanDefinitionParser extends
+               AbstractSingleBeanDefinitionParser {
+       private Log log = LogFactory.getLog(SpecBeanDefinitionParser.class);
+
+       @Override
+       protected void doParse(Element element, ParserContext parserContext,
+                       BeanDefinitionBuilder builder) {
+               builder.getBeanDefinition().setDescription(
+                               DomUtils.getChildElementValueByTagName(element, "description"));
+
+               ManagedMap<String, BeanDefinition> attributes = new ManagedMap<String, BeanDefinition>();
+
+               // Primitives
+               for (Element child : (List<Element>) DomUtils
+                               .getChildElementsByTagName(element, "primitive")) {
+                       BeanDefinitionBuilder childBuilder = BeanDefinitionBuilder
+                                       .genericBeanDefinition(PrimitiveSpecAttribute.class);
+                       addCommonProperties(child, parserContext, childBuilder);
+
+                       String type = child.getAttribute("type");
+                       if (StringUtils.hasText(type))
+                               childBuilder.addPropertyValue("type", type);
+
+                       putInAttributes(attributes, child,
+                                       childBuilder.getBeanDefinition(), "primitive");
+               }
+
+               // Refs
+               for (Element refAttrElem : (List<Element>) DomUtils
+                               .getChildElementsByTagName(element, "ref")) {
+                       BeanDefinitionBuilder refAttrBuilder = BeanDefinitionBuilder
+                                       .genericBeanDefinition(RefSpecAttribute.class);
+                       addCommonProperties(refAttrElem, parserContext, refAttrBuilder);
+
+                       String targetClassName = refAttrElem.getAttribute("targetClass");
+                       if (StringUtils.hasText(targetClassName))
+                               refAttrBuilder.addPropertyValue("targetClass", targetClassName);
+
+                       // Choices
+                       Element choicesElem = DomUtils.getChildElementByTagName(
+                                       refAttrElem, "choices");
+                       if (choicesElem != null) {
+                               List<Element> choices = DomUtils.getChildElementsByTagName(
+                                               choicesElem, "choice");
+                               ManagedList<BeanDefinition> choiceBeans = new ManagedList<BeanDefinition>(
+                                               choices.size());
+                               for (Element choiceElem : choices) {
+                                       BeanDefinitionBuilder choiceBuilder = BeanDefinitionBuilder
+                                                       .genericBeanDefinition(RefValueChoice.class);
+                                       choiceBuilder.addPropertyValue("name",
+                                                       choiceElem.getAttribute("name"));
+                                       String desc = choiceElem.getAttribute("description");
+                                       if (StringUtils.hasText(desc))
+                                               choiceBuilder.addPropertyValue("description", desc);
+
+                                       choiceBeans.add(choiceBuilder.getBeanDefinition());
+                               }
+                               refAttrBuilder.addPropertyValue("choices", choiceBeans);
+                       }
+
+                       putInAttributes(attributes, refAttrElem,
+                                       refAttrBuilder.getBeanDefinition(), "ref");
+               }
+
+               builder.addPropertyValue("attributes", attributes);
+       }
+
+       protected void addCommonProperties(Element element,
+                       ParserContext parserContext, BeanDefinitionBuilder specAttr) {
+               addBooleanProperty("isImmutable", specAttr, element);
+               addBooleanProperty("isConstant", specAttr, element);
+               addBooleanProperty("isHidden", specAttr, element);
+               addBooleanProperty("isParameter", specAttr, element);
+               addBooleanProperty("isFrozen", specAttr, element);
+
+               Object value = NamespaceUtils.parseValue(element, parserContext,
+                               specAttr.getBeanDefinition(), "value");
+               if (value != null)
+                       specAttr.addPropertyValue("value", value);
+
+       }
+
+       protected void putInAttributes(
+                       ManagedMap<String, BeanDefinition> attributes, Element child,
+                       BeanDefinition beanDefinition, String nature) {
+               String name = child.getAttribute("name");
+               attributes.put(name, beanDefinition);
+               if (log.isTraceEnabled())
+                       log.debug("Added " + nature + " attribute " + name);
+
+       }
+
+       private void addBooleanProperty(String name,
+                       BeanDefinitionBuilder specAttr, Element element) {
+               String bool = element.getAttribute(name);
+               if (StringUtils.hasText(bool))
+                       specAttr.addPropertyValue(name, Boolean.parseBoolean(bool));
+
+       }
+
+       @Override
+       protected Class<DefaultExecutionSpec> getBeanClass(Element element) {
+               return DefaultExecutionSpec.class;
+       }
+
+       protected boolean shouldGenerateIdAsFallback() {
+               return false;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/slc-flow-0.12.xsd b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/slc-flow-0.12.xsd
new file mode 100644 (file)
index 0000000..8b31a60
--- /dev/null
@@ -0,0 +1,384 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+       xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns:beans="http://www.springframework.org/schema/beans"
+       targetNamespace="http://www.argeo.org/schema/slc-flow"
+       elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+       <xsd:import namespace="http://www.springframework.org/schema/beans"
+               schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" />
+
+       <xsd:annotation>
+               <xsd:documentation><![CDATA[
+       SLC Flow Schema, version 0.12
+       Authors: Mathieu Baudier
+       
+       This simplifies the definition of SLC flows and their integration with 
+       regular Spring beans.
+               ]]></xsd:documentation>
+       </xsd:annotation>
+
+       <xsd:element name="flow">
+               <xsd:annotation>
+                       <xsd:documentation><![CDATA[
+       Adds an SLC execution flow, using the default implementation.
+                       ]]></xsd:documentation>
+               </xsd:annotation>
+               <xsd:complexType>
+                       <xsd:complexContent>
+                               <xsd:extension base="beans:identifiedType">
+                                       <xsd:sequence>
+                                               <xsd:element ref="beans:description" minOccurs="0" />
+                                               <xsd:sequence>
+                                                       <xsd:element name="arg" minOccurs="0" maxOccurs="unbounded"
+                                                               type="flow:argType">
+                                                               <xsd:annotation>
+                                                                       <xsd:documentation><![CDATA[
+       Parameter for an execution flow which will override at instantiation the 
+       value of the parameter already defined as default value or in a parent bean.
+                                                                       ]]></xsd:documentation>
+                                                               </xsd:annotation>
+                                                       </xsd:element>
+                                               </xsd:sequence>
+                                               <xsd:sequence>
+                                                       <xsd:choice minOccurs="0" maxOccurs="unbounded">
+                                                               <xsd:element ref="beans:bean" />
+                                                               <xsd:element ref="beans:ref" />
+                                                               <xsd:element ref="flow:flow" />
+                                                       </xsd:choice>
+                                                       <!--
+                                                               <xsd:any namespace="##other" processContents="strict"
+                                                               minOccurs="0" maxOccurs="unbounded" />
+                                                       -->
+                                               </xsd:sequence>
+                                       </xsd:sequence>
+                                       <xsd:attribute name="name" type="xsd:string">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       Name of the flow (alternative to ID).
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                                       <xsd:attribute name="class" type="xsd:string">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       Another implementation of execution flow.
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                                       <xsd:attribute name="path" type="xsd:string">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       The hierarchical path under which to register this flow.
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                                       <xsd:attribute name="spec" type="xsd:string">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       A reference to the related specification bean.
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                                       <xsd:attribute name="parent" type="xsd:string">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       The parent bean definition (in Spring sense).
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                                       <xsd:attribute name="abstract" type="xsd:boolean"
+                                               default="false">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       Whether this flow is abstract (in Spring sense).
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                               </xsd:extension>
+                       </xsd:complexContent>
+               </xsd:complexType>
+       </xsd:element>
+
+       <xsd:element name="spec">
+               <xsd:annotation>
+                       <xsd:documentation><![CDATA[
+       SLC flow specifications, defining the parameters and variables
+       which can be used in related flows, along with their default values and 
+       various constraints.
+                       ]]></xsd:documentation>
+               </xsd:annotation>
+               <xsd:complexType>
+                       <xsd:complexContent>
+                               <xsd:extension base="beans:identifiedType">
+                                       <xsd:sequence>
+                                               <xsd:element ref="beans:description" minOccurs="0" />
+                                               <xsd:choice minOccurs="0" maxOccurs="unbounded">
+                                                       <xsd:element name="primitive" type="flow:primitiveSpecAttributeType"
+                                                               minOccurs="0" maxOccurs="unbounded">
+                                                               <xsd:annotation>
+                                                                       <xsd:documentation><![CDATA[
+       A primitive specification attribute, that is, a plain standard value
+       and not a reference to an object.
+                                                                       ]]></xsd:documentation>
+                                                               </xsd:annotation>
+                                                       </xsd:element>
+                                                       <xsd:element name="ref" type="flow:refSpecAttributeType"
+                                                               minOccurs="0" maxOccurs="unbounded">
+                                                               <xsd:annotation>
+                                                                       <xsd:documentation><![CDATA[
+       A reference specification attribute, that is, a reference to another object.
+                                                                       ]]></xsd:documentation>
+                                                               </xsd:annotation>
+                                                       </xsd:element>
+                                               </xsd:choice>
+                                       </xsd:sequence>
+                               </xsd:extension>
+                       </xsd:complexContent>
+               </xsd:complexType>
+       </xsd:element>
+
+       <xsd:complexType name="specAttributeType">
+               <xsd:choice>
+                       <xsd:element name="value" minOccurs="0" maxOccurs="1">
+                               <xsd:annotation>
+                                       <xsd:documentation><![CDATA[
+       The default value of the attribute as an inner bean.
+                                       ]]></xsd:documentation>
+                               </xsd:annotation>
+                               <xsd:complexType>
+                                       <xsd:choice minOccurs="1" maxOccurs="1">
+                                               <xsd:element ref="beans:bean" />
+                                               <xsd:element ref="beans:ref" />
+                                               <xsd:element ref="beans:list" />
+                                               <xsd:element ref="beans:set" />
+                                               <xsd:element ref="beans:map" />
+                                               <xsd:element ref="beans:props" />
+                                       </xsd:choice>
+                               </xsd:complexType>
+                       </xsd:element>
+               </xsd:choice>
+               <xsd:attribute name="name" use="required" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The name of the attribute, under which in can then be referenced.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="value" use="optional" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The default value of the attribute.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="ref" use="optional" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The default value of the attribute as a reference to another bean.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="isParameter" use="optional" type="xsd:boolean"
+                       default="false">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       Whether the attribute is a parameter, that is, it has to be set at 
+       instantiation but can be modified afterwards for objects of scope execution.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="isFrozen" use="optional" type="xsd:boolean"
+                       default="false">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       Whether the attribute is frozen, that is, it cannot be modified at runtime.
+       A frozen attribute has to be a parameter.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="isHidden" use="optional" type="xsd:boolean"
+                       default="false">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       Whether the attribute is hidden, that is, it should not be displayed in UIs.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+       </xsd:complexType>
+
+       <xsd:complexType name="primitiveSpecAttributeType">
+               <xsd:complexContent>
+                       <xsd:extension base="flow:specAttributeType">
+                               <xsd:attribute name="type" default="string">
+                                       <xsd:annotation>
+                                               <xsd:documentation><![CDATA[
+       The type of the primitive specification attribute.
+                                               ]]></xsd:documentation>
+                                       </xsd:annotation>
+                                       <xsd:simpleType>
+                                               <xsd:restriction base="xsd:string">
+                                                       <xsd:enumeration value="string" />
+                                                       <xsd:enumeration value="integer" />
+                                                       <xsd:enumeration value="long" />
+                                                       <xsd:enumeration value="float" />
+                                                       <xsd:enumeration value="double" />
+                                                       <xsd:enumeration value="boolean" />
+                                               </xsd:restriction>
+                                       </xsd:simpleType>
+                               </xsd:attribute>
+                       </xsd:extension>
+               </xsd:complexContent>
+       </xsd:complexType>
+
+       <xsd:complexType name="refSpecAttributeType">
+               <xsd:complexContent>
+                       <xsd:extension base="flow:specAttributeType">
+                               <xsd:choice>
+                                       <xsd:element name="choices" minOccurs="0" maxOccurs="1">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       Possible values to chose from, if ommitted, all the beans in the 
+       application context which implement the provided targetClass will 
+       be considered.
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                               <xsd:complexType>
+                                                       <xsd:choice>
+                                                               <xsd:element name="choice" minOccurs="0" maxOccurs="unbounded"
+                                                                       type="flow:refChoiceType">
+                                                                       <xsd:annotation>
+                                                                               <xsd:documentation><![CDATA[
+       A choice for a reference specification attribute.
+                                                                               ]]></xsd:documentation>
+                                                                       </xsd:annotation>
+                                                               </xsd:element>
+                                                       </xsd:choice>
+                                               </xsd:complexType>
+                                       </xsd:element>
+                               </xsd:choice>
+                               <xsd:attribute name="targetClass" use="required" type="xsd:string">
+                                       <xsd:annotation>
+                                               <xsd:documentation><![CDATA[
+       The class that has to be implemented by the underlying object.
+                                       ]]></xsd:documentation>
+                                       </xsd:annotation>
+                               </xsd:attribute>
+                       </xsd:extension>
+               </xsd:complexContent>
+       </xsd:complexType>
+
+       <xsd:complexType name="refChoiceType">
+               <xsd:attribute name="name" use="required" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The name of the related bean.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="description" use="optional" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       A human readable description of this choice.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+       </xsd:complexType>
+
+       <xsd:complexType name="argType">
+               <xsd:choice minOccurs="0" maxOccurs="1">
+                       <xsd:element ref="beans:bean" />
+                       <xsd:element ref="beans:ref" />
+                       <xsd:element ref="flow:param" />
+                       <xsd:element ref="beans:list" />
+                       <xsd:element ref="beans:set" />
+                       <xsd:element ref="beans:map" />
+                       <xsd:element ref="beans:props" />
+               </xsd:choice>
+               <xsd:attribute name="name" use="required" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The name of the related parameter.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="value" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The plain value of the related parameter.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="ref" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The value of the related parameter as a reference to a bean.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+       </xsd:complexType>
+
+       <xsd:attribute name="as-flow" type="xsd:string">
+               <xsd:annotation>
+                       <xsd:documentation><![CDATA[
+       If decorating an executable bean, it will generate an implicit SLC 
+       execution flow with the provided value as name.
+                       ]]></xsd:documentation>
+               </xsd:annotation>
+       </xsd:attribute>
+       <!--
+               <xsd:attribute name="var" type="xsd:boolean"> <xsd:annotation>
+               <xsd:documentation><![CDATA[ If true, the decorated bean is set to
+               scope execution and proxied. ]]></xsd:documentation> </xsd:annotation>
+               </xsd:attribute>
+       -->
+
+       <xsd:element name="variable">
+               <xsd:complexType>
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       Marks a bean definition as being variable, i.e. a scoped proxy of scope execution 
+                       ]]></xsd:documentation>
+                       </xsd:annotation>
+                       <xsd:attribute name="proxy-target-class" type="xsd:boolean"
+                               default="true">
+                               <xsd:annotation>
+                                       <xsd:documentation><![CDATA[
+                                               Are class-based (CGLIB) proxies to be created?
+                                               This is the default;
+                                               in order to switch to standard Java
+                                               interface-based proxies, turn this flag to
+                                               "false".
+                                       ]]></xsd:documentation>
+                               </xsd:annotation>
+                       </xsd:attribute>
+               </xsd:complexType>
+       </xsd:element>
+
+       <xsd:element name="param">
+               <xsd:annotation>
+                       <xsd:documentation><![CDATA[
+       If within a property tag of a bean, it will set the value of this property
+        with a reference to a parameter.
+                       ]]></xsd:documentation>
+               </xsd:annotation>
+               <xsd:complexType>
+                       <xsd:attribute name="name" type="xsd:string" use="required">
+                               <xsd:annotation>
+                                       <xsd:documentation><![CDATA[
+       The name of the related parameter.
+                                       ]]></xsd:documentation>
+                               </xsd:annotation>
+                       </xsd:attribute>
+                       <xsd:attribute name="instantiationManager" type="xsd:string"
+                               use="optional" default="instantiationManager">
+                               <xsd:annotation>
+                                       <xsd:documentation><![CDATA[
+       A reference to the instantiation manager to use instead of the default one
+       (expert usage).
+                                       ]]></xsd:documentation>
+                               </xsd:annotation>
+                       </xsd:attribute>
+               </xsd:complexType>
+       </xsd:element>
+
+</xsd:schema>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd b/org.argeo.slc.spring/src/org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd
new file mode 100644 (file)
index 0000000..a70798f
--- /dev/null
@@ -0,0 +1,402 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+       xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns:beans="http://www.springframework.org/schema/beans"
+       targetNamespace="http://www.argeo.org/schema/slc-flow"
+       elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+       <xsd:import namespace="http://www.springframework.org/schema/beans"
+               schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" />
+
+       <xsd:annotation>
+               <xsd:documentation><![CDATA[
+       SLC Flow Schema, version 1.2
+       Authors: Mathieu Baudier
+       
+       This simplifies the definition of SLC flows and their integration with 
+       regular Spring beans.
+               ]]></xsd:documentation>
+       </xsd:annotation>
+
+       <xsd:element name="flow">
+               <xsd:annotation>
+                       <xsd:documentation><![CDATA[
+       Adds an SLC execution flow, using the default implementation.
+                       ]]></xsd:documentation>
+               </xsd:annotation>
+               <xsd:complexType>
+                       <xsd:complexContent>
+                               <xsd:extension base="beans:identifiedType">
+                                       <xsd:sequence>
+                                               <xsd:element ref="beans:description" minOccurs="0" />
+                                               <xsd:sequence>
+                                                       <xsd:element name="arg" minOccurs="0" maxOccurs="unbounded"
+                                                               type="flow:argType">
+                                                               <xsd:annotation>
+                                                                       <xsd:documentation><![CDATA[
+       Parameter for an execution flow which will override at instantiation the 
+       value of the parameter already defined as default value or in a parent bean.
+                                                                       ]]></xsd:documentation>
+                                                               </xsd:annotation>
+                                                       </xsd:element>
+                                               </xsd:sequence>
+                                               <xsd:sequence>
+                                                       <xsd:choice minOccurs="0" maxOccurs="unbounded">
+                                                               <xsd:element ref="beans:bean" />
+                                                               <xsd:element ref="beans:ref" />
+                                                               <xsd:element ref="flow:flow" />
+                                                               <xsd:element ref="flow:spec" />
+                                                       </xsd:choice>
+                                                       <!-- <xsd:any namespace="##other" processContents="strict" minOccurs="0" 
+                                                               maxOccurs="unbounded" /> -->
+                                               </xsd:sequence>
+                                       </xsd:sequence>
+                                       <xsd:attribute name="name" type="xsd:string">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       Name of the flow (alternative to ID).
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                                       <xsd:attribute name="class" type="xsd:string">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       Another implementation of execution flow.
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                                       <xsd:attribute name="path" type="xsd:string">
+                                               <!-- DEPRECATED: not used anymore -->
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       The hierarchical path under which to register this flow.
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                                       <xsd:attribute name="spec" type="xsd:string">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       A reference to the related specification bean.
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                                       <xsd:attribute name="parent" type="xsd:string">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       The parent bean definition (in Spring sense).
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                                       <xsd:attribute name="abstract" type="xsd:boolean"
+                                               default="false">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       Whether this flow is abstract (in Spring sense).
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                       </xsd:attribute>
+                               </xsd:extension>
+                       </xsd:complexContent>
+               </xsd:complexType>
+       </xsd:element>
+
+       <xsd:element name="spec">
+               <xsd:annotation>
+                       <xsd:documentation><![CDATA[
+       SLC flow specifications, defining the parameters and variables
+       which can be used in related flows, along with their default values and 
+       various constraints.
+                       ]]></xsd:documentation>
+               </xsd:annotation>
+               <xsd:complexType>
+                       <xsd:complexContent>
+                               <xsd:extension base="beans:identifiedType">
+                                       <xsd:sequence>
+                                               <xsd:element ref="beans:description" minOccurs="0" />
+                                               <xsd:choice minOccurs="0" maxOccurs="unbounded">
+                                                       <xsd:element name="primitive" type="flow:primitiveSpecAttributeType"
+                                                               minOccurs="0" maxOccurs="unbounded">
+                                                               <xsd:annotation>
+                                                                       <xsd:documentation><![CDATA[
+       A primitive specification attribute, that is, a plain standard value
+       and not a reference to an object.
+                                                                       ]]></xsd:documentation>
+                                                               </xsd:annotation>
+                                                       </xsd:element>
+                                                       <xsd:element name="ref" type="flow:refSpecAttributeType"
+                                                               minOccurs="0" maxOccurs="unbounded">
+                                                               <xsd:annotation>
+                                                                       <xsd:documentation><![CDATA[
+       A reference specification attribute, that is, a reference to another object.
+                                                                       ]]></xsd:documentation>
+                                                               </xsd:annotation>
+                                                       </xsd:element>
+                                               </xsd:choice>
+                                       </xsd:sequence>
+                               </xsd:extension>
+                       </xsd:complexContent>
+               </xsd:complexType>
+       </xsd:element>
+
+       <xsd:complexType name="specAttributeType">
+               <xsd:choice>
+                       <xsd:element name="value" minOccurs="0" maxOccurs="1">
+                               <xsd:annotation>
+                                       <xsd:documentation><![CDATA[
+       The default value of the attribute as an inner bean.
+                                       ]]></xsd:documentation>
+                               </xsd:annotation>
+                               <xsd:complexType>
+                                       <xsd:choice minOccurs="1" maxOccurs="1">
+                                               <xsd:element ref="beans:bean" />
+                                               <xsd:element ref="beans:ref" />
+                                               <xsd:element ref="beans:list" />
+                                               <xsd:element ref="beans:set" />
+                                               <xsd:element ref="beans:map" />
+                                               <xsd:element ref="beans:props" />
+                                       </xsd:choice>
+                               </xsd:complexType>
+                       </xsd:element>
+               </xsd:choice>
+               <xsd:attribute name="name" use="required" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The name of the attribute, under which in can then be referenced.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="value" use="optional" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The default value of the attribute.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="ref" use="optional" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The default value of the attribute as a reference to another bean.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="isImmutable" use="optional" type="xsd:boolean"
+                       default="false">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       Whether the attribute is a parameter, that is, it has to be set at 
+       instantiation but can be modified afterwards for objects of scope execution.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="isParameter" use="optional" type="xsd:boolean"
+                       default="false">
+                       <!-- DEPRECATED: old name of isImmutable -->
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       Whether the attribute is a parameter, that is, it has to be set at 
+       instantiation but can be modified afterwards for objects of scope execution.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="isConstant" use="optional" type="xsd:boolean"
+                       default="false">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       Whether the attribute is frozen, that is, it cannot be modified at runtime.
+       A frozen attribute has to be a parameter.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="isFrozen" use="optional" type="xsd:boolean"
+                       default="false">
+                       <!-- DEPRECATED: old name of isConstant -->
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       Whether the attribute is frozen, that is, it cannot be modified at runtime.
+       A frozen attribute has to be a parameter.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="isHidden" use="optional" type="xsd:boolean"
+                       default="false">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       Whether the attribute is hidden, that is, it should not be displayed in UIs.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+       </xsd:complexType>
+
+       <xsd:complexType name="primitiveSpecAttributeType">
+               <xsd:complexContent>
+                       <xsd:extension base="flow:specAttributeType">
+                               <xsd:attribute name="type" default="string">
+                                       <xsd:annotation>
+                                               <xsd:documentation><![CDATA[
+       The type of the primitive specification attribute.
+                                               ]]></xsd:documentation>
+                                       </xsd:annotation>
+                                       <xsd:simpleType>
+                                               <xsd:restriction base="xsd:string">
+                                                       <xsd:enumeration value="string" />
+                                                       <xsd:enumeration value="password" />
+                                                       <xsd:enumeration value="integer" />
+                                                       <xsd:enumeration value="long" />
+                                                       <xsd:enumeration value="float" />
+                                                       <xsd:enumeration value="double" />
+                                                       <xsd:enumeration value="boolean" />
+                                               </xsd:restriction>
+                                       </xsd:simpleType>
+                               </xsd:attribute>
+                       </xsd:extension>
+               </xsd:complexContent>
+       </xsd:complexType>
+
+       <xsd:complexType name="refSpecAttributeType">
+               <xsd:complexContent>
+                       <xsd:extension base="flow:specAttributeType">
+                               <xsd:choice>
+                                       <xsd:element name="choices" minOccurs="0" maxOccurs="1">
+                                               <xsd:annotation>
+                                                       <xsd:documentation><![CDATA[
+       Possible values to chose from, if ommitted, all the beans in the 
+       application context which implement the provided targetClass will 
+       be considered.
+                                                       ]]></xsd:documentation>
+                                               </xsd:annotation>
+                                               <xsd:complexType>
+                                                       <xsd:choice>
+                                                               <xsd:element name="choice" minOccurs="0" maxOccurs="unbounded"
+                                                                       type="flow:refChoiceType">
+                                                                       <xsd:annotation>
+                                                                               <xsd:documentation><![CDATA[
+       A choice for a reference specification attribute.
+                                                                               ]]></xsd:documentation>
+                                                                       </xsd:annotation>
+                                                               </xsd:element>
+                                                       </xsd:choice>
+                                               </xsd:complexType>
+                                       </xsd:element>
+                               </xsd:choice>
+                               <xsd:attribute name="targetClass" use="required" type="xsd:string">
+                                       <xsd:annotation>
+                                               <xsd:documentation><![CDATA[
+       The class that has to be implemented by the underlying object.
+                                       ]]></xsd:documentation>
+                                       </xsd:annotation>
+                               </xsd:attribute>
+                       </xsd:extension>
+               </xsd:complexContent>
+       </xsd:complexType>
+
+       <xsd:complexType name="refChoiceType">
+               <xsd:attribute name="name" use="required" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The name of the related bean.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="description" use="optional" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       A human readable description of this choice.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+       </xsd:complexType>
+
+       <xsd:complexType name="argType">
+               <xsd:choice minOccurs="0" maxOccurs="1">
+                       <xsd:element ref="beans:bean" />
+                       <xsd:element ref="beans:ref" />
+                       <xsd:element ref="flow:param" />
+                       <xsd:element ref="beans:list" />
+                       <xsd:element ref="beans:set" />
+                       <xsd:element ref="beans:map" />
+                       <xsd:element ref="beans:props" />
+               </xsd:choice>
+               <xsd:attribute name="name" use="required" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The name of the related parameter.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="value" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The plain value of the related parameter.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+               <xsd:attribute name="ref" type="xsd:string">
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       The value of the related parameter as a reference to a bean.
+                               ]]></xsd:documentation>
+                       </xsd:annotation>
+               </xsd:attribute>
+       </xsd:complexType>
+
+       <xsd:attribute name="as-flow" type="xsd:string">
+               <xsd:annotation>
+                       <xsd:documentation><![CDATA[
+       If decorating an executable bean, it will generate an implicit SLC 
+       execution flow with the provided value as name.
+                       ]]></xsd:documentation>
+               </xsd:annotation>
+       </xsd:attribute>
+       <!-- <xsd:attribute name="var" type="xsd:boolean"> <xsd:annotation> <xsd:documentation><![CDATA[ 
+               If true, the decorated bean is set to scope execution and proxied. ]]></xsd:documentation> 
+               </xsd:annotation> </xsd:attribute> -->
+
+       <xsd:element name="variable">
+               <xsd:complexType>
+                       <xsd:annotation>
+                               <xsd:documentation><![CDATA[
+       Marks a bean definition as being variable, i.e. a scoped proxy of scope execution 
+                       ]]></xsd:documentation>
+                       </xsd:annotation>
+                       <xsd:attribute name="proxy-target-class" type="xsd:boolean"
+                               default="true">
+                               <xsd:annotation>
+                                       <xsd:documentation><![CDATA[
+                                               Are class-based (CGLIB) proxies to be created?
+                                               This is the default;
+                                               in order to switch to standard Java
+                                               interface-based proxies, turn this flag to
+                                               "false".
+                                       ]]></xsd:documentation>
+                               </xsd:annotation>
+                       </xsd:attribute>
+               </xsd:complexType>
+       </xsd:element>
+
+       <xsd:element name="param">
+               <xsd:annotation>
+                       <xsd:documentation><![CDATA[
+       If within a property tag of a bean, it will set the value of this property
+        with a reference to a parameter.
+                       ]]></xsd:documentation>
+               </xsd:annotation>
+               <xsd:complexType>
+                       <xsd:attribute name="name" type="xsd:string" use="required">
+                               <xsd:annotation>
+                                       <xsd:documentation><![CDATA[
+       The name of the related parameter.
+                                       ]]></xsd:documentation>
+                               </xsd:annotation>
+                       </xsd:attribute>
+                       <xsd:attribute name="instantiationManager" type="xsd:string"
+                               use="optional" default="instantiationManager">
+                               <xsd:annotation>
+                                       <xsd:documentation><![CDATA[
+       A reference to the instantiation manager to use instead of the default one
+       (expert usage).
+                                       ]]></xsd:documentation>
+                               </xsd:annotation>
+                       </xsd:attribute>
+               </xsd:complexType>
+       </xsd:element>
+
+</xsd:schema>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/BasicTestData.java b/org.argeo.slc.spring/src/org/argeo/slc/core/test/BasicTestData.java
new file mode 100644 (file)
index 0000000..39a97f2
--- /dev/null
@@ -0,0 +1,40 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.test.TestData;\r
+\r
+public class BasicTestData implements TestData {\r
+       private Object expected;\r
+       private Object reached;\r
+\r
+       public Object getExpected() {\r
+               return expected;\r
+       }\r
+\r
+       public void setExpected(Object expected) {\r
+               this.expected = expected;\r
+       }\r
+\r
+       public Object getReached() {\r
+               return reached;\r
+       }\r
+\r
+       public void setReached(Object reached) {\r
+               this.reached = reached;\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/BasicTestDefinition.java b/org.argeo.slc.spring/src/org/argeo/slc/core/test/BasicTestDefinition.java
new file mode 100644 (file)
index 0000000..6b92135
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.core.test.context.ContextUtils;\r
+import org.argeo.slc.test.IncompatibleTestDataException;\r
+import org.argeo.slc.test.TestData;\r
+import org.argeo.slc.test.TestDefinition;\r
+import org.argeo.slc.test.TestResult;\r
+import org.argeo.slc.test.TestRun;\r
+import org.argeo.slc.test.TestStatus;\r
+import org.argeo.slc.test.context.ContextAware;\r
+\r
+/** Understands basic test data and context aware test data. */\r
+public class BasicTestDefinition implements TestDefinition {\r
+\r
+       public void execute(TestRun testRun) {\r
+               if (testRun.<TestData> getTestData() instanceof BasicTestData) {\r
+                       BasicTestData testData = testRun.getTestData();\r
+                       TestResult result = testRun.getTestResult();\r
+\r
+                       if (result == null)\r
+                               throw new SlcException("No test result defined.");\r
+\r
+                       try {\r
+                               if (testData.getExpected().equals(testData.getReached())) {\r
+                                       result.addResultPart(new SimpleResultPart(\r
+                                                       TestStatus.PASSED, "Reached and expected equals"));\r
+                               } else {\r
+                                       result.addResultPart(new SimpleResultPart(\r
+                                                       TestStatus.FAILED, "Expected "\r
+                                                                       + testData.getExpected() + " but reached "\r
+                                                                       + testData.getReached()));\r
+                               }\r
+                       } catch (Exception e) {\r
+                               result.addResultPart(new SimpleResultPart(TestStatus.ERROR,\r
+                                               "Could not compare", e));\r
+                       }\r
+               } else if (testRun.<TestData> getTestData() instanceof ContextAware) {\r
+                       TestData testData = testRun.getTestData();\r
+                       ContextUtils.compareReachedExpected((ContextAware) testData,\r
+                                       testRun.getTestResult());\r
+               } else {\r
+                       throw new IncompatibleTestDataException(testRun);\r
+               }\r
+       }\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/SimpleResultPart.java b/org.argeo.slc.spring/src/org/argeo/slc/core/test/SimpleResultPart.java
new file mode 100644 (file)
index 0000000..8ad81af
--- /dev/null
@@ -0,0 +1,150 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import java.io.Serializable;\r
+\r
+import org.argeo.slc.test.TestResultPart;\r
+import org.argeo.slc.test.TestRun;\r
+import org.argeo.slc.test.TestRunAware;\r
+import org.argeo.slc.test.TestStatus;\r
+\r
+/**\r
+ * <p>\r
+ * Basic implementation of a result part, implementing the standard three status\r
+ * approach for test results.\r
+ * </p>\r
+ * \r
+ * @see TestStatus\r
+ */\r
+public class SimpleResultPart implements TestResultPart, TestStatus,\r
+               TestRunAware, Serializable {\r
+       private static final long serialVersionUID = 6669675957685071901L;\r
+\r
+       private Long tid;\r
+\r
+       private String testRunUuid;\r
+\r
+       /** The status. Default to ERROR since it should always be explicitely set. */\r
+       private Integer status = ERROR;\r
+       private String message;\r
+       private String exceptionMessage;\r
+\r
+       public SimpleResultPart() {\r
+       }\r
+\r
+       public SimpleResultPart(Integer status, String message) {\r
+               this(status, message, null);\r
+       }\r
+\r
+       public SimpleResultPart(Integer status, String message, Exception exception) {\r
+               this.status = status;\r
+               this.message = message;\r
+               setException(exception);\r
+       }\r
+\r
+       public String getMessage() {\r
+               return message;\r
+       }\r
+\r
+       public void setMessage(String message) {\r
+               this.message = message;\r
+       }\r
+\r
+       public void setStatus(Integer status) {\r
+               this.status = status;\r
+       }\r
+\r
+       public Integer getStatus() {\r
+               return status;\r
+       }\r
+\r
+       public String getExceptionMessage() {\r
+               return exceptionMessage;\r
+       }\r
+\r
+       public void setException(Exception exception) {\r
+               if (exception == null)\r
+                       return;\r
+\r
+               StringBuffer buf = new StringBuffer("");\r
+               buf.append(exception.toString());\r
+               buf.append('\n');\r
+               for (StackTraceElement elem : exception.getStackTrace()) {\r
+                       buf.append('\t').append(elem.toString()).append('\n');\r
+               }\r
+\r
+               if (exception.getCause() != null)\r
+                       addRootCause(buf, exception.getCause());\r
+\r
+               this.exceptionMessage = buf.toString();\r
+       }\r
+\r
+       protected void addRootCause(StringBuffer buf, Throwable cause) {\r
+               if (cause == null)\r
+                       return;\r
+\r
+               buf.append("Caused by: " + cause.getMessage());\r
+               for (StackTraceElement elem : cause.getStackTrace()) {\r
+                       buf.append('\t').append(elem.toString()).append('\n');\r
+               }\r
+\r
+               if (cause.getCause() != null) {\r
+                       addRootCause(buf, cause.getCause());\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public String toString() {\r
+               StringBuffer buf = new StringBuffer("");\r
+               buf.append(SlcTestUtils.statusToString(status));\r
+               if (status == PASSED || status == FAILED) {\r
+                       buf.append(' ');\r
+               } else if (status == ERROR) {\r
+                       buf.append("  ");\r
+               }\r
+               buf.append(message);\r
+               return buf.toString();\r
+       }\r
+\r
+       /** @deprecated */\r
+       Long getTid() {\r
+               return tid;\r
+       }\r
+\r
+       /** @deprecated */\r
+       void setTid(Long tid) {\r
+               this.tid = tid;\r
+       }\r
+\r
+       public String getTestRunUuid() {\r
+               return testRunUuid;\r
+       }\r
+\r
+       /** For ORM */\r
+       public void setTestRunUuid(String testRunUuid) {\r
+               this.testRunUuid = testRunUuid;\r
+       }\r
+\r
+       public void notifyTestRun(TestRun testRun) {\r
+               testRunUuid = testRun.getUuid();\r
+       }\r
+\r
+       public void setExceptionMessage(String exceptionMessage) {\r
+               this.exceptionMessage = exceptionMessage;\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/SimpleTestResult.java b/org.argeo.slc.spring/src/org/argeo/slc/core/test/SimpleTestResult.java
new file mode 100644 (file)
index 0000000..93306a5
--- /dev/null
@@ -0,0 +1,103 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+import java.util.UUID;\r
+import java.util.Vector;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.test.TestResult;\r
+import org.argeo.slc.test.TestResultPart;\r
+import org.argeo.slc.test.TestRun;\r
+\r
+/**\r
+ * Basic implementation of a test result containing only a list of result parts.\r
+ */\r
+public class SimpleTestResult implements TestResult {\r
+       private static Log log = LogFactory.getLog(SimpleTestResult.class);\r
+\r
+       private String uuid;\r
+       private String currentTestRunUuid;\r
+\r
+       private Boolean throwError = true;\r
+\r
+       private Date closeDate;\r
+       private List<TestResultPart> parts = new Vector<TestResultPart>();\r
+\r
+       private Map<String, String> attributes = new TreeMap<String, String>();\r
+\r
+       public void addResultPart(TestResultPart part) {\r
+               if (throwError && part.getStatus() == ERROR) {\r
+                       throw new SlcException(\r
+                                       "There was an error in the underlying test: "\r
+                                                       + part.getExceptionMessage());\r
+               }\r
+               parts.add(part);\r
+               if (log.isDebugEnabled())\r
+                       log.debug(part);\r
+       }\r
+\r
+       public void close() {\r
+               parts.clear();\r
+               closeDate = new Date();\r
+       }\r
+\r
+       public List<TestResultPart> getParts() {\r
+               return parts;\r
+       }\r
+\r
+       public Date getCloseDate() {\r
+               return closeDate;\r
+       }\r
+\r
+       public void setThrowError(Boolean throwError) {\r
+               this.throwError = throwError;\r
+       }\r
+\r
+       public void notifyTestRun(TestRun testRun) {\r
+               currentTestRunUuid = testRun.getUuid();\r
+       }\r
+\r
+       public String getUuid() {\r
+               if (uuid == null) {\r
+                       uuid = UUID.randomUUID().toString();\r
+               }\r
+               return uuid;\r
+       }\r
+\r
+       public void setUuid(String uuid) {\r
+               this.uuid = uuid;\r
+       }\r
+\r
+       public String getCurrentTestRunUuid() {\r
+               return currentTestRunUuid;\r
+       }\r
+\r
+       public Map<String, String> getAttributes() {\r
+               return attributes;\r
+       }\r
+\r
+       public void setAttributes(Map<String, String> attributes) {\r
+               this.attributes = attributes;\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/SimpleTestRun.java b/org.argeo.slc.spring/src/org/argeo/slc/core/test/SimpleTestRun.java
new file mode 100644 (file)
index 0000000..4f6a12f
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import java.util.UUID;\r
+\r
+import org.argeo.slc.deploy.DeployedSystem;\r
+import org.argeo.slc.test.ExecutableTestRun;\r
+import org.argeo.slc.test.TestData;\r
+import org.argeo.slc.test.TestDefinition;\r
+import org.argeo.slc.test.TestResult;\r
+import org.argeo.slc.test.WritableTestRun;\r
+\r
+/**\r
+ * A basic bean implementation of a <code>WritableTestRun</code>, holding\r
+ * references to the various parts of a test run.\r
+ */\r
+public class SimpleTestRun implements WritableTestRun, ExecutableTestRun {\r
+       private String uuid;\r
+\r
+       // private String slcExecutionUuid;\r
+       // private String slcExecutionStepUuid;\r
+\r
+       private DeployedSystem deployedSystem;\r
+       private TestData testData;\r
+       private TestDefinition testDefinition;\r
+       private TestResult testResult;\r
+\r
+       /** Executes the underlying test definition. */\r
+       public void run() {\r
+               uuid = UUID.randomUUID().toString();\r
+               if (testResult != null)\r
+                       testResult.notifyTestRun(this);\r
+\r
+               testDefinition.execute(this);\r
+       }\r
+\r
+       @SuppressWarnings("unchecked")\r
+       public <T extends DeployedSystem> T getDeployedSystem() {\r
+               return (T) deployedSystem;\r
+       }\r
+\r
+       public void setDeployedSystem(DeployedSystem deployedSystem) {\r
+               this.deployedSystem = deployedSystem;\r
+       }\r
+\r
+       @SuppressWarnings("unchecked")\r
+       public <T extends TestData> T getTestData() {\r
+               return (T) testData;\r
+       }\r
+\r
+       public void setTestData(TestData testData) {\r
+               this.testData = testData;\r
+       }\r
+\r
+       @SuppressWarnings("unchecked")\r
+       public <T extends TestDefinition> T getTestDefinition() {\r
+               return (T) testDefinition;\r
+       }\r
+\r
+       public void setTestDefinition(TestDefinition testDefinition) {\r
+               this.testDefinition = testDefinition;\r
+       }\r
+\r
+       @SuppressWarnings("unchecked")\r
+       public <T extends TestResult> T getTestResult() {\r
+               return (T) testResult;\r
+       }\r
+\r
+       public void setTestResult(TestResult testResult) {\r
+               this.testResult = testResult;\r
+       }\r
+\r
+       public String getUuid() {\r
+               return uuid;\r
+       }\r
+\r
+       public void setUuid(String uuid) {\r
+               this.uuid = uuid;\r
+       }\r
+\r
+       // public String getSlcExecutionUuid() {\r
+       // return slcExecutionUuid;\r
+       // }\r
+       //\r
+       // public void setSlcExecutionUuid(String slcExecutionUuid) {\r
+       // this.slcExecutionUuid = slcExecutionUuid;\r
+       // }\r
+       //\r
+       // public String getSlcExecutionStepUuid() {\r
+       // return slcExecutionStepUuid;\r
+       // }\r
+       //\r
+       // public void setSlcExecutionStepUuid(String slcExecutionStepUuid) {\r
+       // this.slcExecutionStepUuid = slcExecutionStepUuid;\r
+       // }\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/SlcTestUtils.java b/org.argeo.slc.spring/src/org/argeo/slc/core/test/SlcTestUtils.java
new file mode 100644 (file)
index 0000000..c926a69
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.test;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.test.TestStatus;
+
+public abstract class SlcTestUtils {
+       public static String statusToString(Integer status) {
+               if (status.equals(TestStatus.PASSED)) {
+                       return TestStatus.STATUSSTR_PASSED;
+               } else if (status.equals(TestStatus.FAILED)) {
+                       return TestStatus.STATUSSTR_FAILED;
+               } else if (status.equals(TestStatus.ERROR)) {
+                       return TestStatus.STATUSSTR_ERROR;
+               } else {
+                       throw new SlcException("Unrecognized status " + status);
+               }
+       }
+
+       public static Integer stringToStatus(String statusStr) {
+               if (statusStr.equals(TestStatus.STATUSSTR_PASSED)) {
+                       return TestStatus.PASSED;
+               } else if (statusStr.equals(TestStatus.STATUSSTR_FAILED)) {
+                       return TestStatus.FAILED;
+               } else if (statusStr.equals(TestStatus.STATUSSTR_ERROR)) {
+                       return TestStatus.ERROR;
+               } else {
+                       throw new SlcException("Unrecognized status string " + statusStr);
+               }
+       }
+
+       private SlcTestUtils() {
+
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/TestDataUtils.java b/org.argeo.slc.spring/src/org/argeo/slc/core/test/TestDataUtils.java
new file mode 100644 (file)
index 0000000..b32da38
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.UnsupportedException;\r
+import org.argeo.slc.test.TestData;\r
+import org.argeo.slc.test.TestDataProvider;\r
+\r
+/** Utilities for dealing with test datas. */\r
+public class TestDataUtils {\r
+       /** Extracts the test data from the given provider. */\r
+       public static <T extends TestData> T getFromProvider(Object obj,\r
+                       Class<T> clss, String key) {\r
+               if (obj instanceof TestDataProvider) {\r
+                       TestDataProvider testDataProvider = (TestDataProvider) obj;\r
+                       return testDataProvider.getTestData(clss, key);\r
+               } else {\r
+                       throw new UnsupportedException("test data provider", obj);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Extracts the test data from the given provider using <code>null</code>\r
+        * as key.\r
+        */\r
+       public static <T extends TestData> T getFromProvider(Object obj,\r
+                       Class<T> clss) {\r
+               return getFromProvider(obj, clss, null);\r
+       }\r
+\r
+       /**\r
+        * Returns it self after making the proper checks. Used for test data being\r
+        * their own data providers.\r
+        */\r
+       @SuppressWarnings("unchecked")\r
+       public static <T extends TestData> T getItSelf(Class<T> clss,\r
+                       TestData testDataObject) {\r
+               if (clss.isAssignableFrom(testDataObject.getClass())) {\r
+                       return (T) testDataObject;\r
+               } else {\r
+                       throw new UnsupportedException("test data", testDataObject);\r
+               }\r
+\r
+       }\r
+\r
+       /** Makes sure this is an utility class. */\r
+       private TestDataUtils() {\r
+\r
+       }\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/context/ContextUtils.java b/org.argeo.slc.spring/src/org/argeo/slc/core/test/context/ContextUtils.java
new file mode 100644 (file)
index 0000000..f62fb5c
--- /dev/null
@@ -0,0 +1,140 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.core.test.SimpleResultPart;\r
+import org.argeo.slc.test.TestResult;\r
+import org.argeo.slc.test.TestStatus;\r
+import org.argeo.slc.test.context.ContextAware;\r
+import org.argeo.slc.test.context.ParentContextAware;\r
+\r
+/** Utilities for comparing and synchronising contexts. */\r
+public class ContextUtils {\r
+       private final static Log log = LogFactory.getLog(ContextUtils.class);\r
+\r
+       public static void compareReachedExpected(ContextAware contextAware,\r
+                       TestResult testResult) {\r
+               for (String key : contextAware.getExpectedValues().keySet()) {\r
+\r
+                       // Compare expected values with reached ones\r
+                       Object expectedValue = contextAware.getExpectedValues().get(key);\r
+\r
+                       if (expectedValue.toString().equals(\r
+                                       contextAware.getContextSkipFlag())) {\r
+                               if (log.isDebugEnabled())\r
+                                       log.debug("Skipped check for key '" + key + "'");\r
+                               continue;\r
+                       }\r
+\r
+                       if (contextAware.getValues().containsKey(key)) {\r
+                               Object reachedValue = contextAware.getValues().get(key);\r
+\r
+                               if (expectedValue.equals(contextAware.getContextAnyFlag())) {\r
+                                       testResult.addResultPart(new SimpleResultPart(\r
+                                                       TestStatus.PASSED, "Expected any value for key '"\r
+                                                                       + key + "'"));\r
+                               } else if (expectedValue.equals(reachedValue)) {\r
+                                       testResult.addResultPart(new SimpleResultPart(\r
+                                                       TestStatus.PASSED, "Values matched for key '" + key\r
+                                                                       + "'"));\r
+                               } else {\r
+                                       testResult.addResultPart(new SimpleResultPart(\r
+                                                       TestStatus.FAILED, "Mismatch for key '" + key\r
+                                                                       + "': expected '" + expectedValue\r
+                                                                       + "' but reached '" + reachedValue + "'"));\r
+                               }\r
+                       } else {\r
+                               testResult.addResultPart(new SimpleResultPart(\r
+                                               TestStatus.FAILED, "No value reached for key '" + key\r
+                                                               + "'"));\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Makes sure that all children and sub-children of parent share the same\r
+        * maps for values and expected values.\r
+        */\r
+       public static void synchronize(ParentContextAware parent) {\r
+               Map<String, Object> expectedValuesCommon = new TreeMap<String, Object>(\r
+                               parent.getExpectedValues());\r
+               synchronize(parent, expectedValuesCommon);\r
+               if (log.isDebugEnabled())\r
+                       log.debug("Synchronized context " + parent);\r
+\r
+       }\r
+\r
+       private static void synchronize(ParentContextAware parent,\r
+                       Map<String, Object> expectedValuesCommon) {\r
+               for (ContextAware child : parent.getChildContexts()) {\r
+                       // Values\r
+                       putNotContained(parent.getValues(), child.getValues());\r
+                       child.setValues(parent.getValues());\r
+\r
+                       // Expected Values\r
+                       // Expected values reference is not overridden: each child has its\r
+                       // own expected values map.\r
+                       overrideContained(expectedValuesCommon, child.getExpectedValues());\r
+\r
+                       // Creates a new Map in order not to disturb other context using the\r
+                       // same keys\r
+                       Map<String, Object> expectedValuesCommonChild = new TreeMap<String, Object>(\r
+                                       expectedValuesCommon);\r
+                       putNotContained(expectedValuesCommonChild,\r
+                                       child.getExpectedValues());\r
+\r
+                       if (child instanceof ParentContextAware) {\r
+                               // Recursive sync\r
+                               synchronize((ParentContextAware) child,\r
+                                               expectedValuesCommonChild);\r
+                       }\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Put into common map the values from child map which are not already\r
+        * defined in common map.\r
+        */\r
+       public static void putNotContained(Map<String, Object> commonMap,\r
+                       Map<String, Object> childMap) {\r
+               for (String key : childMap.keySet()) {\r
+                       if (!commonMap.containsKey(key)) {\r
+                               commonMap.put(key, childMap.get(key));\r
+                       }\r
+               }\r
+       }\r
+\r
+       /** Overrides child map values with the values already set in common map */\r
+       public static void overrideContained(Map<String, Object> commonMap,\r
+                       Map<String, Object> childMap) {\r
+               for (String key : childMap.keySet()) {\r
+                       if (commonMap.containsKey(key)) {\r
+                               childMap.put(key, commonMap.get(key));\r
+                       }\r
+               }\r
+       }\r
+\r
+       /** Makes sure this cannot be instantiated. */\r
+       private ContextUtils() {\r
+\r
+       }\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/context/DefaultContextTestData.java b/org.argeo.slc.spring/src/org/argeo/slc/core/test/context/DefaultContextTestData.java
new file mode 100644 (file)
index 0000000..ca0bf5f
--- /dev/null
@@ -0,0 +1,29 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import org.argeo.slc.core.test.TestDataUtils;\r
+import org.argeo.slc.test.TestData;\r
+import org.argeo.slc.test.TestDataProvider;\r
+\r
+public class DefaultContextTestData extends SimpleContextAware implements\r
+               TestData, TestDataProvider {\r
+\r
+       public <T extends TestData> T getTestData(Class<T> clss, String key) {\r
+               return TestDataUtils.getItSelf(clss, this);\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/context/SimpleContextAware.java b/org.argeo.slc.spring/src/org/argeo/slc/core/test/context/SimpleContextAware.java
new file mode 100644 (file)
index 0000000..f10be56
--- /dev/null
@@ -0,0 +1,85 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.test.context.ContextAware;\r
+import org.argeo.slc.test.context.ParentContextAware;\r
+import org.springframework.beans.factory.InitializingBean;\r
+\r
+public class SimpleContextAware implements ContextAware, InitializingBean {\r
+       private ParentContextAware parentContext;\r
+\r
+       private Map<String, Object> values = new TreeMap<String, Object>();\r
+       private Map<String, Object> expectedValues = new TreeMap<String, Object>();\r
+\r
+       private String contextSkipFlag = DEFAULT_SKIP_FLAG;\r
+       private String contextAnyFlag = DEFAULT_ANY_FLAG;\r
+\r
+       public Map<String, Object> getValues() {\r
+               return values;\r
+       }\r
+\r
+       public void setValues(Map<String, Object> values) {\r
+               this.values = values;\r
+       }\r
+\r
+       public Map<String, Object> getExpectedValues() {\r
+               return expectedValues;\r
+       }\r
+\r
+       public void setExpectedValues(Map<String, Object> expectedValues) {\r
+               this.expectedValues = expectedValues;\r
+       }\r
+\r
+       /** Used to add this context as a child by setting a property. */\r
+       public void setParentContext(ParentContextAware parentContextAware) {\r
+               if (parentContext != null)\r
+                       throw new SlcException("Parent context already set");\r
+               this.parentContext = parentContextAware;\r
+               this.parentContext.addChildContext(this);\r
+       }\r
+\r
+       protected ParentContextAware getParentContext() {\r
+               return parentContext;\r
+       }\r
+\r
+       public void afterPropertiesSet() throws Exception {\r
+               if (parentContext != null) {\r
+                       ContextUtils.synchronize(parentContext);\r
+               }\r
+       }\r
+\r
+       public String getContextSkipFlag() {\r
+               return contextSkipFlag;\r
+       }\r
+\r
+       public void setContextSkipFlag(String contextSkipFlag) {\r
+               this.contextSkipFlag = contextSkipFlag;\r
+       }\r
+\r
+       public String getContextAnyFlag() {\r
+               return contextAnyFlag;\r
+       }\r
+\r
+       public void setContextAnyFlag(String contextAnyFlag) {\r
+               this.contextAnyFlag = contextAnyFlag;\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/context/SimpleParentContextAware.java b/org.argeo.slc.spring/src/org/argeo/slc/core/test/context/SimpleParentContextAware.java
new file mode 100644 (file)
index 0000000..b8abf7f
--- /dev/null
@@ -0,0 +1,50 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Collection;\r
+import java.util.List;\r
+import java.util.Vector;\r
+\r
+import org.argeo.slc.test.context.ContextAware;\r
+import org.argeo.slc.test.context.ParentContextAware;\r
+import org.springframework.beans.factory.InitializingBean;\r
+\r
+public class SimpleParentContextAware extends SimpleContextAware implements\r
+               ParentContextAware, InitializingBean {\r
+       private List<ContextAware> children = new Vector<ContextAware>();\r
+\r
+       public Collection<ContextAware> getChildContexts() {\r
+               return children;\r
+       }\r
+\r
+       public void addChildContext(ContextAware contextAware) {\r
+               children.add(contextAware);\r
+       }\r
+\r
+       @Override\r
+       public void afterPropertiesSet() throws Exception {\r
+               if (getParentContext() != null) {\r
+                       // If has a parent, sync it.\r
+                       super.afterPropertiesSet();\r
+               } else {\r
+                       if (children.size() > 0) {\r
+                               // No need to synchronize if no children\r
+                               ContextUtils.synchronize(this);\r
+                       }\r
+               }\r
+       }\r
+}\r
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/context/package.html b/org.argeo.slc.spring/src/org/argeo/slc/core/test/context/package.html
new file mode 100644 (file)
index 0000000..cd08d63
--- /dev/null
@@ -0,0 +1,6 @@
+<html>\r
+<head></head>\r
+<body>\r
+Context variables to be passed between parts of tests.\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/package.html b/org.argeo.slc.spring/src/org/argeo/slc/core/test/package.html
new file mode 100644 (file)
index 0000000..c70d2d1
--- /dev/null
@@ -0,0 +1,6 @@
+<html>\r
+<head></head>\r
+<body>\r
+SLC Test: test of software systems.\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/core/test/spring.xml b/org.argeo.slc.spring/src/org/argeo/slc/core/test/spring.xml
new file mode 100644 (file)
index 0000000..31cf671
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (C) 2007-2012 Argeo GmbH
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+            http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
+    default-lazy-init="true">
+
+    <bean name="slcDefault.test.testRun"
+        class="org.argeo.slc.core.test.SimpleTestRun"
+        scope="prototype">
+    </bean>
+
+    <bean name="slcDefault.test.uuid" class="java.util.UUID"
+        factory-method="randomUUID" scope="prototype">
+    </bean>
+
+    <bean id="slcDefault.test.basicSimpleTestResult"
+        class="org.argeo.slc.core.test.SimpleTestResult"
+        abstract="true">
+        <property name="uuid">
+            <bean factory-bean="slcDefault.test.uuid"
+                factory-method="toString">
+            </bean>
+        </property>
+    </bean>
+
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/jcr/JcrMetadataWriter.java b/org.argeo.slc.spring/src/org/argeo/slc/jcr/JcrMetadataWriter.java
new file mode 100644 (file)
index 0000000..c4922d3
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.jcr;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.SlcNames;
+
+/**
+ * Writes arbitrary metadata into a child node of a given node (or the node
+ * itself if metadata node name is set to null)
+ */
+public class JcrMetadataWriter implements Runnable {
+       private final static Log log = LogFactory.getLog(JcrMetadataWriter.class);
+
+       private Node baseNode;
+       private String metadataNodeName = SlcNames.SLC_METADATA;
+
+       private Map<String, String> metadata = new HashMap<String, String>();
+
+       public void run() {
+               try {
+                       Node metadataNode;
+                       if (metadataNodeName != null)
+                               metadataNode = baseNode.hasNode(metadataNodeName) ? baseNode
+                                               .getNode(metadataNodeName) : baseNode
+                                               .addNode(metadataNodeName);
+                       else
+                               metadataNode = baseNode;
+
+                       for (String key : metadata.keySet())
+                               metadataNode.setProperty(key, metadata.get(key));
+
+                       baseNode.getSession().save();
+
+                       if (log.isDebugEnabled())
+                               log.debug("Wrote " + metadata.size() + " metadata entries to "
+                                               + metadataNode);
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot write metadata to " + baseNode, e);
+               } finally {
+                       JcrUtils.discardUnderlyingSessionQuietly(baseNode);
+               }
+
+       }
+
+       public void setBaseNode(Node baseNode) {
+               this.baseNode = baseNode;
+       }
+
+       public void setMetadataNodeName(String metadataNodeName) {
+               this.metadataNodeName = metadataNodeName;
+       }
+
+       public void setMetadata(Map<String, String> metadata) {
+               this.metadata = metadata;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/jcr/JcrTestResult.java b/org.argeo.slc.spring/src/org/argeo/slc/jcr/JcrTestResult.java
new file mode 100644 (file)
index 0000000..c9ec874
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.jcr;
+
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.SlcNames;
+import org.argeo.slc.SlcTypes;
+import org.argeo.slc.core.attachment.Attachment;
+import org.argeo.slc.core.attachment.AttachmentsEnabled;
+import org.argeo.slc.test.TestResult;
+import org.argeo.slc.test.TestResultPart;
+import org.argeo.slc.test.TestRun;
+import org.argeo.slc.test.TestStatus;
+
+/**
+ * {@link TestResult} wrapping a JCR node of type
+ * {@link SlcTypes#SLC_TEST_RESULT}.
+ */
+public class JcrTestResult implements TestResult, SlcNames, AttachmentsEnabled {
+       private final static Log log = LogFactory.getLog(JcrTestResult.class);
+
+       /** Should only be set for an already existing result. */
+       private String uuid;
+       private Repository repository;
+       private Session session;
+       /**
+        * For testing purposes, best practice is to not set them explicitely but
+        * via other mechanisms such as JAAS or SPring Security.
+        */
+       private Credentials credentials = null;
+       private String resultType = SlcTypes.SLC_TEST_RESULT;
+
+       /** cached for performance purposes */
+       private String nodeIdentifier = null;
+
+       private Map<String, String> attributes = new HashMap<String, String>();
+
+       public void init() {
+               try {
+                       session = repository.login(credentials);
+                       if (uuid == null) {
+                               // create new result
+                               uuid = UUID.randomUUID().toString();
+                               String path = SlcJcrUtils.createResultPath(session, uuid);
+                               Node resultNode = JcrUtils.mkdirs(session, path, resultType);
+                               resultNode.setProperty(SLC_UUID, uuid);
+                               for (String attr : attributes.keySet()) {
+                                       String property = attr;
+                                       // compatibility with legacy applications
+                                       if ("testCase".equals(attr))
+                                               property = SLC_TEST_CASE;
+                                       else if ("testCaseType".equals(attr))
+                                               property = SLC_TEST_CASE_TYPE;
+                                       resultNode.setProperty(property, attributes.get(attr));
+                               }
+                               session.save();
+                               if (log.isDebugEnabled())
+                                       log.debug("Created test result " + uuid);
+                       }
+               } catch (Exception e) {
+                       JcrUtils.discardQuietly(session);
+                       throw new SlcException("Cannot initialize JCR result", e);
+               }
+       }
+
+       public void destroy() {
+               JcrUtils.logoutQuietly(session);
+               if (log.isTraceEnabled())
+                       log.trace("Logged out session for result " + uuid);
+       }
+
+       public Node getNode() {
+               try {
+                       Node resultNode;
+                       if (nodeIdentifier != null) {
+                               return session.getNodeByIdentifier(nodeIdentifier);
+                       } else {
+                               QueryManager qm = session.getWorkspace().getQueryManager();
+                               Query q = qm.createQuery("select * from ["
+                                               + SlcTypes.SLC_TEST_RESULT + "] where [slc:uuid]='"
+                                               + uuid + "'", Query.JCR_SQL2);
+                               resultNode = JcrUtils.querySingleNode(q);
+                               if (resultNode != null)
+                                       nodeIdentifier = resultNode.getIdentifier();
+                       }
+                       return resultNode;
+               } catch (Exception e) {
+                       throw new SlcException("Cannot get result node", e);
+               }
+       }
+
+       public void notifyTestRun(TestRun testRun) {
+               // TODO store meta data about the test running
+               // if (log.isDebugEnabled())
+               // log.debug("Running test "
+               // + testRun.getTestDefinition().getClass().getName() + "...");
+       }
+
+       public void addResultPart(TestResultPart testResultPart) {
+               Node node = getNode();
+
+               try {
+                       // error : revert all unsaved changes on the resultNode to be sure
+                       // it is in a consistant state
+                       if (testResultPart.getExceptionMessage() != null)
+                               JcrUtils.discardQuietly(node.getSession());
+                       node.getSession().save();
+
+                       // add the new result part, retrieving status information
+                       Node resultPartNode = node.addNode(SlcNames.SLC_RESULT_PART,
+                                       SlcTypes.SLC_CHECK);
+                       resultPartNode.setProperty(SLC_SUCCESS, testResultPart.getStatus()
+                                       .equals(TestStatus.PASSED));
+                       if (testResultPart.getMessage() != null)
+                               resultPartNode.setProperty(SLC_MESSAGE,
+                                               testResultPart.getMessage());
+                       if (testResultPart.getStatus().equals(TestStatus.ERROR)) {
+                               resultPartNode.setProperty(SLC_ERROR_MESSAGE,
+                                               (testResultPart.getExceptionMessage() == null) ? ""
+                                                               : testResultPart.getExceptionMessage());
+                       }
+
+                       // helper update aggregate status node
+                       Node mainStatus;
+                       if (!node.hasNode(SLC_AGGREGATED_STATUS)) {
+
+                               mainStatus = node.addNode(SLC_AGGREGATED_STATUS,
+                                               SlcTypes.SLC_CHECK);
+                               mainStatus.setProperty(SLC_SUCCESS,
+                                               resultPartNode.getProperty(SLC_SUCCESS).getBoolean());
+                               if (resultPartNode.hasProperty(SLC_MESSAGE))
+                                       mainStatus.setProperty(SLC_MESSAGE, resultPartNode
+                                                       .getProperty(SLC_MESSAGE).getString());
+                               if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE))
+                                       mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode
+                                                       .getProperty(SLC_ERROR_MESSAGE).getString());
+                       } else {
+                               mainStatus = node.getNode(SLC_AGGREGATED_STATUS);
+                               if (mainStatus.hasProperty(SLC_ERROR_MESSAGE)) {
+                                       // main status already in error we do nothing
+                               } else if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE)) {
+                                       // main status was not in error and new result part is in
+                                       // error; we update main status
+                                       mainStatus.setProperty(SLC_SUCCESS, false);
+                                       mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode
+                                                       .getProperty(SLC_ERROR_MESSAGE).getString());
+                                       if (resultPartNode.hasProperty(SLC_MESSAGE))
+                                               mainStatus.setProperty(SLC_MESSAGE, resultPartNode
+                                                               .getProperty(SLC_MESSAGE).getString());
+                                       else
+                                               // remove old message to remain consistent
+                                               mainStatus.setProperty(SLC_MESSAGE, "");
+                               } else if (!mainStatus.getProperty(SLC_SUCCESS).getBoolean()) {
+                                       // main status was already failed and new result part is not
+                                       // in error, we do nothing
+                               } else if (!resultPartNode.getProperty(SLC_SUCCESS)
+                                               .getBoolean()) {
+                                       // new resultPart that is failed
+                                       mainStatus.setProperty(SLC_SUCCESS, false);
+                                       if (resultPartNode.hasProperty(SLC_MESSAGE))
+                                               mainStatus.setProperty(SLC_MESSAGE, resultPartNode
+                                                               .getProperty(SLC_MESSAGE).getString());
+                                       else
+                                               // remove old message to remain consistent
+                                               mainStatus.setProperty(SLC_MESSAGE, "");
+                               } else if (resultPartNode.hasProperty(SLC_MESSAGE)
+                                               && (!mainStatus.hasProperty(SLC_MESSAGE) || (""
+                                                               .equals(mainStatus.getProperty(SLC_MESSAGE)
+                                                                               .getString().trim())))) {
+                                       mainStatus.setProperty(SLC_MESSAGE, resultPartNode
+                                                       .getProperty(SLC_MESSAGE).getString());
+                               }
+                       }
+                       JcrUtils.updateLastModified(node);
+                       node.getSession().save();
+               } catch (Exception e) {
+                       JcrUtils.discardUnderlyingSessionQuietly(node);
+                       throw new SlcException("Cannot add ResultPart to node " + node, e);
+               }
+       }
+
+       public String getUuid() {
+               Node node = getNode();
+               try {
+                       return node.getProperty(SLC_UUID).getString();
+               } catch (Exception e) {
+                       throw new SlcException("Cannot get UUID from " + node, e);
+               }
+       }
+
+       /** JCR session is NOT logged out */
+       public void close() {
+               Node node = getNode();
+               try {
+                       if (node.hasNode(SLC_COMPLETED))
+                               return;
+                       node.setProperty(SLC_COMPLETED, new GregorianCalendar());
+                       JcrUtils.updateLastModified(node);
+                       node.getSession().save();
+               } catch (Exception e) {
+                       JcrUtils.discardUnderlyingSessionQuietly(node);
+                       throw new SlcException("Cannot get close date from " + node, e);
+               }
+       }
+
+       public Date getCloseDate() {
+               Node node = getNode();
+               try {
+                       if (!node.hasNode(SLC_COMPLETED))
+                               return null;
+                       return node.getProperty(SLC_COMPLETED).getDate().getTime();
+               } catch (Exception e) {
+                       throw new SlcException("Cannot get close date from " + node, e);
+               }
+       }
+
+       public Map<String, String> getAttributes() {
+               Node node = getNode();
+               try {
+                       Map<String, String> map = new HashMap<String, String>();
+                       PropertyIterator pit = node.getProperties();
+                       while (pit.hasNext()) {
+                               Property p = pit.nextProperty();
+                               if (!p.isMultiple())
+                                       map.put(p.getName(), p.getValue().getString());
+                       }
+                       return map;
+               } catch (Exception e) {
+                       throw new SlcException("Cannot get close date from " + node, e);
+               }
+       }
+
+       public void addAttachment(Attachment attachment) {
+               // TODO implement it
+       }
+
+       public void setUuid(String uuid) {
+               this.uuid = uuid;
+       }
+
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+
+       public void setResultType(String resultType) {
+               this.resultType = resultType;
+       }
+
+       public void setAttributes(Map<String, String> attributes) {
+               if (uuid != null)
+                       throw new SlcException(
+                                       "Attributes cannot be set on an already initialized test result."
+                                                       + " Update the related JCR node directly instead.");
+               this.attributes = attributes;
+       }
+
+       public void setCredentials(Credentials credentials) {
+               this.credentials = credentials;
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/jcr/SlcJcrConstants.java b/org.argeo.slc.spring/src/org/argeo/slc/jcr/SlcJcrConstants.java
new file mode 100644 (file)
index 0000000..3190c85
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.jcr;
+
+import org.argeo.slc.SlcNames;
+
+/** JCR related constants used across SLC */
+public interface SlcJcrConstants {
+       public final static String PROPERTY_PATH = "argeo.slc.jcr.path";
+
+       public final static String SLC_BASE_PATH = "/" + SlcNames.SLC_SYSTEM;
+       public final static String AGENTS_BASE_PATH = SLC_BASE_PATH + "/"
+                       + SlcNames.SLC_AGENTS;
+       public final static String VM_AGENT_FACTORY_PATH = AGENTS_BASE_PATH + "/"
+                       + SlcNames.SLC_VM;
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/jcr/SlcJcrResultUtils.java b/org.argeo.slc.spring/src/org/argeo/slc/jcr/SlcJcrResultUtils.java
new file mode 100644 (file)
index 0000000..6353804
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.jcr;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.node.NodeUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.SlcNames;
+import org.argeo.slc.SlcTypes;
+
+/**
+ * Utilities around the SLC JCR Result model. Note that it relies on fixed base
+ * paths (convention over configuration) for optimization purposes.
+ */
+public class SlcJcrResultUtils {
+
+       /**
+        * Returns the path to the current slc:result node
+        */
+       public static String getSlcResultsBasePath(Session session) {
+               try {
+                       Node userHome = NodeUtils.getUserHome(session);
+                       if (userHome == null)
+                               throw new SlcException("No user home available for "
+                                               + session.getUserID());
+                       return userHome.getPath() + '/' + SlcNames.SLC_SYSTEM + '/'
+                                       + SlcNames.SLC_RESULTS;
+               } catch (RepositoryException re) {
+                       throw new SlcException(
+                                       "Unexpected error while getting Slc Results Base Path.", re);
+               }
+       }
+
+       /**
+        * Returns the base node to store SlcResults. If it does not exists, it is
+        * created. If a node already exists at the given path with the wrong type,
+        * it throws an exception.
+        * 
+        * @param session
+        * @return
+        */
+       public static Node getSlcResultsParentNode(Session session) {
+               try {
+                       String absPath = getSlcResultsBasePath(session);
+                       if (session.nodeExists(absPath)) {
+                               Node currNode = session.getNode(absPath);
+                               if (currNode.isNodeType(NodeType.NT_UNSTRUCTURED))
+                                       return currNode;
+                               else
+                                       throw new SlcException(
+                                                       "A node already exists at this path : " + absPath
+                                                                       + " that has the wrong type. ");
+                       } else {
+                               Node slcResParNode = JcrUtils.mkdirs(session, absPath);
+                               slcResParNode.setPrimaryType(NodeType.NT_UNSTRUCTURED);
+                               session.save();
+                               return slcResParNode;
+                       }
+               } catch (RepositoryException re) {
+                       throw new SlcException(
+                                       "Unexpected error while creating slcResult root parent node.",
+                                       re);
+               }
+       }
+
+       /**
+        * Returns the path to the current Result UI specific node, depending the
+        * current user
+        */
+       public static String getMyResultsBasePath(Session session) {
+               try {
+                       Node userHome = NodeUtils.getUserHome(session);
+                       if (userHome == null)
+                               throw new SlcException("No user home available for "
+                                               + session.getUserID());
+                       return userHome.getPath() + '/' + SlcNames.SLC_SYSTEM + '/'
+                                       + SlcNames.SLC_MY_RESULTS;
+               } catch (RepositoryException re) {
+                       throw new SlcException(
+                                       "Unexpected error while getting Slc Results Base Path.", re);
+               }
+       }
+
+       /**
+        * Creates a new node with type SlcTypes.SLC_MY_RESULT_ROOT_FOLDER at the
+        * given absolute path. If a node already exists at the given path, returns
+        * that node if it has the correct type and throws an exception otherwise.
+        * 
+        * @param session
+        * @return
+        */
+       public static Node getMyResultParentNode(Session session) {
+               try {
+                       String absPath = getMyResultsBasePath(session);
+                       if (session.nodeExists(absPath)) {
+                               Node currNode = session.getNode(absPath);
+                               if (currNode.isNodeType(SlcTypes.SLC_MY_RESULT_ROOT_FOLDER))
+                                       return currNode;
+                               else
+                                       throw new SlcException(
+                                                       "A node already exists at this path : " + absPath
+                                                                       + " that has the wrong type. ");
+                       } else {
+                               Node myResParNode = JcrUtils.mkdirs(session, absPath);
+                               myResParNode.setPrimaryType(SlcTypes.SLC_MY_RESULT_ROOT_FOLDER);
+                               session.save();
+                               return myResParNode;
+                       }
+               } catch (RepositoryException re) {
+                       throw new SlcException(
+                                       "Unexpected error while creating user MyResult base node.",
+                                       re);
+               }
+       }
+
+       /**
+        * Creates a new node with type SlcTypes.SLC_RESULT_FOLDER at the given
+        * absolute path. If a node already exists at the given path, returns that
+        * node if it has the correct type and throws an exception otherwise.
+        * 
+        * @param session
+        * @param absPath
+        * @return
+        */
+       public static synchronized Node createResultFolderNode(Session session,
+                       String absPath) {
+               try {
+                       if (session.nodeExists(absPath)) {
+                               // Sanity check
+                               Node currNode = session.getNode(absPath);
+                               if (currNode.isNodeType(SlcTypes.SLC_RESULT_FOLDER))
+                                       return currNode;
+                               else
+                                       throw new SlcException(
+                                                       "A node already exists at this path : " + absPath
+                                                                       + " that has the wrong type. ");
+                       }
+                       Node rfNode = JcrUtils.mkdirs(session, absPath);
+                       rfNode.setPrimaryType(SlcTypes.SLC_RESULT_FOLDER);
+                       Node statusNode = rfNode.addNode(SlcNames.SLC_AGGREGATED_STATUS,
+                                       SlcTypes.SLC_CHECK);
+                       statusNode.setProperty(SlcNames.SLC_SUCCESS, true);
+                       session.save();
+                       return rfNode;
+               } catch (RepositoryException re) {
+                       throw new SlcException(
+                                       "Unexpected error while creating Result Folder node.", re);
+               }
+       }
+}
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/jcr/SlcJcrUtils.java b/org.argeo.slc.spring/src/org/argeo/slc/jcr/SlcJcrUtils.java
new file mode 100644 (file)
index 0000000..137e298
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.jcr;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.node.NodeUtils;
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.SlcNames;
+import org.argeo.slc.SlcTypes;
+import org.argeo.slc.core.execution.PrimitiveAccessor;
+import org.argeo.slc.core.execution.PrimitiveUtils;
+import org.argeo.slc.deploy.ModuleDescriptor;
+import org.argeo.slc.test.TestStatus;
+
+/**
+ * Utilities around the SLC JCR model. Note that it relies on fixed base paths
+ * (convention over configuration) for optimization purposes.
+ */
+public class SlcJcrUtils implements SlcNames {
+       public final static Integer AGENT_FACTORY_DEPTH = 3;
+
+       /** Extracts the path of a flow relative to its execution module */
+       public static String flowRelativePath(String fullFlowPath) {
+               String[] tokens = fullFlowPath.split("/");
+               StringBuffer buf = new StringBuffer(fullFlowPath.length());
+               for (int i = AGENT_FACTORY_DEPTH + 3; i < tokens.length; i++) {
+                       buf.append('/').append(tokens[i]);
+               }
+               return buf.toString();
+       }
+
+       /** Extracts the path to the related execution module */
+       public static String modulePath(String fullFlowPath) {
+               String[] tokens = fullFlowPath.split("/");
+               StringBuffer buf = new StringBuffer(fullFlowPath.length());
+               for (int i = 0; i < AGENT_FACTORY_DEPTH + 3; i++) {
+                       if (!tokens[i].equals(""))
+                               buf.append('/').append(tokens[i]);
+               }
+               return buf.toString();
+       }
+
+       /** Extracts the module name from a flow path */
+       public static String moduleName(String fullFlowPath) {
+               String[] tokens = fullFlowPath.split("/");
+               String moduleName = tokens[AGENT_FACTORY_DEPTH + 2];
+               moduleName = moduleName.substring(0, moduleName.indexOf('_'));
+               return moduleName;
+       }
+
+       /** Extracts the module name and version from a flow path */
+       public static NameVersion moduleNameVersion(String fullFlowPath) {
+               String[] tokens = fullFlowPath.split("/");
+               String module = tokens[AGENT_FACTORY_DEPTH + 2];
+               String moduleName = module.substring(0, module.indexOf('_'));
+               String moduleVersion = module.substring(module.indexOf('_') + 1);
+               return new DefaultNameVersion(moduleName, moduleVersion);
+       }
+
+       /** Module node name based on module name and version */
+       public static String getModuleNodeName(ModuleDescriptor moduleDescriptor) {
+               return moduleDescriptor.getName() + "_" + moduleDescriptor.getVersion();
+       }
+
+       /** Extracts the agent factory of a flow */
+       public static String flowAgentFactoryPath(String fullFlowPath) {
+               String[] tokens = fullFlowPath.split("/");
+               StringBuffer buf = new StringBuffer(fullFlowPath.length());
+               // first token is always empty
+               for (int i = 1; i < AGENT_FACTORY_DEPTH + 1; i++) {
+                       buf.append('/').append(tokens[i]);
+               }
+               return buf.toString();
+       }
+
+       /** Create a new execution process path based on the current time */
+       public static String createExecutionProcessPath(Session session, String uuid) {
+               Calendar now = new GregorianCalendar();
+               return getSlcProcessesBasePath(session) + '/'
+                               + JcrUtils.dateAsPath(now, true) + uuid;
+       }
+
+       /** Get the base for the user processi. */
+       public static String getSlcProcessesBasePath(Session session) {
+               try {
+                       Node userHome = NodeUtils.getUserHome(session);
+                       if (userHome == null)
+                               throw new SlcException("No user home available for "
+                                               + session.getUserID());
+                       return userHome.getPath() + '/' + SlcNames.SLC_SYSTEM + '/'
+                                       + SlcNames.SLC_PROCESSES;
+               } catch (RepositoryException re) {
+                       throw new SlcException(
+                                       "Unexpected error while getting Slc Results Base Path.", re);
+               }
+       }
+
+       /**
+        * Create a new execution result path in the user home based on the current
+        * time
+        */
+       public static String createResultPath(Session session, String uuid)
+                       throws RepositoryException {
+               Calendar now = new GregorianCalendar();
+               StringBuffer absPath = new StringBuffer(
+                               SlcJcrResultUtils.getSlcResultsBasePath(session) + '/');
+               // Remove hours and add title property to the result process path on
+               // request of O. Capillon
+               // return getSlcProcessesBasePath(session) + '/'
+               // + JcrUtils.dateAsPath(now, true) + uuid;
+               String relPath = JcrUtils.dateAsPath(now, false);
+               List<String> names = JcrUtils.tokenize(relPath);
+               for (String name : names) {
+                       absPath.append(name + "/");
+                       Node node = JcrUtils.mkdirs(session, absPath.toString());
+                       try {
+                               node.addMixin(NodeType.MIX_TITLE);
+                               node.setProperty(Property.JCR_TITLE, name.substring(1));
+                       } catch (RepositoryException e) {
+                               throw new SlcException(
+                                               "unable to create execution process path", e);
+                       }
+               }
+               return absPath.toString() + uuid;
+       }
+
+       /**
+        * Set the value of the primitive accessor as a JCR property. Does nothing
+        * if the value is null.
+        */
+       public static void setPrimitiveAsProperty(Node node, String propertyName,
+                       PrimitiveAccessor primitiveAccessor) {
+               String type = primitiveAccessor.getType();
+               Object value = primitiveAccessor.getValue();
+               setPrimitiveAsProperty(node, propertyName, type, value);
+       }
+
+       /** Map a primitive value to JCR property value. */
+       public static void setPrimitiveAsProperty(Node node, String propertyName,
+                       String type, Object value) {
+               if (value == null)
+                       return;
+               if (value instanceof CharSequence)
+                       value = PrimitiveUtils.convert(type,
+                                       ((CharSequence) value).toString());
+               if (value instanceof char[])
+                       value = new String((char[]) value);
+
+               try {
+                       if (type.equals(PrimitiveAccessor.TYPE_STRING))
+                               node.setProperty(propertyName, value.toString());
+                       else if (type.equals(PrimitiveAccessor.TYPE_PASSWORD))
+                               node.setProperty(propertyName, value.toString());
+                       else if (type.equals(PrimitiveAccessor.TYPE_INTEGER))
+                               node.setProperty(propertyName, (long) ((Integer) value));
+                       else if (type.equals(PrimitiveAccessor.TYPE_LONG))
+                               node.setProperty(propertyName, ((Long) value));
+                       else if (type.equals(PrimitiveAccessor.TYPE_FLOAT))
+                               node.setProperty(propertyName, (double) ((Float) value));
+                       else if (type.equals(PrimitiveAccessor.TYPE_DOUBLE))
+                               node.setProperty(propertyName, ((Double) value));
+                       else if (type.equals(PrimitiveAccessor.TYPE_BOOLEAN))
+                               node.setProperty(propertyName, ((Boolean) value));
+                       else
+                               throw new SlcException("Unsupported type " + type);
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot set primitive of " + type
+                                       + " as property " + propertyName + " on " + node, e);
+               }
+       }
+
+       /** Aggregates the {@link TestStatus} of this sub-tree. */
+       public static Integer aggregateTestStatus(Node node) {
+               try {
+                       Integer status = TestStatus.PASSED;
+                       if (node.isNodeType(SlcTypes.SLC_CHECK))
+                               if (node.getProperty(SLC_SUCCESS).getBoolean())
+                                       status = TestStatus.PASSED;
+                               else if (node.hasProperty(SLC_ERROR_MESSAGE))
+                                       status = TestStatus.ERROR;
+                               else
+                                       status = TestStatus.FAILED;
+
+                       NodeIterator it = node.getNodes();
+                       while (it.hasNext()) {
+                               Node curr = it.nextNode();
+
+                               // Manually skip aggregated status
+                               if (!SlcNames.SLC_AGGREGATED_STATUS.equals(curr.getName())) {
+                                       Integer childStatus = aggregateTestStatus(curr);
+                                       if (childStatus > status)
+                                               status = childStatus;
+                               }
+                       }
+                       return status;
+               } catch (Exception e) {
+                       throw new SlcException("Could not aggregate test status from "
+                                       + node, e);
+               }
+       }
+
+       /**
+        * Aggregates the {@link TestStatus} of this sub-tree.
+        * 
+        * @return the same {@link StringBuffer}, for convenience (typically calling
+        *         toString() on it)
+        */
+       public static StringBuffer aggregateTestMessages(Node node,
+                       StringBuffer messages) {
+               try {
+                       if (node.isNodeType(SlcTypes.SLC_CHECK)) {
+                               if (node.hasProperty(SLC_MESSAGE)) {
+                                       if (messages.length() > 0)
+                                               messages.append('\n');
+                                       messages.append(node.getProperty(SLC_MESSAGE).getString());
+                               }
+                               if (node.hasProperty(SLC_ERROR_MESSAGE)) {
+                                       if (messages.length() > 0)
+                                               messages.append('\n');
+                                       messages.append(node.getProperty(SLC_ERROR_MESSAGE)
+                                                       .getString());
+                               }
+                       }
+                       NodeIterator it = node.getNodes();
+                       while (it.hasNext()) {
+                               Node child = it.nextNode();
+                               // Manually skip aggregated status
+                               if (!SlcNames.SLC_AGGREGATED_STATUS.equals(child.getName())) {
+                                       aggregateTestMessages(child, messages);
+                               }
+                       }
+                       return messages;
+               } catch (Exception e) {
+                       throw new SlcException("Could not aggregate test messages from "
+                                       + node, e);
+               }
+       }
+
+       /** Prevents instantiation */
+       private SlcJcrUtils() {
+       }
+}
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrAgent.java b/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrAgent.java
new file mode 100644 (file)
index 0000000..89b4530
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.jcr.execution;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.UUID;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.security.Privilege;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcConstants;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.SlcNames;
+import org.argeo.slc.SlcTypes;
+import org.argeo.slc.core.execution.DefaultAgent;
+import org.argeo.slc.core.execution.ProcessThread;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.jcr.SlcJcrConstants;
+
+/** SLC VM agent synchronizing with a JCR repository. */
+public class JcrAgent extends DefaultAgent implements SlcNames {
+       // final static String ROLE_REMOTE = "ROLE_REMOTE";
+       final static String NODE_REPO_URI = "argeo.node.repo.uri";
+
+       private Repository repository;
+
+       private String agentNodeName = "default";
+
+       /*
+        * LIFECYCLE
+        */
+       protected String initAgentUuid() {
+               Session session = null;
+               try {
+                       session = repository.login();
+
+                       String agentFactoryPath = getAgentFactoryPath();
+                       Node vmAgentFactoryNode = JcrUtils.mkdirsSafe(session, agentFactoryPath, SlcTypes.SLC_AGENT_FACTORY);
+                       JcrUtils.addPrivilege(session, SlcJcrConstants.SLC_BASE_PATH, SlcConstants.ROLE_SLC, Privilege.JCR_ALL);
+                       if (!vmAgentFactoryNode.hasNode(agentNodeName)) {
+                               String uuid = UUID.randomUUID().toString();
+                               Node agentNode = vmAgentFactoryNode.addNode(agentNodeName, SlcTypes.SLC_AGENT);
+                               agentNode.setProperty(SLC_UUID, uuid);
+                       }
+                       session.save();
+                       return vmAgentFactoryNode.getNode(agentNodeName).getProperty(SLC_UUID).getString();
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(session);
+                       throw new SlcException("Cannot find JCR agent UUID", e);
+               } finally {
+                       JcrUtils.logoutQuietly(session);
+               }
+       }
+
+       @Override
+       public void destroy() {
+               super.destroy();
+       }
+
+       /*
+        * SLC AGENT
+        */
+       @Override
+       protected ProcessThread createProcessThread(ThreadGroup processesThreadGroup,
+                       ExecutionModulesManager modulesManager, ExecutionProcess process) {
+               if (process instanceof JcrExecutionProcess)
+                       return new JcrProcessThread(processesThreadGroup, modulesManager, (JcrExecutionProcess) process);
+               else
+                       return super.createProcessThread(processesThreadGroup, modulesManager, process);
+       }
+
+       /*
+        * UTILITIES
+        */
+       public String getNodePath() {
+               return getAgentFactoryPath() + '/' + getAgentNodeName();
+       }
+
+       public String getAgentFactoryPath() {
+               try {
+                       Boolean isRemote = System.getProperty(NODE_REPO_URI) != null;
+                       String agentFactoryPath;
+                       if (isRemote) {
+                               InetAddress localhost = InetAddress.getLocalHost();
+                               agentFactoryPath = SlcJcrConstants.AGENTS_BASE_PATH + "/" + localhost.getCanonicalHostName();
+
+                               if (agentFactoryPath.equals(SlcJcrConstants.VM_AGENT_FACTORY_PATH))
+                                       throw new SlcException("Unsupported hostname " + localhost.getCanonicalHostName());
+                       } else {// local
+                               agentFactoryPath = SlcJcrConstants.VM_AGENT_FACTORY_PATH;
+                       }
+                       return agentFactoryPath;
+               } catch (UnknownHostException e) {
+                       throw new SlcException("Cannot find agent factory base path", e);
+               }
+       }
+
+       /*
+        * BEAN
+        */
+       public String getAgentNodeName() {
+               return agentNodeName;
+       }
+
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+
+       public void setAgentNodeName(String agentNodeName) {
+               this.agentNodeName = agentNodeName;
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrAttachmentUploader.java b/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrAttachmentUploader.java
new file mode 100644 (file)
index 0000000..105d549
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.jcr.execution;
+
+import javax.jcr.Session;
+
+import org.argeo.slc.core.attachment.Attachment;
+import org.argeo.slc.core.attachment.AttachmentUploader;
+import org.springframework.core.io.Resource;
+
+/** JCR based attachment uploader */
+public class JcrAttachmentUploader implements AttachmentUploader {
+       private Session session;
+
+       public void upload(Attachment attachment, Resource resource) {
+               session.toString();
+               // not yet implemented, need to review the interface
+       }
+
+       public void setSession(Session session) {
+               this.session = session;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java b/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java
new file mode 100644 (file)
index 0000000..1a2576e
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.jcr.execution;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.SlcNames;
+import org.argeo.slc.SlcTypes;
+import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
+import org.argeo.slc.core.execution.PrimitiveValue;
+import org.argeo.slc.core.execution.RefSpecAttribute;
+import org.argeo.slc.core.execution.RefValueChoice;
+import org.argeo.slc.deploy.ModuleDescriptor;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
+import org.argeo.slc.execution.ExecutionModulesListener;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.argeo.slc.jcr.SlcJcrUtils;
+
+/**
+ * Synchronizes the local execution runtime with a JCR repository. For the time
+ * being the state is completely reset from one start to another.
+ */
+public class JcrExecutionModulesListener implements ExecutionModulesListener,
+               SlcNames {
+       private final static String SLC_EXECUTION_MODULES_PROPERTY = "slc.executionModules";
+
+       private final static Log log = LogFactory
+                       .getLog(JcrExecutionModulesListener.class);
+       private JcrAgent agent;
+
+       private ExecutionModulesManager modulesManager;
+
+       private Repository repository;
+       /**
+        * We don't use a thread bound session because many different threads will
+        * call this critical component and we don't want to login each time. We
+        * therefore rather protect access to this session via synchronized.
+        */
+       private Session session;
+
+       /*
+        * LIFECYCLE
+        */
+       public void init() {
+               try {
+                       session = repository.login();
+                       clearAgent();
+                       if (modulesManager != null) {
+                               Node agentNode = session.getNode(agent.getNodePath());
+
+                               List<ModuleDescriptor> moduleDescriptors = modulesManager
+                                               .listModules();
+
+                               // scan SLC-ExecutionModule metadata
+                               for (ModuleDescriptor md : moduleDescriptors) {
+                                       if (md.getMetadata().containsKey(
+                                                       ExecutionModuleDescriptor.SLC_EXECUTION_MODULE)) {
+                                               String moduleNodeName = SlcJcrUtils
+                                                               .getModuleNodeName(md);
+                                               Node moduleNode = agentNode.hasNode(moduleNodeName) ? agentNode
+                                                               .getNode(moduleNodeName) : agentNode
+                                                               .addNode(moduleNodeName);
+                                               moduleNode.addMixin(SlcTypes.SLC_EXECUTION_MODULE);
+                                               moduleNode.setProperty(SLC_NAME, md.getName());
+                                               moduleNode.setProperty(SLC_VERSION, md.getVersion());
+                                               moduleNode.setProperty(Property.JCR_TITLE,
+                                                               md.getTitle());
+                                               moduleNode.setProperty(Property.JCR_DESCRIPTION,
+                                                               md.getDescription());
+                                               moduleNode.setProperty(SLC_STARTED, md.getStarted());
+                                       }
+                               }
+
+                               // scan execution modules property
+                               String executionModules = System
+                                               .getProperty(SLC_EXECUTION_MODULES_PROPERTY);
+                               if (executionModules != null) {
+                                       for (String executionModule : executionModules.split(",")) {
+                                               allModules: for (ModuleDescriptor md : moduleDescriptors) {
+                                                       String moduleNodeName = SlcJcrUtils
+                                                                       .getModuleNodeName(md);
+                                                       if (md.getName().equals(executionModule)) {
+                                                               Node moduleNode = agentNode
+                                                                               .hasNode(moduleNodeName) ? agentNode
+                                                                               .getNode(moduleNodeName) : agentNode
+                                                                               .addNode(moduleNodeName);
+                                                               moduleNode
+                                                                               .addMixin(SlcTypes.SLC_EXECUTION_MODULE);
+                                                               moduleNode.setProperty(SLC_NAME, md.getName());
+                                                               moduleNode.setProperty(SLC_VERSION,
+                                                                               md.getVersion());
+                                                               moduleNode.setProperty(Property.JCR_TITLE,
+                                                                               md.getTitle());
+                                                               moduleNode.setProperty(
+                                                                               Property.JCR_DESCRIPTION,
+                                                                               md.getDescription());
+                                                               moduleNode.setProperty(SLC_STARTED,
+                                                                               md.getStarted());
+                                                               break allModules;
+                                                       }
+                                               }
+                                       }
+
+                                       // save if needed
+                                       if (session.hasPendingChanges())
+                                               session.save();
+                               }
+                       }
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(session);
+                       JcrUtils.logoutQuietly(session);
+                       throw new SlcException("Cannot initialize modules", e);
+               }
+       }
+
+       public void destroy() {
+               clearAgent();
+               JcrUtils.logoutQuietly(session);
+       }
+
+       protected synchronized void clearAgent() {
+               try {
+                       Node agentNode = session.getNode(agent.getNodePath());
+                       for (NodeIterator nit = agentNode.getNodes(); nit.hasNext();)
+                               nit.nextNode().remove();
+                       session.save();
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(session);
+                       throw new SlcException("Cannot clear agent " + agent, e);
+               }
+       }
+
+       /*
+        * EXECUTION MODULES LISTENER
+        */
+
+       public synchronized void executionModuleAdded(
+                       ModuleDescriptor moduleDescriptor) {
+               syncExecutionModule(moduleDescriptor);
+       }
+
+       protected void syncExecutionModule(ModuleDescriptor moduleDescriptor) {
+               try {
+                       Node agentNode = session.getNode(agent.getNodePath());
+                       String moduleNodeName = SlcJcrUtils
+                                       .getModuleNodeName(moduleDescriptor);
+                       Node moduleNode = agentNode.hasNode(moduleNodeName) ? agentNode
+                                       .getNode(moduleNodeName) : agentNode
+                                       .addNode(moduleNodeName);
+                       moduleNode.addMixin(SlcTypes.SLC_EXECUTION_MODULE);
+                       moduleNode.setProperty(SLC_NAME, moduleDescriptor.getName());
+                       moduleNode.setProperty(SLC_VERSION, moduleDescriptor.getVersion());
+                       moduleNode.setProperty(Property.JCR_TITLE,
+                                       moduleDescriptor.getTitle());
+                       moduleNode.setProperty(Property.JCR_DESCRIPTION,
+                                       moduleDescriptor.getDescription());
+                       moduleNode.setProperty(SLC_STARTED, moduleDescriptor.getStarted());
+                       session.save();
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(session);
+                       throw new SlcException("Cannot sync module " + moduleDescriptor, e);
+               }
+       }
+
+       public synchronized void executionModuleRemoved(
+                       ModuleDescriptor moduleDescriptor) {
+               try {
+                       String moduleName = SlcJcrUtils.getModuleNodeName(moduleDescriptor);
+                       Node agentNode = session.getNode(agent.getNodePath());
+                       if (agentNode.hasNode(moduleName)) {
+                               Node moduleNode = agentNode.getNode(moduleName);
+                               for (NodeIterator nit = moduleNode.getNodes(); nit.hasNext();) {
+                                       nit.nextNode().remove();
+                               }
+                               moduleNode.setProperty(SLC_STARTED, false);
+                       }
+                       session.save();
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(session);
+                       throw new SlcException("Cannot remove module " + moduleDescriptor,
+                                       e);
+               }
+       }
+
+       public synchronized void executionFlowAdded(ModuleDescriptor module,
+                       ExecutionFlowDescriptor efd) {
+               try {
+                       Node agentNode = session.getNode(agent.getNodePath());
+                       Node moduleNode = agentNode.getNode(SlcJcrUtils
+                                       .getModuleNodeName(module));
+                       String relativePath = getExecutionFlowRelativePath(efd);
+                       @SuppressWarnings("unused")
+                       Node flowNode = null;
+                       if (!moduleNode.hasNode(relativePath)) {
+                               flowNode = createExecutionFlowNode(moduleNode, relativePath,
+                                               efd);
+                               session.save();
+                       } else {
+                               flowNode = moduleNode.getNode(relativePath);
+                       }
+
+                       if (log.isTraceEnabled())
+                               log.trace("Flow " + efd + " added to JCR");
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(session);
+                       throw new SlcException("Cannot add flow " + efd + " from module "
+                                       + module, e);
+               }
+
+       }
+
+       protected Node createExecutionFlowNode(Node moduleNode,
+                       String relativePath, ExecutionFlowDescriptor efd)
+                       throws RepositoryException {
+               Node flowNode = null;
+               List<String> pathTokens = Arrays.asList(relativePath.split("/"));
+
+               Iterator<String> names = pathTokens.iterator();
+               // create intermediary paths
+               Node currNode = moduleNode;
+               while (names.hasNext()) {
+                       String name = names.next();
+                       if (currNode.hasNode(name))
+                               currNode = currNode.getNode(name);
+                       else {
+                               if (names.hasNext())
+                                       currNode = currNode.addNode(name);
+                               else
+                                       flowNode = currNode.addNode(name,
+                                                       SlcTypes.SLC_EXECUTION_FLOW);
+                       }
+               }
+
+               // name, description
+               flowNode.setProperty(SLC_NAME, efd.getName());
+               String endName = pathTokens.get(pathTokens.size() - 1);
+               flowNode.setProperty(Property.JCR_TITLE, endName);
+               if (efd.getDescription() != null
+                               && !efd.getDescription().trim().equals("")) {
+                       flowNode.setProperty(Property.JCR_DESCRIPTION, efd.getDescription());
+               } else {
+                       flowNode.setProperty(Property.JCR_DESCRIPTION, endName);
+               }
+
+               // execution spec
+               ExecutionSpec executionSpec = efd.getExecutionSpec();
+               String esName = executionSpec.getName();
+               if (esName == null || esName.equals(ExecutionSpec.INTERNAL_NAME)
+                               || esName.contains("#")/* automatically generated bean name */) {
+                       // internal spec node
+                       mapExecutionSpec(flowNode, executionSpec);
+               } else {
+                       // reference spec node
+                       Node executionSpecsNode = moduleNode.hasNode(SLC_EXECUTION_SPECS) ? moduleNode
+                                       .getNode(SLC_EXECUTION_SPECS) : moduleNode
+                                       .addNode(SLC_EXECUTION_SPECS);
+                       Node executionSpecNode = executionSpecsNode.addNode(esName,
+                                       SlcTypes.SLC_EXECUTION_SPEC);
+                       executionSpecNode.setProperty(SLC_NAME, esName);
+                       executionSpecNode.setProperty(Property.JCR_TITLE, esName);
+                       if (executionSpec.getDescription() != null
+                                       && !executionSpec.getDescription().trim().equals(""))
+                               executionSpecNode.setProperty(Property.JCR_DESCRIPTION,
+                                               executionSpec.getDescription());
+                       mapExecutionSpec(executionSpecNode, executionSpec);
+                       flowNode.setProperty(SLC_SPEC, executionSpecNode);
+               }
+
+               // flow values
+               for (String attr : efd.getValues().keySet()) {
+                       ExecutionSpecAttribute esa = executionSpec.getAttributes()
+                                       .get(attr);
+                       if (esa instanceof PrimitiveSpecAttribute) {
+                               PrimitiveSpecAttribute psa = (PrimitiveSpecAttribute) esa;
+                               // if spec reference there will be no node at this stage
+                               Node valueNode = JcrUtils.getOrAdd(flowNode, attr);
+                               valueNode.setProperty(SLC_TYPE, psa.getType());
+                               SlcJcrUtils.setPrimitiveAsProperty(valueNode, SLC_VALUE,
+                                               (PrimitiveValue) efd.getValues().get(attr));
+                       }
+               }
+
+               return flowNode;
+       }
+
+       /**
+        * Base can be either an execution spec node, or an execution flow node (in
+        * case the execution spec is internal)
+        */
+       protected void mapExecutionSpec(Node baseNode, ExecutionSpec executionSpec)
+                       throws RepositoryException {
+               for (String attrName : executionSpec.getAttributes().keySet()) {
+                       ExecutionSpecAttribute esa = executionSpec.getAttributes().get(
+                                       attrName);
+                       Node attrNode = baseNode.addNode(attrName);
+                       // booleans
+                       attrNode.addMixin(SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE);
+                       attrNode.setProperty(SLC_IS_IMMUTABLE, esa.getIsImmutable());
+                       attrNode.setProperty(SLC_IS_CONSTANT, esa.getIsConstant());
+                       attrNode.setProperty(SLC_IS_HIDDEN, esa.getIsHidden());
+
+                       if (esa instanceof PrimitiveSpecAttribute) {
+                               attrNode.addMixin(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE);
+                               PrimitiveSpecAttribute psa = (PrimitiveSpecAttribute) esa;
+                               SlcJcrUtils.setPrimitiveAsProperty(attrNode, SLC_VALUE, psa);
+                               attrNode.setProperty(SLC_TYPE, psa.getType());
+                       } else if (esa instanceof RefSpecAttribute) {
+                               attrNode.addMixin(SlcTypes.SLC_REF_SPEC_ATTRIBUTE);
+                               RefSpecAttribute rsa = (RefSpecAttribute) esa;
+                               attrNode.setProperty(SLC_TYPE, rsa.getTargetClassName());
+                               Object value = rsa.getValue();
+                               if (rsa.getChoices() != null) {
+                                       Integer index = null;
+                                       int count = 0;
+                                       for (RefValueChoice choice : rsa.getChoices()) {
+                                               String name = choice.getName();
+                                               if (value != null && name.equals(value.toString()))
+                                                       index = count;
+                                               Node choiceNode = attrNode.addNode(choice.getName());
+                                               choiceNode.addMixin(NodeType.MIX_TITLE);
+                                               choiceNode.setProperty(Property.JCR_TITLE,
+                                                               choice.getName());
+                                               if (choice.getDescription() != null
+                                                               && !choice.getDescription().trim().equals(""))
+                                                       choiceNode.setProperty(Property.JCR_DESCRIPTION,
+                                                                       choice.getDescription());
+                                               count++;
+                                       }
+
+                                       if (index != null)
+                                               attrNode.setProperty(SLC_VALUE, index);
+                               }
+                       }
+               }
+       }
+
+       public synchronized void executionFlowRemoved(ModuleDescriptor module,
+                       ExecutionFlowDescriptor executionFlow) {
+               try {
+                       Node agentNode = session.getNode(agent.getNodePath());
+                       Node moduleNode = agentNode.getNode(SlcJcrUtils
+                                       .getModuleNodeName(module));
+                       String relativePath = getExecutionFlowRelativePath(executionFlow);
+                       if (moduleNode.hasNode(relativePath))
+                               moduleNode.getNode(relativePath).remove();
+                       agentNode.getSession().save();
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot remove flow " + executionFlow
+                                       + " from module " + module, e);
+               }
+       }
+
+       /*
+        * UTILITIES
+        */
+       /** @return the relative path, never starts with '/' */
+       @SuppressWarnings("deprecation")
+       protected String getExecutionFlowRelativePath(
+                       ExecutionFlowDescriptor executionFlow) {
+               String relativePath = executionFlow.getPath() == null ? executionFlow
+                               .getName() : executionFlow.getPath() + '/'
+                               + executionFlow.getName();
+               // we assume that it is more than one char long
+               if (relativePath.charAt(0) == '/')
+                       relativePath = relativePath.substring(1);
+               // FIXME quick hack to avoid duplicate '/'
+               relativePath = relativePath.replaceAll("//", "/");
+               return relativePath;
+       }
+
+       /*
+        * BEAN
+        */
+       public void setAgent(JcrAgent agent) {
+               this.agent = agent;
+       }
+
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+
+       public void setModulesManager(ExecutionModulesManager modulesManager) {
+               this.modulesManager = modulesManager;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrExecutionProcess.java b/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrExecutionProcess.java
new file mode 100644 (file)
index 0000000..e1ad69e
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.jcr.execution;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.SlcNames;
+import org.argeo.slc.SlcTypes;
+import org.argeo.slc.core.execution.ProcessThread;
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.ExecutionStep;
+import org.argeo.slc.execution.RealizedFlow;
+import org.argeo.slc.jcr.SlcJcrUtils;
+
+/** Execution process implementation based on a JCR node. */
+public class JcrExecutionProcess implements ExecutionProcess, SlcNames {
+       private final static Log log = LogFactory.getLog(JcrExecutionProcess.class);
+       private final Node node;
+
+       private Long nextLogLine = 1l;
+
+       public JcrExecutionProcess(Node node) {
+               this.node = node;
+       }
+
+       public synchronized String getUuid() {
+               try {
+                       return node.getProperty(SLC_UUID).getString();
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot get uuid for " + node, e);
+               }
+       }
+
+       public synchronized String getStatus() {
+               try {
+                       return node.getProperty(SLC_STATUS).getString();
+               } catch (RepositoryException e) {
+                       log.error("Cannot get status: " + e);
+                       // we should re-throw exception because this information can
+                       // probably used for monitoring in case there are already unexpected
+                       // exceptions
+                       return UNKOWN;
+               }
+       }
+
+       public synchronized void setStatus(String status) {
+               try {
+                       node.setProperty(SLC_STATUS, status);
+                       // last modified properties needs to be manually updated
+                       // see https://issues.apache.org/jira/browse/JCR-2233
+                       JcrUtils.updateLastModified(node);
+                       node.getSession().save();
+               } catch (RepositoryException e) {
+                       JcrUtils.discardUnderlyingSessionQuietly(node);
+                       // we should re-throw exception because this information can
+                       // probably used for monitoring in case there are already unexpected
+                       // exceptions
+                       log.error("Cannot set status " + status + ": " + e);
+               }
+       }
+
+       /**
+        * Synchronized in order to make sure that there is no concurrent
+        * modification of {@link #nextLogLine}.
+        */
+       public synchronized void addSteps(List<ExecutionStep> steps) {
+               try {
+                       steps: for (ExecutionStep step : steps) {
+                               String type;
+                               if (step.getType().equals(ExecutionStep.TRACE))
+                                       type = SlcTypes.SLC_LOG_TRACE;
+                               else if (step.getType().equals(ExecutionStep.DEBUG))
+                                       type = SlcTypes.SLC_LOG_DEBUG;
+                               else if (step.getType().equals(ExecutionStep.INFO))
+                                       type = SlcTypes.SLC_LOG_INFO;
+                               else if (step.getType().equals(ExecutionStep.WARNING))
+                                       type = SlcTypes.SLC_LOG_WARNING;
+                               else if (step.getType().equals(ExecutionStep.ERROR))
+                                       type = SlcTypes.SLC_LOG_ERROR;
+                               else
+                                       // skip
+                                       continue steps;
+
+                               String relPath = SLC_LOG + '/'
+                                               + step.getThread().replace('/', '_') + '/'
+                                               + step.getLocation().replace('.', '/');
+                               String path = node.getPath() + '/' + relPath;
+                               // clean special character
+                               // TODO factorize in JcrUtils
+                               path = path.replace('@', '_');
+
+                               Node location = JcrUtils.mkdirs(node.getSession(), path);
+                               Node logEntry = location.addNode(Long.toString(nextLogLine),
+                                               type);
+                               logEntry.setProperty(SLC_MESSAGE, step.getLog());
+                               Calendar calendar = new GregorianCalendar();
+                               calendar.setTime(step.getTimestamp());
+                               logEntry.setProperty(SLC_TIMESTAMP, calendar);
+
+                               // System.out.println("Logged " + logEntry.getPath());
+
+                               nextLogLine++;
+                       }
+
+                       // last modified properties needs to be manually updated
+                       // see https://issues.apache.org/jira/browse/JCR-2233
+                       JcrUtils.updateLastModified(node);
+
+                       node.getSession().save();
+               } catch (Exception e) {
+                       JcrUtils.discardUnderlyingSessionQuietly(node);
+                       e.printStackTrace();
+               }
+       }
+
+       // public Node getNode() {
+       // return node;
+       // }
+
+       public List<RealizedFlow> getRealizedFlows() {
+               try {
+                       List<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();
+                       Node rootRealizedFlowNode = node.getNode(SLC_FLOW);
+                       // we just manage one level for the time being
+                       NodeIterator nit = rootRealizedFlowNode.getNodes(SLC_FLOW);
+                       while (nit.hasNext()) {
+                               Node realizedFlowNode = nit.nextNode();
+
+                               if (realizedFlowNode.hasNode(SLC_ADDRESS)) {
+                                       String flowPath = realizedFlowNode.getNode(SLC_ADDRESS)
+                                                       .getProperty(Property.JCR_PATH).getString();
+                                       NameVersion moduleNameVersion = SlcJcrUtils
+                                                       .moduleNameVersion(flowPath);
+                                       ((ProcessThread) Thread.currentThread())
+                                                       .getExecutionModulesManager().start(
+                                                                       moduleNameVersion);
+                               }
+
+                               RealizedFlow realizedFlow = new JcrRealizedFlow(
+                                               realizedFlowNode);
+                               if (realizedFlow != null)
+                                       realizedFlows.add(realizedFlow);
+                       }
+                       return realizedFlows;
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot get realized flows", e);
+               }
+       }
+
+       public String getNodePath() {
+               try {
+                       return node.getPath();
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot get process node path for " + node,
+                                       e);
+               }
+       }
+
+       public Repository getRepository() {
+               try {
+                       return node.getSession().getRepository();
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot get process JCR repository for "
+                                       + node, e);
+               }
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrProcessThread.java b/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrProcessThread.java
new file mode 100644 (file)
index 0000000..a73e1a9
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.jcr.execution;
+
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.SlcNames;
+import org.argeo.slc.core.execution.ProcessThread;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.RealizedFlow;
+
+/** Where the actual execution takes place */
+public class JcrProcessThread extends ProcessThread implements SlcNames {
+
+       public JcrProcessThread(ThreadGroup processesThreadGroup,
+                       ExecutionModulesManager executionModulesManager,
+                       JcrExecutionProcess process) {
+               super(processesThreadGroup, executionModulesManager, process);
+       }
+
+       /** Overridden in order to set progress status on realized flow nodes. */
+       @Override
+       protected void process() throws InterruptedException {
+               Session session = null;
+               if (getProcess() instanceof JcrExecutionProcess)
+                       try {
+                               session = ((JcrExecutionProcess) getProcess()).getRepository()
+                                               .login();
+
+                               List<RealizedFlow> realizedFlows = getProcess()
+                                               .getRealizedFlows();
+                               for (RealizedFlow realizedFlow : realizedFlows) {
+                                       Node realizedFlowNode = session
+                                                       .getNode(((JcrRealizedFlow) realizedFlow).getPath());
+                                       setFlowStatus(realizedFlowNode, ExecutionProcess.RUNNING);
+
+                                       try {
+                                               //
+                                               // EXECUTE THE FLOW
+                                               //
+                                               execute(realizedFlow, true);
+
+                                               setFlowStatus(realizedFlowNode,
+                                                               ExecutionProcess.COMPLETED);
+                                       } catch (RepositoryException e) {
+                                               throw e;
+                                       } catch (InterruptedException e) {
+                                               setFlowStatus(realizedFlowNode, ExecutionProcess.KILLED);
+                                               throw e;
+                                       } catch (RuntimeException e) {
+                                               setFlowStatus(realizedFlowNode, ExecutionProcess.ERROR);
+                                               throw e;
+                                       }
+                               }
+                       } catch (RepositoryException e) {
+                               throw new SlcException("Cannot process "
+                                               + getJcrExecutionProcess().getNodePath(), e);
+                       } finally {
+                               JcrUtils.logoutQuietly(session);
+                       }
+               else
+                       super.process();
+       }
+
+       protected void setFlowStatus(Node realizedFlowNode, String status)
+                       throws RepositoryException {
+               realizedFlowNode.setProperty(SLC_STATUS, status);
+               realizedFlowNode.getSession().save();
+       }
+
+       protected JcrExecutionProcess getJcrExecutionProcess() {
+               return (JcrExecutionProcess) getProcess();
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrRealizedFlow.java b/org.argeo.slc.spring/src/org/argeo/slc/jcr/execution/JcrRealizedFlow.java
new file mode 100644 (file)
index 0000000..c371b11
--- /dev/null
@@ -0,0 +1,143 @@
+package org.argeo.slc.jcr.execution;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.SlcNames;
+import org.argeo.slc.SlcTypes;
+import org.argeo.slc.core.execution.DefaultExecutionSpec;
+import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
+import org.argeo.slc.core.execution.PrimitiveUtils;
+import org.argeo.slc.core.execution.RefSpecAttribute;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.argeo.slc.execution.RealizedFlow;
+import org.argeo.slc.jcr.SlcJcrUtils;
+
+public class JcrRealizedFlow extends RealizedFlow implements SlcNames {
+       private static final long serialVersionUID = -3709453850260712001L;
+       private String path;
+
+       public JcrRealizedFlow(Node node) {
+               try {
+                       this.path = node.getPath();
+                       loadFromNode(node);
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot initialize from " + node, e);
+               }
+       }
+
+       protected void loadFromNode(Node realizedFlowNode)
+                       throws RepositoryException {
+               if (realizedFlowNode.hasNode(SLC_ADDRESS)) {
+                       String flowPath = realizedFlowNode.getNode(SLC_ADDRESS)
+                                       .getProperty(Property.JCR_PATH).getString();
+                       // TODO: convert to local path if remote
+                       // FIXME start related module
+                       Node flowNode = realizedFlowNode.getSession().getNode(flowPath);
+                       String flowName = flowNode.getProperty(SLC_NAME).getString();
+                       String description = null;
+                       if (flowNode.hasProperty(Property.JCR_DESCRIPTION))
+                               description = flowNode.getProperty(Property.JCR_DESCRIPTION)
+                                               .getString();
+
+                       Node executionModuleNode = flowNode.getSession().getNode(
+                                       SlcJcrUtils.modulePath(flowPath));
+                       String executionModuleName = executionModuleNode.getProperty(
+                                       SLC_NAME).getString();
+                       String executionModuleVersion = executionModuleNode.getProperty(
+                                       SLC_VERSION).getString();
+
+                       RealizedFlow realizedFlow = this;
+                       realizedFlow.setModuleName(executionModuleName);
+                       realizedFlow.setModuleVersion(executionModuleVersion);
+
+                       // retrieve execution spec
+                       DefaultExecutionSpec executionSpec = new DefaultExecutionSpec();
+                       Map<String, ExecutionSpecAttribute> attrs = readExecutionSpecAttributes(realizedFlowNode);
+                       executionSpec.setAttributes(attrs);
+
+                       // set execution spec name
+                       if (flowNode.hasProperty(SlcNames.SLC_SPEC)) {
+                               Node executionSpecNode = flowNode.getProperty(SLC_SPEC)
+                                               .getNode();
+                               executionSpec.setBeanName(executionSpecNode.getProperty(
+                                               SLC_NAME).getString());
+                       }
+
+                       // explicitly retrieve values
+                       Map<String, Object> values = new HashMap<String, Object>();
+                       for (String attrName : attrs.keySet()) {
+                               ExecutionSpecAttribute attr = attrs.get(attrName);
+                               Object value = attr.getValue();
+                               values.put(attrName, value);
+                       }
+
+                       ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(flowName,
+                                       description, values, executionSpec);
+                       realizedFlow.setFlowDescriptor(efd);
+               } else {
+                       throw new SlcException("Unsupported realized flow "
+                                       + realizedFlowNode);
+               }
+       }
+
+       protected Map<String, ExecutionSpecAttribute> readExecutionSpecAttributes(
+                       Node node) {
+               try {
+                       Map<String, ExecutionSpecAttribute> attrs = new HashMap<String, ExecutionSpecAttribute>();
+                       for (NodeIterator nit = node.getNodes(); nit.hasNext();) {
+                               Node specAttrNode = nit.nextNode();
+                               if (specAttrNode
+                                               .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) {
+                                       String type = specAttrNode.getProperty(SLC_TYPE)
+                                                       .getString();
+                                       Object value = null;
+                                       if (specAttrNode.hasProperty(SLC_VALUE)) {
+                                               String valueStr = specAttrNode.getProperty(SLC_VALUE)
+                                                               .getString();
+                                               value = PrimitiveUtils.convert(type, valueStr);
+                                       }
+                                       PrimitiveSpecAttribute specAttr = new PrimitiveSpecAttribute(
+                                                       type, value);
+                                       attrs.put(specAttrNode.getName(), specAttr);
+                               } else if (specAttrNode
+                                               .isNodeType(SlcTypes.SLC_REF_SPEC_ATTRIBUTE)) {
+                                       if (!specAttrNode.hasProperty(SLC_VALUE)) {
+                                               continue;
+                                       }
+                                       Integer value = (int) specAttrNode.getProperty(SLC_VALUE)
+                                                       .getLong();
+                                       RefSpecAttribute specAttr = new RefSpecAttribute();
+                                       NodeIterator children = specAttrNode.getNodes();
+                                       int index = 0;
+                                       String id = null;
+                                       while (children.hasNext()) {
+                                               Node child = children.nextNode();
+                                               if (index == value)
+                                                       id = child.getName();
+                                               index++;
+                                       }
+                                       specAttr.setValue(id);
+                                       attrs.put(specAttrNode.getName(), specAttr);
+                               }
+                               // throw new SlcException("Unsupported spec attribute "
+                               // + specAttrNode);
+                       }
+                       return attrs;
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot read spec attributes from " + node,
+                                       e);
+               }
+       }
+
+       public String getPath() {
+               return path;
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/BundleRegister.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/BundleRegister.java
new file mode 100644 (file)
index 0000000..747785f
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi;
+
+/** <b>Experimental</b> A structured set of OSGi bundles. */
+public interface BundleRegister {
+       /**
+        * @param pkg
+        *            the Java package
+        * @param version
+        *            the version, can be only major.minor or null
+        * @return the bundle providing this package or null if none was found
+        */
+       public String bundleProvidingPackage(String pkg, String version);
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/BundlesManager.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/BundlesManager.java
new file mode 100644 (file)
index 0000000..9877c31
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi;
+
+import java.util.Collection;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEvent;
+import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextListener;
+import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextClosedEvent;
+import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextFailedEvent;
+import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextRefreshedEvent;
+import org.eclipse.gemini.blueprint.util.OsgiBundleUtils;
+import org.eclipse.gemini.blueprint.util.OsgiFilterUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.util.Assert;
+
+/** Wraps low-level access to a {@link BundleContext} */
+@SuppressWarnings("deprecation")
+public class BundlesManager implements BundleContextAware, FrameworkListener,
+               InitializingBean, DisposableBean,
+               OsgiBundleApplicationContextListener<OsgiBundleApplicationContextEvent> {
+       private final static Log log = LogFactory.getLog(BundlesManager.class);
+
+       private BundleContext bundleContext;
+
+       private Long defaultTimeout = 60 * 1000l;
+       private Long pollingPeriod = 200l;
+
+       // Refresh sync objects
+       private final Object refreshedPackageSem = new Object();
+       private Boolean packagesRefreshed = false;
+
+       public BundlesManager() {
+       }
+
+       public BundlesManager(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+       }
+
+       /**
+        * Stop the module, update it, refresh it and restart it. All synchronously.
+        */
+       public void upgradeSynchronous(OsgiBundle osgiBundle) {
+               try {
+                       Bundle bundle = findRelatedBundle(osgiBundle);
+
+                       long begin = System.currentTimeMillis();
+
+                       long bStop = begin;
+                       stopSynchronous(bundle);
+
+                       long bUpdate = System.currentTimeMillis();
+                       updateSynchronous(bundle);
+
+                       // Refresh in case there are fragments
+                       long bRefresh = System.currentTimeMillis();
+                       refreshSynchronous(bundle);
+
+                       long bStart = System.currentTimeMillis();
+                       startSynchronous(bundle);
+
+                       long aStart = System.currentTimeMillis();
+                       if (log.isTraceEnabled()) {
+                               log.debug("OSGi upgrade performed in " + (aStart - begin)
+                                               + "ms for bundle " + osgiBundle);
+                               log.debug(" stop \t: " + (bUpdate - bStop) + "ms");
+                               log.debug(" update\t: " + (bRefresh - bUpdate) + "ms");
+                               log.debug(" refresh\t: " + (bStart - bRefresh) + "ms");
+                               log.debug(" start\t: " + (aStart - bStart) + "ms");
+                               log.debug(" TOTAL\t: " + (aStart - begin) + "ms");
+                       }
+
+                       long bAppContext = System.currentTimeMillis();
+                       String filter = "(Bundle-SymbolicName=" + bundle.getSymbolicName()
+                                       + ")";
+                       // Wait for application context to be ready
+                       // TODO: use service tracker
+                       Collection<ServiceReference<ApplicationContext>> srs = getServiceRefSynchronous(
+                                       ApplicationContext.class, filter);
+                       ServiceReference<ApplicationContext> sr = srs.iterator().next();
+                       long aAppContext = System.currentTimeMillis();
+                       long end = aAppContext;
+
+                       if (log.isTraceEnabled()) {
+                               log.debug("Application context refresh performed in "
+                                               + (aAppContext - bAppContext) + "ms for bundle "
+                                               + osgiBundle);
+                       }
+
+                       if (log.isDebugEnabled())
+                               log.debug("Bundle '" + bundle.getSymbolicName()
+                                               + "' upgraded and ready " + " (upgrade performed in "
+                                               + (end - begin) + "ms).");
+
+                       if (log.isTraceEnabled()) {
+                               ApplicationContext applicationContext = (ApplicationContext) bundleContext
+                                               .getService(sr);
+                               int beanDefCount = applicationContext.getBeanDefinitionCount();
+                               log.debug(" " + beanDefCount + " beans in app context of "
+                                               + bundle.getSymbolicName()
+                                               + ", average init time per bean=" + (end - begin)
+                                               / beanDefCount + "ms");
+                       }
+
+                       bundleContext.ungetService(sr);
+
+               } catch (Exception e) {
+                       throw new SlcException("Cannot update bundle " + osgiBundle, e);
+               }
+       }
+
+       /** Updates bundle synchronously. */
+       protected void updateSynchronous(Bundle bundle) throws BundleException {
+               bundle.update();
+               boolean waiting = true;
+
+               long begin = System.currentTimeMillis();
+               do {
+                       int state = bundle.getState();
+                       if (state == Bundle.INSTALLED || state == Bundle.ACTIVE
+                                       || state == Bundle.RESOLVED)
+                               waiting = false;
+
+                       sleepWhenPolling();
+                       checkTimeout(begin, "Update of bundle " + bundle.getSymbolicName()
+                                       + " timed out. Bundle state = " + bundle.getState());
+               } while (waiting);
+
+               if (log.isTraceEnabled())
+                       log.debug("Bundle " + bundle.getSymbolicName() + " updated.");
+       }
+
+       /** Starts bundle synchronously. Does nothing if already started. */
+       protected void startSynchronous(Bundle bundle) throws BundleException {
+               int originalState = bundle.getState();
+               if (originalState == Bundle.ACTIVE)
+                       return;
+
+               bundle.start();
+               boolean waiting = true;
+
+               long begin = System.currentTimeMillis();
+               do {
+                       if (bundle.getState() == Bundle.ACTIVE)
+                               waiting = false;
+
+                       sleepWhenPolling();
+                       checkTimeout(begin, "Start of bundle " + bundle.getSymbolicName()
+                                       + " timed out. Bundle state = " + bundle.getState());
+               } while (waiting);
+
+               if (log.isTraceEnabled())
+                       log.debug("Bundle " + bundle.getSymbolicName() + " started.");
+       }
+
+       /** Stops bundle synchronously. Does nothing if already started. */
+       protected void stopSynchronous(Bundle bundle) throws BundleException {
+               int originalState = bundle.getState();
+               if (originalState != Bundle.ACTIVE)
+                       return;
+
+               bundle.stop();
+               boolean waiting = true;
+
+               long begin = System.currentTimeMillis();
+               do {
+                       if (bundle.getState() != Bundle.ACTIVE
+                                       && bundle.getState() != Bundle.STOPPING)
+                               waiting = false;
+
+                       sleepWhenPolling();
+                       checkTimeout(begin, "Stop of bundle " + bundle.getSymbolicName()
+                                       + " timed out. Bundle state = " + bundle.getState());
+               } while (waiting);
+
+               if (log.isTraceEnabled())
+                       log.debug("Bundle " + bundle.getSymbolicName() + " stopped.");
+       }
+
+       /** Refresh bundle synchronously. Does nothing if already started. */
+       protected void refreshSynchronous(Bundle bundle) throws BundleException {
+               ServiceReference<PackageAdmin> packageAdminRef = bundleContext
+                               .getServiceReference(PackageAdmin.class);
+               PackageAdmin packageAdmin = (PackageAdmin) bundleContext
+                               .getService(packageAdminRef);
+               Bundle[] bundles = { bundle };
+
+               long begin = System.currentTimeMillis();
+               synchronized (refreshedPackageSem) {
+                       packagesRefreshed = false;
+                       packageAdmin.refreshPackages(bundles);
+                       try {
+                               refreshedPackageSem.wait(defaultTimeout);
+                       } catch (InterruptedException e) {
+                               // silent
+                       }
+                       if (!packagesRefreshed) {
+                               long now = System.currentTimeMillis();
+                               throw new SlcException("Packages not refreshed after "
+                                               + (now - begin) + "ms");
+                       } else {
+                               packagesRefreshed = false;
+                       }
+               }
+
+               if (log.isTraceEnabled())
+                       log.debug("Bundle " + bundle.getSymbolicName() + " refreshed.");
+       }
+
+       public void frameworkEvent(FrameworkEvent event) {
+               if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
+                       synchronized (refreshedPackageSem) {
+                               packagesRefreshed = true;
+                               refreshedPackageSem.notifyAll();
+                       }
+               }
+       }
+
+       public <S> Collection<ServiceReference<S>> getServiceRefSynchronous(
+                       Class<S> clss, String filter) throws InvalidSyntaxException {
+               if (log.isTraceEnabled())
+                       log.debug("Filter: '" + filter + "'");
+               Collection<ServiceReference<S>> sfs = null;
+               boolean waiting = true;
+               long begin = System.currentTimeMillis();
+               do {
+                       sfs = bundleContext.getServiceReferences(clss, filter);
+
+                       if (sfs != null)
+                               waiting = false;
+
+                       sleepWhenPolling();
+                       checkTimeout(begin, "Search of services " + clss + " with filter "
+                                       + filter + " timed out.");
+               } while (waiting);
+
+               return sfs;
+       }
+
+       protected void checkTimeout(long begin, String msg) {
+               long now = System.currentTimeMillis();
+               if (now - begin > defaultTimeout)
+                       throw new SlcException(msg + " (timeout after " + (now - begin)
+                                       + "ms)");
+
+       }
+
+       protected void sleepWhenPolling() {
+               try {
+                       Thread.sleep(pollingPeriod);
+               } catch (InterruptedException e) {
+                       throw new SlcException("Polling interrupted");
+               }
+       }
+
+       /** Creates and open a new service tracker. */
+       public <S> ServiceTracker<S, S> newTracker(Class<S> clss) {
+               ServiceTracker<S, S> st = new ServiceTracker<S, S>(bundleContext, clss,
+                               null);
+               st.open();
+               return st;
+       }
+
+       public <T> T getSingleService(Class<T> clss, String filter,
+                       Boolean synchronous) {
+               if (filter != null)
+                       Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter");
+               Collection<ServiceReference<T>> sfs;
+               try {
+                       if (synchronous)
+                               sfs = getServiceRefSynchronous(clss, filter);
+                       else
+                               sfs = bundleContext.getServiceReferences(clss, filter);
+               } catch (InvalidSyntaxException e) {
+                       throw new SlcException("Cannot retrieve service reference for "
+                                       + filter, e);
+               }
+
+               if (sfs == null || sfs.size() == 0)
+                       return null;
+               else if (sfs.size() > 1)
+                       throw new SlcException("More than one execution flow found for "
+                                       + filter);
+               return (T) bundleContext.getService(sfs.iterator().next());
+       }
+
+       public <T> T getSingleServiceStrict(Class<T> clss, String filter,
+                       Boolean synchronous) {
+               T service = getSingleService(clss, filter, synchronous);
+               if (service == null)
+                       throw new SlcException("No execution flow found for " + filter);
+               else
+                       return service;
+       }
+
+       public OsgiBundle findRelatedBundle(String moduleName, String moduleVersion) {
+               OsgiBundle osgiBundle = new OsgiBundle(moduleName, moduleVersion);
+               if (osgiBundle.getVersion() == null) {
+                       Bundle bundle = findRelatedBundle(osgiBundle);
+                       osgiBundle = new OsgiBundle(bundle);
+               }
+               return osgiBundle;
+       }
+
+       /**
+        * @param osgiBundle
+        *            cannot be null
+        * @return the related bundle or null if not found
+        * @throws SlcException
+        *             if osgiBundle argument is null
+        */
+       public Bundle findRelatedBundle(OsgiBundle osgiBundle) {
+               if (osgiBundle == null)
+                       throw new SlcException("OSGi bundle cannot be null");
+
+               Bundle bundle = null;
+               if (osgiBundle.getInternalBundleId() != null) {
+                       bundle = bundleContext.getBundle(osgiBundle.getInternalBundleId());
+                       Assert.isTrue(
+                                       osgiBundle.getName().equals(bundle.getSymbolicName()),
+                                       "symbolic name consistent");
+                       if (osgiBundle.getVersion() != null)
+                               Assert.isTrue(
+                                               osgiBundle.getVersion().equals(
+                                                               bundle.getHeaders().get(
+                                                                               Constants.BUNDLE_VERSION)),
+                                               "version consistent");
+               } else if (osgiBundle.getVersion() == null
+                               || osgiBundle.getVersion().equals("0.0.0")) {
+                       bundle = OsgiBundleUtils.findBundleBySymbolicName(bundleContext,
+                                       osgiBundle.getName());
+               } else {// scan all bundles
+                       bundles: for (Bundle b : bundleContext.getBundles()) {
+                               if (b.getSymbolicName() == null) {
+                                       log.warn("Bundle " + b + " has no symbolic name defined.");
+                                       continue bundles;
+                               }
+
+                               if (b.getSymbolicName().equals(osgiBundle.getName())) {
+                                       if (osgiBundle.getVersion() == null) {
+                                               bundle = b;
+                                               break bundles;
+                                       }
+
+                                       if (b.getHeaders().get(Constants.BUNDLE_VERSION)
+                                                       .equals(osgiBundle.getVersion())) {
+                                               bundle = b;
+                                               osgiBundle.setInternalBundleId(b.getBundleId());
+                                               break bundles;
+                                       }
+                               }
+                       }
+               }
+               return bundle;
+       }
+
+       /** Find a single bundle based on a symbolic name pattern. */
+       public OsgiBundle findFromPattern(String pattern) {
+               OsgiBundle osgiBundle = null;
+               for (Bundle b : bundleContext.getBundles()) {
+                       if (b.getSymbolicName().contains(pattern)) {
+                               osgiBundle = new OsgiBundle(b);
+                               break;
+                       }
+               }
+               return osgiBundle;
+       }
+
+       public OsgiBundle getBundle(Long bundleId) {
+               Bundle bundle = bundleContext.getBundle(bundleId);
+               return new OsgiBundle(bundle);
+       }
+
+       public void setBundleContext(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               bundleContext.addFrameworkListener(this);
+       }
+
+       public void destroy() throws Exception {
+               bundleContext.removeFrameworkListener(this);
+       }
+
+       public void setDefaultTimeout(Long defaultTimeout) {
+               this.defaultTimeout = defaultTimeout;
+       }
+
+       /**
+        * Use with caution since it may interfer with some cached information
+        * within this object
+        */
+       public BundleContext getBundleContext() {
+               return bundleContext;
+       }
+
+       public void setPollingPeriod(Long pollingPeriod) {
+               this.pollingPeriod = pollingPeriod;
+       }
+
+       public void onOsgiApplicationEvent(OsgiBundleApplicationContextEvent event) {
+               if (event instanceof OsgiBundleContextRefreshedEvent) {
+                       log.debug("App context refreshed: " + event);
+               } else if (event instanceof OsgiBundleContextFailedEvent) {
+                       log.debug("App context failed: " + event);
+               }
+               if (event instanceof OsgiBundleContextClosedEvent) {
+                       log.debug("App context closed: " + event);
+               }
+
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/FileSystemBundleRegister.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/FileSystemBundleRegister.java
new file mode 100644 (file)
index 0000000..03f21c5
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.Constants;
+
+/** <b>Experimental</b> */
+public class FileSystemBundleRegister implements BundleRegister {
+       private final static Log log = LogFactory
+                       .getLog(FileSystemBundleRegister.class);
+       private Properties packagesBundles = null;
+
+       public String bundleProvidingPackage(String pkg, String version) {
+               if (packagesBundles == null)
+                       return null;
+               return packagesBundles.getProperty(pkg);
+       }
+
+       protected void scan(File baseDirectory) {
+               long begin = System.currentTimeMillis();
+               int bundleCount = 0;
+               int packageCount = 0;
+
+               packagesBundles = new Properties();
+
+               File[] files = baseDirectory.listFiles();
+               for (File file : files) {
+                       if (file.isDirectory()) {
+
+                       } else {
+                               JarFile jarFile = null;
+                               try {
+                                       jarFile = new JarFile(file);
+                                       Manifest manifest = jarFile.getManifest();
+                                       String symbolicName = manifest.getMainAttributes()
+                                                       .getValue(Constants.BUNDLE_SYMBOLICNAME);
+                                       String exportPackage = manifest.getMainAttributes()
+                                                       .getValue(Constants.EXPORT_PACKAGE);
+
+                                       // List exported packages
+                                       Set<String> exportedPackages = exportPackageToPackageNames(exportPackage);
+
+                                       for (String exportedPackage : exportedPackages) {
+                                               packagesBundles.put(exportedPackage, symbolicName);
+                                               packageCount++;
+                                               if (log.isTraceEnabled())
+                                                       log.trace("Register " + exportedPackage + "="
+                                                                       + symbolicName);
+                                       }
+                                       bundleCount++;
+                               } catch (Exception e) {
+                                       log.warn("Cannot scan " + file, e);
+                                       if (log.isTraceEnabled())
+                                               e.printStackTrace();
+                               } finally {
+                                       IOUtils.closeQuietly(jarFile);
+                               }
+                       }
+               }
+               if (log.isDebugEnabled())
+                       log.debug("Scanned " + bundleCount + " bundles with "
+                                       + packageCount + " packages in "
+                                       + (System.currentTimeMillis() - begin) + " ms");
+       }
+
+       protected Set<String> exportPackageToPackageNames(String exportPackage) {
+               Set<String> exportedPackages = new HashSet<String>();
+               if (exportPackage == null)
+                       return exportedPackages;
+               char[] arr = exportPackage.toCharArray();
+
+               StringBuffer currentPkg = new StringBuffer("");
+               boolean skip = false;
+               boolean inQuote = false;
+               for (char c : arr) {
+                       if (c == ' ' || c == '\n') {
+                               // ignore
+                       } else if (c == ';') {
+                               if (!skip)
+                                       skip = true;
+                       } else if (c == ',') {
+                               if (skip && !inQuote) {
+                                       skip = false;
+                                       // add new package
+                                       exportedPackages.add(currentPkg.toString());
+                                       currentPkg = new StringBuffer("");
+                               }
+                       } else if (c == '\"') {
+                               inQuote = inQuote ? false : true;
+                       } else {
+                               if (!skip)
+                                       currentPkg.append(c);
+                       }
+               }
+
+               return exportedPackages;
+       }
+
+       public static void main(String[] args) {
+               FileSystemBundleRegister fsbr = new FileSystemBundleRegister();
+               fsbr.scan(new File(
+                               "/home/mbaudier/dev/src/slc/dist/org.argeo.slc.sdk/target/lib"));
+
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java
new file mode 100644 (file)
index 0000000..2d8b031
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.core.Ordered;
+
+/** Publishes beans of the application context as OSGi services. */
+@SuppressWarnings(value = { "unchecked", "rawtypes" })
+public class MultipleServiceExporterPostProcessor implements
+               ApplicationListener, Ordered {
+       private final static Log log = LogFactory
+                       .getLog(MultipleServiceExporterPostProcessor.class);
+
+       private List<Class> interfaces = new ArrayList<Class>();
+
+       private int order = Ordered.LOWEST_PRECEDENCE;
+
+       private BundleContext bundleContext = null;
+
+       // private Class osgiServiceFactoryClass = OsgiServiceFactoryBean.class;
+       // private Boolean useServiceProviderContextClassLoader = false;
+
+       public void onApplicationEvent(ApplicationEvent event) {
+               Map<String, Object> beans = new HashMap<String, Object>();
+               if (event instanceof ContextRefreshedEvent) {
+                       if (bundleContext != null) {
+                               for (Class clss : interfaces) {
+                                       ApplicationContext ac = ((ContextRefreshedEvent) event)
+                                                       .getApplicationContext();
+                                       beans.putAll(ac.getBeansOfType(clss, false, false));
+                               }
+
+                               int count = 0;
+                               for (String beanName : beans.keySet()) {
+                                       Object bean = beans.get(beanName);
+                                       List<String> classes = new ArrayList<String>();
+                                       for (Class clss : interfaces) {
+                                               if (clss.isAssignableFrom(bean.getClass())) {
+                                                       classes.add(clss.getName());
+                                               }
+                                       }
+                                       Properties props = new Properties();
+                                       Bundle bundle = bundleContext.getBundle();
+                                       props.put(Constants.BUNDLE_SYMBOLICNAME,
+                                                       bundle.getSymbolicName());
+                                       props.put(Constants.BUNDLE_VERSION, bundle.getVersion());
+                                       // retrocompatibility with pre-1.0:
+                                       props.put("org.eclipse.gemini.blueprint.bean.name", beanName);
+                                       bundleContext.registerService(
+                                                       classes.toArray(new String[classes.size()]), bean,
+                                                       new Hashtable(props));
+                                       count++;
+                               }
+                               if (log.isTraceEnabled())
+                                       log.trace("Published " + count + " " + interfaces
+                                                       + " as OSGi services from bundle "
+                                                       + bundleContext.getBundle().getSymbolicName() + " "
+                                                       + bundleContext.getBundle().getVersion());
+                               // note: the services will be automatically unregistered when
+                               // the bundle will be stopped
+                       }
+               }
+       }
+
+       // public void postProcessBeanFactory(
+       // ConfigurableListableBeanFactory beanFactory) throws BeansException {
+       // if (!(beanFactory instanceof BeanDefinitionRegistry)) {
+       // throw new SlcException("Can only work on "
+       // + BeanDefinitionRegistry.class);
+       // }
+       //
+       // long begin = System.currentTimeMillis();
+       //
+       // // Merge all beans implementing these interfaces
+       // Set<String> beanNames = new HashSet<String>();
+       // for (Class clss : interfaces) {
+       // String[] strs = beanFactory.getBeanNamesForType(clss, true, false);
+       // beanNames.addAll(Arrays.asList(strs));
+       // }
+       //
+       // // Register service factory beans for them
+       // for (String beanName : beanNames) {
+       // MutablePropertyValues mpv = new MutablePropertyValues();
+       // mpv.addPropertyValue("interfaces", interfaces.toArray());
+       // mpv.addPropertyValue("targetBeanName", beanName);
+       // if (useServiceProviderContextClassLoader)
+       // mpv.addPropertyValue("contextClassLoader",
+       // ExportContextClassLoader.SERVICE_PROVIDER);
+       // RootBeanDefinition bd = new RootBeanDefinition(
+       // osgiServiceFactoryClass, mpv);
+       //
+       // String exporterBeanName = "osgiService." + beanName;
+       // if (log.isTraceEnabled())
+       // log.debug("Registering OSGi service exporter "
+       // + exporterBeanName);
+       // ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(
+       // exporterBeanName, bd);
+       // }
+       //
+       // long end = System.currentTimeMillis();
+       // if (log.isTraceEnabled())
+       // log.debug("Multiple services exported in " + (end - begin)
+       // + " ms in bundle.");
+       //
+       // }
+
+       public void setInterfaces(List<Class> interfaces) {
+               this.interfaces = interfaces;
+       }
+
+       // public void setOsgiServiceFactoryClass(Class osgiServiceFactoryClass) {
+       // this.osgiServiceFactoryClass = osgiServiceFactoryClass;
+       // }
+
+       public int getOrder() {
+               return order;
+       }
+
+       public void setOrder(int order) {
+               this.order = order;
+       }
+
+       // public void setUseServiceProviderContextClassLoader(
+       // Boolean useServiceProviderContextClassLoader) {
+       // this.useServiceProviderContextClassLoader =
+       // useServiceProviderContextClassLoader;
+       // }
+
+       public void setBundleContext(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiBundle.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiBundle.java
new file mode 100644 (file)
index 0000000..cb11615
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi;
+
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.core.build.ResourceDistribution;
+import org.argeo.slc.deploy.DeploymentData;
+import org.argeo.slc.deploy.Module;
+import org.argeo.slc.deploy.ModuleDescriptor;
+import org.argeo.slc.deploy.TargetData;
+import org.argeo.slc.execution.RealizedFlow;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.springframework.core.io.Resource;
+
+/** A deployed OSGi bundle. */
+public class OsgiBundle extends DefaultNameVersion implements Module {
+       private ResourceDistribution distribution;
+
+       private Long internalBundleId;
+
+       private String title;
+       private String description;
+
+       public OsgiBundle() {
+
+       }
+
+       public OsgiBundle(String name, String version) {
+               super(name, version);
+       }
+
+       public OsgiBundle(NameVersion nameVersion) {
+               super(nameVersion);
+       }
+
+       public OsgiBundle(Bundle bundle) {
+               super(bundle.getSymbolicName(), getVersionSafe(bundle));
+               internalBundleId = bundle.getBundleId();
+       }
+
+       /**
+        * Initialize from a {@link RealizedFlow}.
+        * 
+        * @deprecated introduce an unnecessary dependency. TODO: create a separate
+        *             helper.
+        */
+       public OsgiBundle(RealizedFlow realizedFlow) {
+               super(realizedFlow.getModuleName(), realizedFlow.getModuleVersion());
+       }
+
+       /** Utility to avoid NPE. */
+       private static String getVersionSafe(Bundle bundle) {
+               Object versionObj = bundle.getHeaders().get(Constants.BUNDLE_VERSION);
+               if (versionObj != null)
+                       return versionObj.toString();
+               else
+                       return null;
+       }
+
+       /** Unique deployed system id. TODO: use internal bundle id when available? */
+       public String getDeployedSystemId() {
+               return getName() + ":" + getVersion();
+       }
+
+       /**
+        * OSGi bundle are self-contained and do not require additional deployment
+        * data.
+        * 
+        * @return always null
+        */
+       public DeploymentData getDeploymentData() {
+               return null;
+       }
+
+       /** The related distribution. */
+       public Distribution getDistribution() {
+               return distribution;
+       }
+
+       /**
+        * The related distribution, a jar file with OSGi metadata referenced by a
+        * {@link Resource}.
+        */
+       public ResourceDistribution getResourceDistribution() {
+               return distribution;
+       }
+
+       /** TODO: reference the {@link OsgiRuntime} as target data? */
+       public TargetData getTargetData() {
+               throw new UnsupportedOperationException();
+       }
+
+       public void setResourceDistribution(ResourceDistribution distribution) {
+               this.distribution = distribution;
+       }
+
+       /**
+        * Bundle ID used by the OSGi runtime. To be used for optimization when
+        * looking in the bundle context. Can therefore be null.
+        */
+       public Long getInternalBundleId() {
+               return internalBundleId;
+       }
+
+       /** Only package access for the time being. e.g. from {@link BundlesManager} */
+       void setInternalBundleId(Long internalBundleId) {
+               this.internalBundleId = internalBundleId;
+       }
+
+       /** Value of the <code>Bundle-Name</code> directive. */
+       public String getTitle() {
+               return title;
+       }
+
+       public void setTitle(String label) {
+               this.title = label;
+       }
+
+       /** Value of the <code>Bundle-Description</code> directive. */
+       public String getDescription() {
+               return description;
+       }
+
+       public void setDescription(String description) {
+               this.description = description;
+       }
+
+       public ModuleDescriptor getModuleDescriptor() {
+               ModuleDescriptor moduleDescriptor = new ModuleDescriptor();
+               moduleDescriptor.setName(getName());
+               moduleDescriptor.setVersion(getVersion());
+               moduleDescriptor.setDescription(description);
+               moduleDescriptor.setTitle(title);
+               return moduleDescriptor;
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiExecutionModule.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiExecutionModule.java
new file mode 100644 (file)
index 0000000..df7ae9b
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.core.execution.AbstractSpringExecutionModule;
+import org.argeo.slc.execution.ExecutionContext;
+
+@Deprecated
+public class OsgiExecutionModule extends AbstractSpringExecutionModule {
+       private final static Log log = LogFactory.getLog(OsgiExecutionModule.class);
+
+       public OsgiExecutionModule() {
+               log.error("######## ERROR - DEPRECATED APPROACH USED ########");
+               log.error(OsgiExecutionModule.class.getName() + " is deprecated. ");
+               log
+                               .error("It will be removed in the next release. Remove its bean definition.");
+               log
+                               .error("And replace: <service interface=\"org.argeo.slc.execution.ExecutionModule\" ref=\"executionModule\" />");
+               log
+                               .error("by: <beans:import resource=\"classpath:org/argeo/slc/osgi/execution/spring.xml\" /> ");
+               log.error("in osgi.xml.\n\n");
+       }
+
+       public void setExecutionContext(ExecutionContext executionContext) {
+               // do nothing, just for compatibility
+       }
+
+       /*
+        * private BundleContext bundleContext;
+        * 
+        * @Override public void execute(ExecutionFlowDescriptor
+        * executionFlowDescriptor) { if (descriptorConverter != null)
+        * executionContext.addVariables(descriptorConverter
+        * .convertValues(executionFlowDescriptor));
+        * 
+        * ExecutionFlow flow = findExecutionFlow(getName(), getVersion(),
+        * executionFlowDescriptor.getName()); flow.run(); }
+        * 
+        * @Override protected Map<String, ExecutionFlow> listFlows() { String
+        * filter = "(org.argeo.slc.execution.module.name=" + getName() + ")";
+        * ServiceReference[] sfs; try { sfs =
+        * bundleContext.getServiceReferences(ExecutionFlow.class .getName(),
+        * filter); } catch (InvalidSyntaxException e) { throw new SlcException(
+        * "Cannot retrieve service reference for flow " + filter, e); }
+        * 
+        * Map<String, ExecutionFlow> flows = new HashMap<String, ExecutionFlow>();
+        * for (ServiceReference sf : sfs) { ExecutionFlow flow = (ExecutionFlow)
+        * bundleContext.getService(sf); flows.put(flow.getName(), flow); } return
+        * flows; }
+        * 
+        * public String getName() { return
+        * bundleContext.getBundle().getSymbolicName(); }
+        * 
+        * public String getVersion() { return
+        * bundleContext.getBundle().getHeaders().get("Bundle-Version") .toString();
+        * }
+        * 
+        * public void setBundleContext(BundleContext bundleContext) {
+        * this.bundleContext = bundleContext; }
+        * 
+        * protected ExecutionFlow findExecutionFlow(String moduleName, String
+        * moduleVersion, String flowName) { String filter =
+        * "(&(org.argeo.slc.execution.module.name=" + moduleName +
+        * ")(org.argeo.slc.execution.flow.name=" + flowName + "))";
+        * log.debug("OSGi filter: " + filter);
+        * 
+        * Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter");
+        * ServiceReference[] sfs; try { sfs =
+        * bundleContext.getServiceReferences(ExecutionFlow.class .getName(),
+        * filter); } catch (InvalidSyntaxException e) { throw new
+        * SlcException("Cannot retrieve service reference for " + filter, e); }
+        * 
+        * if (sfs == null || sfs.length == 0) throw new
+        * SlcException("No execution flow found for " + filter); else if
+        * (sfs.length > 1) throw new
+        * SlcException("More than one execution flow found for " + filter); return
+        * (ExecutionFlow) bundleContext.getService(sfs[0]); }
+        */
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiExecutionModulesManager.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiExecutionModulesManager.java
new file mode 100644 (file)
index 0000000..046cfb6
--- /dev/null
@@ -0,0 +1,701 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi;
+
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.StandardMBean;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.AbstractExecutionModulesManager;
+import org.argeo.slc.core.execution.DefaultExecutionFlowDescriptorConverter;
+import org.argeo.slc.deploy.Module;
+import org.argeo.slc.deploy.ModuleDescriptor;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
+import org.argeo.slc.execution.ExecutionModulesListener;
+import org.argeo.slc.execution.RealizedFlow;
+import org.eclipse.gemini.blueprint.service.importer.OsgiServiceLifecycleListener;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Constants;
+import org.osgi.framework.launch.Framework;
+import org.springframework.context.ApplicationContext;
+
+/** Execution modules manager implementation based on an OSGi runtime. */
+public class OsgiExecutionModulesManager extends
+               AbstractExecutionModulesManager implements
+               OsgiServiceLifecycleListener, BundleListener {
+
+       private final static Log log = LogFactory
+                       .getLog(OsgiExecutionModulesManager.class);
+
+       private BundlesManager bundlesManager;
+       private Map<OsgiBundle, ExecutionContext> executionContexts = new HashMap<OsgiBundle, ExecutionContext>();
+       private Map<OsgiBundle, ExecutionFlowDescriptorConverter> executionFlowDescriptorConverters = new HashMap<OsgiBundle, ExecutionFlowDescriptorConverter>();
+       private Map<OsgiBundle, Set<ExecutionFlow>> executionFlows = new HashMap<OsgiBundle, Set<ExecutionFlow>>();
+       private ExecutionFlowDescriptorConverter defaultDescriptorConverter = new DefaultExecutionFlowDescriptorConverter();
+
+       private List<ExecutionModulesListener> executionModulesListeners = new ArrayList<ExecutionModulesListener>();
+
+       private Boolean registerFlowsToJmx = false;
+
+       public void init() throws Exception {
+               bundlesManager.getBundleContext().addBundleListener(this);
+
+               final String module = System.getProperty(UNIQUE_LAUNCH_MODULE_PROPERTY);
+               final String flow = System.getProperty(UNIQUE_LAUNCH_FLOW_PROPERTY);
+               if (module != null) {
+                       // launch a flow and stops
+                       new Thread("Unique Flow") {
+                               @Override
+                               public void run() {
+                                       executeFlowAndExit(module, null, flow);
+                               }
+                       }.start();
+               }
+       }
+
+       public void destroy() {
+               bundlesManager.getBundleContext().removeBundleListener(this);
+       }
+
+       /** Executes a single flow and <b>stops the JVM</b> */
+       protected void executeFlowAndExit(final String module,
+                       final String version, final String flow) {
+               if (log.isDebugEnabled())
+                       log.debug("Launch unique flow " + flow + " from module " + module);
+               try {
+                       OsgiBundle osgiBundle = bundlesManager.findFromPattern(module);
+                       if (osgiBundle == null)
+                               throw new SlcException("No OSGi bundle found for " + module);
+                       // Bundle moduleBundle =
+                       // bundlesManager.findRelatedBundle(osgiBundle);
+                       start(osgiBundle);
+
+                       RealizedFlow lastLaunch = findRealizedFlow(module, flow);
+                       if (lastLaunch == null)
+                               throw new SlcException("Cannot find launch for " + module + " "
+                                               + flow);
+                       execute(lastLaunch);
+               } catch (Exception e) {
+                       log.error(
+                                       "Error in unique flow " + flow + " from module " + module,
+                                       e);
+               } finally {
+                       if (log.isDebugEnabled())
+                               log.debug("Shutdown OSGi runtime...");
+                       Framework framework = (Framework) bundlesManager.getBundleContext()
+                                       .getBundle(0);
+                       try {
+                               // shutdown framework
+                               framework.stop();
+                               // wait 1 min for shutdown
+                               framework.waitForStop(60 * 1000);
+                               // close VM
+                               System.exit(0);
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                               System.exit(1);
+                       }
+               }
+       }
+
+       // public void startExectionModule(String moduleName, String moduleVersion)
+       // {
+       // try {
+       // ServiceReference[] sr = bundlesManager.getServiceRefSynchronous(
+       // ApplicationContext.class.getName(),
+       // "org.springframework.context.service.name=" + moduleName);
+       // // bundlesManager.startSynchronous(moduleBundle);
+       // if (sr == null || sr.length == 0)
+       // throw new SlcException(
+       // "Cannot find execution module application context "
+       // + moduleName);
+       // } catch (InvalidSyntaxException e) {
+       // throw new SlcException("Cannot start exeuction module "
+       // + moduleName, e);
+       // }
+       // }
+
+       public synchronized ExecutionModuleDescriptor getExecutionModuleDescriptor(
+                       String moduleName, String version) {
+               ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
+               OsgiBundle osgiBundle = null;
+               DefaultNameVersion nameVersion = new DefaultNameVersion(moduleName,
+                               version);
+               bundles: for (Iterator<OsgiBundle> iterator = executionContexts
+                               .keySet().iterator(); iterator.hasNext();) {
+                       OsgiBundle ob = iterator.next();
+                       if (nameVersion.getVersion() != null) {
+                               if (ob.equals(nameVersion)) {
+                                       osgiBundle = ob;
+                                       break bundles;
+                               }
+                       } else {
+                               if (ob.getName().equals(nameVersion.getName())) {
+                                       osgiBundle = ob;
+                                       break bundles;
+                               }
+                       }
+               }
+               if (osgiBundle == null)
+                       throw new SlcException("No execution module registered for "
+                                       + nameVersion);
+               md.setName(osgiBundle.getName());
+               md.setVersion(osgiBundle.getVersion());
+               md.setTitle(osgiBundle.getTitle());
+               md.setDescription(osgiBundle.getDescription());
+
+               ExecutionFlowDescriptorConverter executionFlowDescriptorConverter = getExecutionFlowDescriptorConverter(
+                               moduleName, version);
+               if (executionFlowDescriptorConverter == null)
+                       throw new SlcException("No flow converter found.");
+               executionFlowDescriptorConverter.addFlowsToDescriptor(md,
+                               listFlows(moduleName, version));
+               return md;
+       }
+
+       public synchronized List<ExecutionModuleDescriptor> listExecutionModules() {
+               List<ExecutionModuleDescriptor> descriptors = new ArrayList<ExecutionModuleDescriptor>();
+
+               for (Iterator<OsgiBundle> iterator = executionContexts.keySet()
+                               .iterator(); iterator.hasNext();) {
+                       OsgiBundle osgiBundle = iterator.next();
+                       ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
+                       setMetadataFromBundle(md,
+                                       bundlesManager.findRelatedBundle(osgiBundle));
+                       descriptors.add(md);
+               }
+               return descriptors;
+       }
+
+       protected synchronized Map<String, ExecutionFlow> listFlows(
+                       String moduleName, String moduleVersion) {
+
+               Map<String, ExecutionFlow> flows = new HashMap<String, ExecutionFlow>();
+               OsgiBundle key = bundlesManager.findRelatedBundle(moduleName,
+                               moduleVersion);
+               if (!executionFlows.containsKey(key))
+                       return flows;
+               Set<ExecutionFlow> flowsT = executionFlows.get(key);
+               for (ExecutionFlow flow : flowsT)
+                       flows.put(flow.getName(), flow);
+               return flows;
+       }
+
+       protected ExecutionFlow findExecutionFlow(String moduleName,
+                       String moduleVersion, String flowName) {
+               String filter = moduleVersion == null || moduleVersion.equals("0.0.0") ? "(&(Bundle-SymbolicName="
+                               + moduleName
+                               + ")(org.eclipse.gemini.blueprint.bean.name="
+                               + flowName + "))"
+                               : "(&(Bundle-SymbolicName=" + moduleName + ")(Bundle-Version="
+                                               + moduleVersion
+                                               + ")(org.eclipse.gemini.blueprint.bean.name="
+                                               + flowName + "))";
+               return bundlesManager.getSingleServiceStrict(ExecutionFlow.class,
+                               filter, true);
+       }
+
+       protected ExecutionContext findExecutionContext(String moduleName,
+                       String moduleVersion) {
+               String filter = moduleFilter(moduleName, moduleVersion);
+               return bundlesManager.getSingleServiceStrict(ExecutionContext.class,
+                               filter, true);
+       }
+
+       protected ExecutionFlowDescriptorConverter findExecutionFlowDescriptorConverter(
+                       String moduleName, String moduleVersion) {
+               String filter = moduleFilter(moduleName, moduleVersion);
+               return bundlesManager.getSingleService(
+                               ExecutionFlowDescriptorConverter.class, filter, false);
+       }
+
+       /** Only based on symbolic name if version is null or "0.0.0" */
+       protected String moduleFilter(String moduleName, String moduleVersion) {
+               return moduleVersion == null || moduleVersion.equals("0.0.0") ? "(Bundle-SymbolicName="
+                               + moduleName + ")"
+                               : "(&(Bundle-SymbolicName=" + moduleName + ")(Bundle-Version="
+                                               + moduleVersion + "))";
+
+       }
+
+       /**
+        * Builds a minimal realized flow, based on the provided information
+        * (typically from the command line).
+        * 
+        * @param module
+        *            a bundle id, or a pattern contained in a bundle symbolic name
+        * @param module
+        *            the execution flow name
+        * @return a minimal realized flow, to be used in an execution
+        */
+       public RealizedFlow findRealizedFlow(String module, String executionName) {
+               // First check whether we have a bundleId
+               Long bundleId = null;
+               try {
+                       bundleId = Long.parseLong(module);
+               } catch (NumberFormatException e) {
+                       // silent
+               }
+
+               // Look for bundle names containing pattern
+               OsgiBundle bundle = null;
+               if (bundleId != null) {
+                       bundle = bundlesManager.getBundle(bundleId);
+               } else {
+                       bundle = bundlesManager.findFromPattern(module);
+               }
+
+               if (bundle != null) {
+                       RealizedFlow launch = new RealizedFlow();
+                       launch.setModuleName(bundle.getName());
+                       launch.setModuleVersion(bundle.getVersion());
+                       ExecutionFlowDescriptor descriptor = new ExecutionFlowDescriptor();
+                       descriptor.setName(executionName);
+                       launch.setFlowDescriptor(descriptor);
+                       return launch;
+               } else {
+                       log.warn("Could not find any execution module matching these requirements.");
+                       return null;
+               }
+       }
+
+       public void upgrade(NameVersion nameVersion) {
+               OsgiBundle osgiBundle = new OsgiBundle(nameVersion);
+               bundlesManager.upgradeSynchronous(osgiBundle);
+       }
+
+       protected synchronized ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
+                       String moduleName, String moduleVersion) {
+               return findExecutionFlowDescriptorConverter(moduleName, moduleVersion);
+               // OsgiBundle osgiBundle = new OsgiBundle(moduleName, moduleVersion);
+               // return getExecutionFlowDescriptorConverter(osgiBundle);
+       }
+
+       protected synchronized ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
+                       OsgiBundle osgiBundle) {
+               if (executionFlowDescriptorConverters.containsKey(osgiBundle))
+                       return executionFlowDescriptorConverters.get(osgiBundle);
+               else
+                       return defaultDescriptorConverter;
+       }
+
+       public ModuleDescriptor getModuleDescriptor(String moduleName,
+                       String version) {
+               return getExecutionModuleDescriptor(moduleName, version);
+       }
+
+       public List<ModuleDescriptor> listModules() {
+               Bundle[] bundles = bundlesManager.getBundleContext().getBundles();
+               List<ModuleDescriptor> lst = new ArrayList<ModuleDescriptor>();
+               for (Bundle bundle : bundles) {
+                       ModuleDescriptor moduleDescriptor = new ModuleDescriptor();
+                       setMetadataFromBundle(moduleDescriptor, bundle);
+                       lst.add(moduleDescriptor);
+               }
+               return lst;
+       }
+
+       public void start(NameVersion nameVersion) {
+               try {
+                       Bundle bundle = bundlesManager.findRelatedBundle(new OsgiBundle(
+                                       nameVersion));
+                       if (bundle == null)
+                               throw new SlcException("Could not find bundle for "
+                                               + nameVersion);
+
+                       bundlesManager.startSynchronous(bundle);
+                       if (isSpringInstrumented(bundle)) {
+                               // Wait for Spring application context to be ready
+                               String filter = "(Bundle-SymbolicName="
+                                               + bundle.getSymbolicName() + ")";
+                               try {
+                                       bundlesManager.getServiceRefSynchronous(
+                                                       ApplicationContext.class, filter);
+                               } catch (Exception e) {
+                                       // stop if application context not found
+                                       bundle.stop();
+                                       throw e;
+                               }
+                       }
+               } catch (Exception e) {
+                       throw new SlcException("Cannot start " + nameVersion, e);
+               }
+       }
+
+       /** Do it calmly in order to avoid NPE */
+       private Boolean isSpringInstrumented(Bundle bundle) {
+               Dictionary<?, ?> headers = bundle.getHeaders();
+               if (headers != null && headers.get("Spring-Context") != null)
+                       return true;
+               Enumeration<?> springEntryPaths = bundle
+                               .getEntryPaths("/META-INF/spring");
+               if (springEntryPaths != null && springEntryPaths.hasMoreElements())
+                       return true;
+               return false;
+       }
+
+       public void stop(NameVersion nameVersion) {
+               try {
+                       Bundle bundle = bundlesManager.findRelatedBundle(new OsgiBundle(
+                                       nameVersion));
+                       bundlesManager.stopSynchronous(bundle);
+               } catch (BundleException e) {
+                       throw new SlcException("Cannot stop " + nameVersion, e);
+               }
+       }
+
+       protected void setMetadataFromBundle(ModuleDescriptor md, Bundle bundle) {
+               Bundle bdl = bundle;
+               if (bdl == null) {
+                       if (md.getName() == null || md.getVersion() == null)
+                               throw new SlcException("Name and version not available.");
+
+                       Bundle[] bundles = bundlesManager.getBundleContext().getBundles();
+                       for (Bundle b : bundles) {
+                               if (b.getSymbolicName().equals(md.getName())
+                                               && md.getVersion().equals(
+                                                               getHeaderSafe(b, Constants.BUNDLE_VERSION))) {
+                                       bdl = b;
+                                       break;
+                               }
+                       }
+
+               }
+
+               if (bdl == null)
+                       throw new SlcException("Cannot find bundle.");
+
+               md.setName(bdl.getSymbolicName());
+               md.setVersion(getHeaderSafe(bdl, Constants.BUNDLE_VERSION));
+               md.setTitle(getHeaderSafe(bdl, Constants.BUNDLE_NAME));
+               md.setDescription(getHeaderSafe(bdl, Constants.BUNDLE_DESCRIPTION));
+
+               // copy manifets header to meta data
+               Dictionary<?, ?> headers = bundle.getHeaders();
+               Enumeration<?> keys = headers.keys();
+               while (keys.hasMoreElements()) {
+                       Object key = keys.nextElement();
+                       Object value = headers.get(key);
+                       if (value != null)
+                               md.getMetadata().put(key.toString(), value.toString());
+               }
+
+               // check if started
+               if (bundle.getState() == Bundle.ACTIVE
+                               || bundle.getState() == Bundle.STARTING)
+                       md.setStarted(true);
+               else
+                       md.setStarted(false);
+       }
+
+       private String getHeaderSafe(Bundle bundle, Object key) {
+               Object obj = bundle.getHeaders().get(key);
+               if (obj == null)
+                       return null;
+               else
+                       return obj.toString();
+       }
+
+       /*
+        * REGISTRATION
+        */
+
+       /** Registers an execution context. */
+       public synchronized void register(ExecutionContext executionContext,
+                       Map<String, String> properties) {
+               OsgiBundle osgiBundle = asOsgiBundle(properties);
+               Bundle bundle = bundlesManager.findRelatedBundle(osgiBundle);
+               osgiBundle.setTitle(getHeaderSafe(bundle, Constants.BUNDLE_NAME));
+               osgiBundle.setDescription(getHeaderSafe(bundle,
+                               Constants.BUNDLE_DESCRIPTION));
+               executionContexts.put(osgiBundle, executionContext);
+               if (log.isTraceEnabled())
+                       log.trace("Registered execution context from " + osgiBundle);
+               // Notify
+               ModuleDescriptor md = osgiBundle.getModuleDescriptor();
+               md.setStarted(true);
+               for (ExecutionModulesListener listener : executionModulesListeners)
+                       listener.executionModuleAdded(md);
+       }
+
+       /** Unregisters an execution context. */
+       public synchronized void unregister(ExecutionContext executionContext,
+                       Map<String, String> properties) {
+               // FIXME why are properties null?
+               if (properties == null)
+                       return;
+               OsgiBundle osgiBundle = asOsgiBundle(properties);
+               if (executionContexts.containsKey(osgiBundle)) {
+                       executionContexts.remove(osgiBundle);
+                       if (log.isTraceEnabled())
+                               log.trace("Removed execution context from " + osgiBundle);
+                       // Notify
+                       ModuleDescriptor md = osgiBundle.getModuleDescriptor();
+                       md.setStarted(false);
+                       for (ExecutionModulesListener listener : executionModulesListeners)
+                               listener.executionModuleRemoved(md);
+               }
+       }
+
+       /** Registers an execution flow. */
+       public synchronized void register(ExecutionFlow executionFlow,
+                       Map<String, String> properties) {
+               OsgiBundle osgiBundle = asOsgiBundle(properties);
+               if (!executionFlows.containsKey(osgiBundle)) {
+                       executionFlows.put(osgiBundle, new HashSet<ExecutionFlow>());
+               }
+               executionFlows.get(osgiBundle).add(executionFlow);
+               if (log.isTraceEnabled())
+                       log.trace("Registered " + executionFlow + " from " + osgiBundle);
+
+               // notifications
+               if (registerFlowsToJmx)
+                       registerMBean(osgiBundle, executionFlow);
+               ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle);
+               for (ExecutionModulesListener listener : executionModulesListeners)
+                       listener.executionFlowAdded(osgiBundle.getModuleDescriptor(),
+                                       efdc.getExecutionFlowDescriptor(executionFlow));
+       }
+
+       /** Unregisters an execution flow. */
+       public synchronized void unregister(ExecutionFlow executionFlow,
+                       Map<String, String> properties) {
+               // FIXME why are properties null?
+               if (properties == null)
+                       return;
+               OsgiBundle osgiBundle = asOsgiBundle(properties);
+               if (executionFlows.containsKey(osgiBundle)) {
+                       Set<ExecutionFlow> flows = executionFlows.get(osgiBundle);
+                       flows.remove(executionFlow);
+                       if (log.isTraceEnabled())
+                               log.trace("Removed " + executionFlow + " from " + osgiBundle);
+                       if (flows.size() == 0) {
+                               executionFlows.remove(osgiBundle);
+                               if (log.isTraceEnabled())
+                                       log.trace("Removed flows set from " + osgiBundle);
+                       }
+
+                       // notifications
+                       if (registerFlowsToJmx)
+                               unregisterMBean(osgiBundle, executionFlow);
+                       ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle);
+                       for (ExecutionModulesListener listener : executionModulesListeners)
+                               listener.executionFlowRemoved(osgiBundle.getModuleDescriptor(),
+                                               efdc.getExecutionFlowDescriptor(executionFlow));
+               }
+       }
+
+       /** Registers an execution module listener. */
+       public synchronized void register(
+                       ExecutionModulesListener executionModulesListener,
+                       Map<String, String> properties) {
+               // sync with current state
+               for (OsgiBundle osgiBundle : executionContexts.keySet()) {
+                       executionModulesListener.executionModuleAdded(osgiBundle
+                                       .getModuleDescriptor());
+               }
+               for (OsgiBundle osgiBundle : executionFlows.keySet()) {
+                       ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle);
+                       for (ExecutionFlow executionFlow : executionFlows.get(osgiBundle))
+                               executionModulesListener.executionFlowAdded(
+                                               osgiBundle.getModuleDescriptor(),
+                                               efdc.getExecutionFlowDescriptor(executionFlow));
+               }
+               executionModulesListeners.add(executionModulesListener);
+       }
+
+       /** Unregisters an execution module listener. */
+       public synchronized void unregister(
+                       ExecutionModulesListener executionModulesListener,
+                       Map<String, String> properties) {
+               executionModulesListeners.remove(executionModulesListener);
+       }
+
+       /*
+        * INTERFACE IMPLEMENTATIONS
+        */
+
+       public void bundleChanged(BundleEvent evt) {
+               Bundle bundle = evt.getBundle();
+               if (bundle.getHeaders().get(
+                               ExecutionModuleDescriptor.SLC_EXECUTION_MODULE) != null) {
+                       OsgiBundle osgiBundle = new OsgiBundle(bundle);
+                       if (evt.getType() == BundleEvent.INSTALLED)
+                               for (ExecutionModulesListener listener : executionModulesListeners)
+                                       listener.executionModuleAdded(osgiBundle
+                                                       .getModuleDescriptor());
+                       else if (evt.getType() == BundleEvent.UNINSTALLED)
+                               for (ExecutionModulesListener listener : executionModulesListeners)
+                                       listener.executionModuleRemoved(osgiBundle
+                                                       .getModuleDescriptor());
+               }
+
+       }
+
+       @SuppressWarnings({ "rawtypes" })
+       public synchronized void bind(Object service, Map properties)
+                       throws Exception {
+               if (service instanceof ExecutionFlowDescriptorConverter) {
+                       ExecutionFlowDescriptorConverter executionFlowDescriptorConverter = (ExecutionFlowDescriptorConverter) service;
+                       OsgiBundle osgiBundle = asOsgiBundle(properties);
+                       executionFlowDescriptorConverters.put(osgiBundle,
+                                       executionFlowDescriptorConverter);
+                       if (log.isTraceEnabled())
+                               log.debug("Registered execution flow descriptor converter from "
+                                               + osgiBundle);
+               } else {
+                       // ignore
+               }
+       }
+
+       @SuppressWarnings("rawtypes")
+       public synchronized void unbind(Object service, Map properties)
+                       throws Exception {
+               if (service instanceof ExecutionFlowDescriptorConverter) {
+                       OsgiBundle osgiBundle = asOsgiBundle(properties);
+                       if (executionFlowDescriptorConverters.containsKey(osgiBundle)) {
+                               executionFlowDescriptorConverters.remove(osgiBundle);
+                               if (log.isTraceEnabled())
+                                       log.debug("Removed execution flow descriptor converter from "
+                                                       + osgiBundle);
+                       }
+               } else {
+                       // ignore
+               }
+       }
+
+       /*
+        * JMX
+        */
+       protected MBeanServer getMBeanServer() {
+               return ManagementFactory.getPlatformMBeanServer();
+       }
+
+       public void registerMBean(Module module, ExecutionFlow executionFlow) {
+               try {
+                       StandardMBean mbean = new StandardMBean(executionFlow,
+                                       ExecutionFlow.class);
+                       getMBeanServer().registerMBean(mbean,
+                                       flowMBeanName(module, executionFlow));
+               } catch (Exception e) {
+                       String msg = "Cannot register execution flow " + executionFlow
+                                       + " as mbean";
+                       throw new SlcException(msg, e);
+               }
+       }
+
+       public void unregisterMBean(Module module, ExecutionFlow executionFlow) {
+               try {
+                       getMBeanServer().unregisterMBean(
+                                       flowMBeanName(module, executionFlow));
+               } catch (Exception e) {
+                       String msg = "Cannot unregister execution flow " + executionFlow
+                                       + " as mbean";
+                       throw new SlcException(msg, e);
+               }
+       }
+
+       protected ObjectName flowMBeanName(Module module,
+                       ExecutionFlow executionFlow) {
+               String executionModulesPrefix = "SLCExecutionModules";
+               // String path = executionFlow.getPath();
+               String name = executionFlow.getName();
+               // if (path == null && name.indexOf('/') >= 0) {
+               // path = name.substring(0, name.lastIndexOf('/'));
+               // name = name.substring(name.lastIndexOf('/'));
+               // }
+
+               StringBuffer buf = new StringBuffer(executionModulesPrefix + ":"
+                               + "module=" + module.getName() + " [" + module.getVersion()
+                               + "],");
+
+               // if (path != null && !path.equals("")) {
+               // int depth = 0;
+               // for (String token : path.split("/")) {
+               // if (!token.equals("")) {
+               // buf.append("path").append(depth).append('=');
+               // // in order to have directories first
+               // buf.append('/');
+               // buf.append(token).append(',');
+               // depth++;
+               // }
+               // }
+               // }
+               buf.append("name=").append(name);
+               try {
+                       return new ObjectName(buf.toString());
+               } catch (Exception e) {
+                       throw new SlcException("Cannot generate object name based on "
+                                       + buf, e);
+               }
+       }
+
+       /*
+        * UTILITIES
+        */
+       @SuppressWarnings("rawtypes")
+       private OsgiBundle asOsgiBundle(Map properties) {
+               String bundleSymbolicName = checkAndGet(Constants.BUNDLE_SYMBOLICNAME,
+                               properties);
+               String bundleVersion = checkAndGet(Constants.BUNDLE_VERSION, properties);
+               return new OsgiBundle(bundleSymbolicName, bundleVersion);
+       }
+
+       @SuppressWarnings("rawtypes")
+       private String checkAndGet(Object key, Map properties) {
+               if (!properties.containsKey(key) || properties.get(key) == null)
+                       throw new SlcException(key + " not set in " + properties);
+               else
+                       return properties.get(key).toString();
+       }
+
+       public void setBundlesManager(BundlesManager bundlesManager) {
+               this.bundlesManager = bundlesManager;
+       }
+
+       public void setDefaultDescriptorConverter(
+                       ExecutionFlowDescriptorConverter defaultDescriptorConverter) {
+               this.defaultDescriptorConverter = defaultDescriptorConverter;
+       }
+
+       public void setRegisterFlowsToJmx(Boolean registerFlowsToJmx) {
+               this.registerFlowsToJmx = registerFlowsToJmx;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiExecutionResources.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiExecutionResources.java
new file mode 100644 (file)
index 0000000..306ad07
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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.eclipse.gemini.blueprint.context.BundleContextAware;
+import org.eclipse.gemini.blueprint.io.OsgiBundleResource;
+import org.osgi.framework.BundleContext;
+import org.springframework.core.io.Resource;
+
+/** Write access to resources in an OSGi context */
+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());
+                       // log.debug(framework);
+                       String installArea = System.getProperty("osgi.install.area")
+                                       .substring("file:".length());
+                       // log.debug(installArea);
+                       base = installArea + '/' + relPath;
+                       // 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 (!file.exists())
+                       throw new SlcException(file
+                                       + " was retrieved in bundle located at '" + location
+                                       + "' for resource " + resource + " but it does not exist");
+
+               if (log.isTraceEnabled())
+                       log.debug("OSGi local resource: " + file + " from " + resource);
+               return file;
+       }
+
+       public void setBundleContext(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiRuntime.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/OsgiRuntime.java
new file mode 100644 (file)
index 0000000..8286ecc
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.StreamReadable;
+import org.argeo.slc.UnsupportedException;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.core.build.VersionedResourceDistribution;
+import org.argeo.slc.deploy.DeploymentData;
+import org.argeo.slc.deploy.DynamicRuntime;
+import org.argeo.slc.deploy.TargetData;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+public class OsgiRuntime implements BundleContextAware, ResourceLoaderAware,
+               DynamicRuntime<OsgiBundle> {
+       private String uuid = UUID.randomUUID().toString();
+       private BundleContext bundleContext;
+       private ResourceLoader resourceLoader;
+
+       public List<OsgiBundle> listModules() {
+               List<OsgiBundle> modules = new ArrayList<OsgiBundle>();
+               Bundle[] bundles = bundleContext.getBundles();
+               for (Bundle bundle : bundles) {
+                       OsgiBundle osgiBundle = new OsgiBundle(bundle);
+                       modules.add(osgiBundle);
+                       String location = bundle.getLocation();
+                       if (location != null) {
+                               Resource resource = resourceLoader.getResource(location);
+                               osgiBundle
+                                               .setResourceDistribution(new VersionedResourceDistribution(
+                                                               osgiBundle.getName(), osgiBundle.getVersion(),
+                                                               resource));
+                       }
+               }
+               return modules;
+       }
+
+       public OsgiBundle installModule(Distribution distribution) {
+               if (!(distribution instanceof StreamReadable))
+                       throw new UnsupportedException("distribution", distribution);
+
+               StreamReadable sr = (StreamReadable) distribution;
+               Bundle bundle;
+               try {
+                       bundle = bundleContext.installBundle(sr.toString(), sr
+                                       .getInputStream());
+               } catch (BundleException e) {
+                       throw new SlcException(
+                                       "Cannot install OSGi bundle " + distribution, e);
+               }
+               return new OsgiBundle(bundle);
+       }
+
+       public void updateModule(NameVersion nameVersion) {
+               Bundle bundle = findBundle(nameVersion);
+               try {
+                       bundle.update();
+               } catch (BundleException e) {
+                       throw new SlcException("Cannot update " + bundle, e);
+               }
+       }
+
+       public void uninstallModule(NameVersion nameVersion) {
+               Bundle bundle = findBundle(nameVersion);
+               try {
+                       bundle.uninstall();
+               } catch (BundleException e) {
+                       throw new SlcException("Cannot uninstall " + bundle, e);
+               }
+       }
+
+       public void startModule(NameVersion nameVersion) {
+               Bundle bundle = findBundle(nameVersion);
+               try {
+                       bundle.start();
+                       // TODO: use bundle manager
+               } catch (BundleException e) {
+                       throw new SlcException("Cannot uninstall " + bundle, e);
+               }
+       }
+
+       protected Bundle findBundle(NameVersion nameVersion) {
+               Bundle[] bundles = bundleContext.getBundles();
+               for (Bundle bundle : bundles) {
+                       OsgiBundle osgiBundle = new OsgiBundle(bundle);
+                       if (osgiBundle.equals(nameVersion)) {
+                               return bundle;
+                       }
+               }
+               throw new SlcException("Could not find bundle " + nameVersion);
+       }
+
+       public void shutdown() {
+               // FIXME use framework
+               throw new UnsupportedException();
+       }
+
+       public String getDeployedSystemId() {
+               return uuid;
+       }
+
+       public DeploymentData getDeploymentData() {
+               throw new UnsupportedException();
+       }
+
+       public Distribution getDistribution() {
+               throw new UnsupportedException();
+       }
+
+       public TargetData getTargetData() {
+               throw new UnsupportedException();
+       }
+
+       public void setBundleContext(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+       }
+
+       public void setResourceLoader(ResourceLoader resourceLoader) {
+               this.resourceLoader = resourceLoader;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/AbstractOsgiModularDistribution.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/AbstractOsgiModularDistribution.java
new file mode 100644 (file)
index 0000000..c76659f
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi.build;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.UnsupportedException;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.build.ModularDistribution;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.springframework.beans.factory.InitializingBean;
+
+public abstract class AbstractOsgiModularDistribution implements
+               ModularDistribution, BundleContextAware, InitializingBean {
+       private final static Log log = LogFactory
+                       .getLog(AbstractOsgiModularDistribution.class);
+
+       private BundleContext bundleContext;
+       private EclipseUpdateSite eclipseUpdateSite;
+
+       /** Initialized by the object itself. */
+       private SortedMap<NameVersion, Distribution> distributions = new TreeMap<NameVersion, Distribution>();
+
+       protected abstract void fillDistributions(
+                       SortedMap<NameVersion, Distribution> distributions)
+                       throws Exception;
+
+       public Distribution getModuleDistribution(String moduleName,
+                       String moduleVersion) {
+               return distributions.get(new DefaultNameVersion(moduleName,
+                               moduleVersion));
+       }
+
+       public String getDistributionId() {
+               return bundleContext.getBundle().getSymbolicName()
+                               + "-"
+                               + bundleContext.getBundle().getHeaders()
+                                               .get(Constants.BUNDLE_VERSION);
+       }
+
+       public Set<NameVersion> listModulesNameVersions() {
+               return distributions.keySet();
+       }
+
+       public Iterator<NameVersion> nameVersions() {
+               return distributions.keySet().iterator();
+       }
+
+       public void setBundleContext(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               fillDistributions(distributions);
+               if (log.isDebugEnabled())
+                       log.debug("Distribution " + getName() + ":" + getVersion()
+                                       + " loaded (" + distributions.size() + " modules)");
+       }
+
+       protected String findVersion(String name) {
+               Set<String> versions = new HashSet<String>();
+               for (NameVersion key : distributions.keySet()) {
+                       if (key.getName().equals(name))
+                               versions.add(key.getVersion());
+               }
+
+               if (versions.size() == 0)
+                       throw new SlcException("Cannot find version for name " + name);
+               else if (versions.size() > 1)
+                       throw new SlcException("Found more than one version for name "
+                                       + name + ": " + versions);
+               else
+                       return versions.iterator().next();
+
+       }
+
+       public Object getModulesDescriptor(String descriptorType) {
+               if (descriptorType.equals("eclipse"))
+                       return writeEclipseUpdateSite();
+               else
+                       throw new UnsupportedException("descriptorType", descriptorType);
+       }
+
+       protected Set<NameVersion> writePlainUrlList() {
+               return distributions.keySet();
+       }
+
+       protected String writeEclipseUpdateSite() {
+               if (eclipseUpdateSite == null)
+                       throw new SlcException("No eclipse update site declared.");
+
+               StringBuffer buf = new StringBuffer("");
+               buf.append("<site>");
+
+               List<EclipseUpdateSiteCategory> usedCategories = new ArrayList<EclipseUpdateSiteCategory>();
+               for (EclipseUpdateSiteFeature feature : eclipseUpdateSite.getFeatures()) {
+
+                       String featureId = feature.getName();
+                       String featureVersion = findVersion(featureId);
+                       buf.append("<feature");
+                       buf.append(" url=\"features/").append(featureId).append('_')
+                                       .append(featureVersion).append(".jar\"");
+                       buf.append(" id=\"").append(featureId).append("\"");
+                       buf.append(" version=\"").append(featureVersion).append("\"");
+                       buf.append(">\n");
+
+                       for (EclipseUpdateSiteCategory category : feature.getCategories()) {
+                               usedCategories.add(category);
+                               buf.append("  <category name=\"").append(category.getName())
+                                               .append("\"/>\n");
+                       }
+                       buf.append("</feature>\n\n");
+               }
+
+               for (EclipseUpdateSiteCategory category : usedCategories) {
+                       buf.append("<category-def");
+                       buf.append(" name=\"").append(category.getName()).append("\"");
+                       buf.append(" label=\"").append(category.getLabel()).append("\"");
+                       buf.append(">\n");
+                       buf.append("  <description>").append(category.getDescription())
+                                       .append("</description>\n");
+                       buf.append("</category-def>\n\n");
+               }
+
+               buf.append("</site>");
+               return buf.toString();
+       }
+
+       public String getName() {
+               return bundleContext.getBundle().getSymbolicName();
+       }
+
+       public String getVersion() {
+               return bundleContext.getBundle().getHeaders()
+                               .get(Constants.BUNDLE_VERSION).toString();
+       }
+
+       @Override
+       public String toString() {
+               return new DefaultNameVersion(this).toString();
+       }
+
+       public void setEclipseUpdateSite(EclipseUpdateSite eclipseUpdateSite) {
+               this.eclipseUpdateSite = eclipseUpdateSite;
+       }
+
+       public BundleContext getBundleContext() {
+               return bundleContext;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/BundleModularDistribution.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/BundleModularDistribution.java
new file mode 100644 (file)
index 0000000..db7c7e8
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi.build;
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.SortedMap;
+import java.util.StringTokenizer;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.core.build.VersionedResourceDistribution;
+import org.osgi.framework.Constants;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.ResourceLoader;
+
+public class BundleModularDistribution extends AbstractOsgiModularDistribution
+               implements ResourceLoaderAware {
+       private ResourceLoader resourceLoader;
+
+       private String libDirectory = "/lib";
+
+       protected void fillDistributions(
+                       SortedMap<NameVersion, Distribution> distributions)
+                       throws Exception {
+               Enumeration<URL> urls = (Enumeration<URL>) getBundleContext()
+                               .getBundle().findEntries(libDirectory, "*.jar", false);
+               while (urls.hasMoreElements()) {
+                       URL url = urls.nextElement();
+                       JarInputStream in = null;
+                       try {
+                               in = new JarInputStream(url.openStream());
+                               Manifest mf = in.getManifest();
+                               String name = mf.getMainAttributes().getValue(
+                                               Constants.BUNDLE_SYMBOLICNAME);
+                               // Skip additional specs such as
+                               // ; singleton:=true
+                               if (name.indexOf(';') > -1) {
+                                       name = new StringTokenizer(name, " ;").nextToken();
+                               }
+
+                               String version = mf.getMainAttributes().getValue(
+                                               Constants.BUNDLE_VERSION);
+                               DefaultNameVersion nameVersion = new DefaultNameVersion(name,
+                                               version);
+                               distributions.put(nameVersion,
+                                               new VersionedResourceDistribution(name, version,
+                                                               resourceLoader.getResource(url.toString())));
+                       } finally {
+                               IOUtils.closeQuietly(in);
+                       }
+               }
+       }
+
+       public void setLibDirectory(String libDirectory) {
+               this.libDirectory = libDirectory;
+       }
+
+       public void setResourceLoader(ResourceLoader resourceLoader) {
+               this.resourceLoader = resourceLoader;
+       }
+
+       /*
+        * @SuppressWarnings(value = { "unchecked" }) protected URL
+        * findModule(String moduleName, String version) { Enumeration<URL> urls =
+        * (Enumeration<URL>) bundleContext.getBundle() .findEntries(libDirectory,
+        * moduleName + "*", false);
+        * 
+        * if (!urls.hasMoreElements()) throw new SlcException("Cannot find module "
+        * + moduleName);
+        * 
+        * URL url = urls.nextElement();
+        * 
+        * // TODO: check version as well if (urls.hasMoreElements()) throw new
+        * SlcException("More than one module with name " + moduleName); return url;
+        * }
+        */
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/EclipseUpdateSite.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/EclipseUpdateSite.java
new file mode 100644 (file)
index 0000000..e38d9c0
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi.build;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EclipseUpdateSite {
+       private List<EclipseUpdateSiteFeature> features = new ArrayList<EclipseUpdateSiteFeature>();
+
+       public List<EclipseUpdateSiteFeature> getFeatures() {
+               return features;
+       }
+
+       public void setFeatures(List<EclipseUpdateSiteFeature> features) {
+               this.features = features;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/EclipseUpdateSiteCategory.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/EclipseUpdateSiteCategory.java
new file mode 100644 (file)
index 0000000..c716562
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi.build;
+
+public class EclipseUpdateSiteCategory {
+       private String name;
+       private String label;
+       private String description;
+
+       public String getLabel() {
+               return label;
+       }
+
+       public void setLabel(String label) {
+               this.label = label;
+       }
+
+       public String getDescription() {
+               return description;
+       }
+
+       public void setDescription(String description) {
+               this.description = description;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/EclipseUpdateSiteFeature.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/EclipseUpdateSiteFeature.java
new file mode 100644 (file)
index 0000000..f28c0cb
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi.build;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EclipseUpdateSiteFeature {
+       private String name;
+       private List<EclipseUpdateSiteCategory> categories = new ArrayList<EclipseUpdateSiteCategory>();
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public List<EclipseUpdateSiteCategory> getCategories() {
+               return categories;
+       }
+
+       public void setCategories(List<EclipseUpdateSiteCategory> categories) {
+               this.categories = categories;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/OsgiRuntimeModularDistribution.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/build/OsgiRuntimeModularDistribution.java
new file mode 100644 (file)
index 0000000..5523e6e
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi.build;
+
+import java.net.URL;
+import java.util.SortedMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.core.build.VersionedResourceDistribution;
+import org.argeo.slc.osgi.OsgiBundle;
+import org.eclipse.gemini.blueprint.util.OsgiBundleUtils;
+import org.osgi.framework.Bundle;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+public class OsgiRuntimeModularDistribution extends
+               AbstractOsgiModularDistribution implements ResourceLoaderAware {
+       private final static Log log = LogFactory
+                       .getLog(OsgiRuntimeModularDistribution.class);
+
+       private ResourceLoader resourceLoader;
+
+       protected void fillDistributions(
+                       SortedMap<NameVersion, Distribution> distributions)
+                       throws Exception {
+
+               String frameworkUrl = System.getProperty("osgi.framework");
+               String frameworkBaseUrl = null;
+               if (frameworkUrl != null)
+                       frameworkBaseUrl = frameworkUrl.substring(0, frameworkUrl
+                                       .lastIndexOf('/'));
+               bundles: for (Bundle bundle : getBundleContext().getBundles()) {
+                       OsgiBundle osgiBundle = new OsgiBundle(bundle);
+
+                       String originalLocation = bundle.getLocation();
+
+                       if (OsgiBundleUtils.isSystemBundle(bundle)) {
+                               continue bundles;
+                       }
+
+                       String location = originalLocation;
+                       if (originalLocation.startsWith("reference:file:"))
+                               location = originalLocation.substring("reference:".length());
+
+                       if (frameworkBaseUrl != null
+                                       && originalLocation.startsWith("initial@reference:file:")) {
+                               location = frameworkBaseUrl
+                                               + '/'
+                                               + originalLocation.substring("initial@reference:file:"
+                                                               .length());
+                       }
+
+                       try {
+                               URL url = new URL(location);
+                               Resource res = resourceLoader.getResource(url.toString());
+                               distributions.put(osgiBundle,
+                                               new VersionedResourceDistribution(osgiBundle, res));
+
+                               if (log.isTraceEnabled())
+                                       log.debug("Added url " + url + " from original location "
+                                                       + originalLocation);
+                       } catch (Exception e) {
+                               log.warn("Cannot interpret location " + location
+                                               + " of bundle " + bundle + ": " + e);
+                       }
+               }
+       }
+
+       public void setResourceLoader(ResourceLoader resourceLoader) {
+               this.resourceLoader = resourceLoader;
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/deploy/OsgiResourceSet.java b/org.argeo.slc.spring/src/org/argeo/slc/osgi/deploy/OsgiResourceSet.java
new file mode 100644 (file)
index 0000000..2414788
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.osgi.deploy;
+
+import org.argeo.slc.core.deploy.DefaultResourceSet;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+import org.eclipse.gemini.blueprint.io.OsgiBundleResourceLoader;
+import org.eclipse.gemini.blueprint.io.OsgiBundleResourcePatternResolver;
+import org.eclipse.gemini.blueprint.util.OsgiBundleUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.springframework.core.io.ResourceLoader;
+
+/**
+ * Retrieves ressources from an OSGi bundle either the active one or another one
+ * referenced by its symbolic name.
+ */
+public class OsgiResourceSet extends DefaultResourceSet implements
+               BundleContextAware {
+       private BundleContext bundleContext;
+       private Bundle bundle = null;
+       private String bundleSymbolicName = null;
+
+       private OsgiBundleResourceLoader osgiBundleResourceLoader = null;
+
+       @Override
+       public void afterPropertiesSet() throws Exception {
+               osgiBundleResourceLoader = new OsgiBundleResourceLoader(getBundle());
+               if (getResourcePatternResolver() == null)
+                       setResourcePatternResolver(new OsgiBundleResourcePatternResolver(
+                                       osgiBundleResourceLoader));
+               super.afterPropertiesSet();
+       }
+
+       public Bundle getBundle() {
+               if (bundle != null)
+                       return bundle;
+               else if (bundleSymbolicName != null)// do not cache
+                       return OsgiBundleUtils.findBundleBySymbolicName(bundleContext,
+                                       bundleSymbolicName);
+               else
+                       // containing bundle
+                       return bundleContext.getBundle();
+       }
+
+       public void setBundleContext(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+       }
+
+       @Override
+       public ResourceLoader getResourceLoaderToUse() {
+               return osgiBundleResourceLoader;
+       }
+
+       public void setBundle(Bundle bundle) {
+               this.bundle = bundle;
+       }
+
+       public void setBundleSymbolicName(String bundleSymbolicName) {
+               this.bundleSymbolicName = bundleSymbolicName;
+       }
+
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/osgi/execution.xml b/org.argeo.slc.spring/src/org/argeo/slc/osgi/execution.xml
new file mode 100644 (file)
index 0000000..cc0aac0
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007-2012 Argeo GmbH Licensed under the Apache License, 
+       Version 2.0 (the "License"); you may not use this file except in compliance 
+       with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
+       Unless required by applicable law or agreed to in writing, software distributed 
+       under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
+       OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
+       the specific language governing permissions and limitations under the License. -->
+<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under 
+       the Apache License, Version 2.0 (the "License"); you may not use this file 
+       except in compliance with the License. You may obtain a copy of the License 
+       at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
+       law or agreed to in writing, software distributed under the License is distributed 
+       on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
+       express or implied. See the License for the specific language governing permissions 
+       and limitations under the License. -->
+
+<beans xmlns:osgi="http://www.springframework.org/schema/osgi"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"
+       xsi:schemaLocation="http://www.springframework.org/schema/osgi  
+       http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd
+       http://www.springframework.org/schema/beans   
+       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+       <osgi:service interface="org.argeo.slc.execution.ExecutionContext"
+               ref="executionContext" />
+       <osgi:service
+               interface="org.argeo.slc.execution.ExecutionFlowDescriptorConverter"
+               ref="executionFlowDescriptorConverter" />
+
+       <osgi:reference id="callbackHandler"
+               interface="javax.security.auth.callback.CallbackHandler" cardinality="0..1" />
+
+       <bean class="org.argeo.slc.osgi.MultipleServiceExporterPostProcessor">
+               <property name="interfaces">
+                       <list>
+                               <value><![CDATA[org.argeo.slc.execution.ExecutionFlow]]></value>
+                       </list>
+               </property>
+               <property name="bundleContext" ref="bundleContext" />
+       </bean>
+
+       <bean id="osgiExecutionResources" class="org.argeo.slc.osgi.OsgiExecutionResources">
+               <property name="executionContext" ref="executionContext" />
+       </bean>
+</beans>
\ No newline at end of file
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/spring/AbstractSystemExecution.java b/org.argeo.slc.spring/src/org/argeo/slc/spring/AbstractSystemExecution.java
new file mode 100644 (file)
index 0000000..7813b9a
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.spring;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.node.NodeConstants;
+import org.argeo.slc.SlcException;
+
+/** Provides base method for executing code with system authorization. */
+abstract class AbstractSystemExecution {
+       private final static Log log = LogFactory.getLog(AbstractSystemExecution.class);
+       private final Subject subject = new Subject();
+
+       /** Authenticate the calling thread */
+       protected void authenticateAsSystem() {
+               ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader();
+               Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+               try {
+                       LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN, subject);
+                       lc.login();
+               } catch (LoginException e) {
+                       throw new SlcException("Cannot login as system", e);
+               } finally {
+                       Thread.currentThread().setContextClassLoader(origClassLoader);
+               }
+               if (log.isTraceEnabled())
+                       log.trace("System authenticated");
+       }
+
+       protected void deauthenticateAsSystem() {
+               ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader();
+               Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+               try {
+                       LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN, subject);
+                       lc.logout();
+               } catch (LoginException e) {
+                       throw new SlcException("Cannot logout as system", e);
+               } finally {
+                       Thread.currentThread().setContextClassLoader(origClassLoader);
+               }
+       }
+
+       protected Subject getSubject() {
+               return subject;
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/spring/AuthenticatedApplicationContextInitialization.java b/org.argeo.slc.spring/src/org/argeo/slc/spring/AuthenticatedApplicationContextInitialization.java
new file mode 100644 (file)
index 0000000..68a9cc9
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.spring;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.gemini.blueprint.context.DependencyInitializationAwareBeanPostProcessor;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.support.AbstractBeanFactory;
+import org.springframework.beans.factory.support.SecurityContextProvider;
+import org.springframework.beans.factory.support.SimpleSecurityContextProvider;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+/**
+ * Executes with a system authentication the instantiation and initialization
+ * methods of the application context where it has been defined.
+ */
+public class AuthenticatedApplicationContextInitialization extends
+               AbstractSystemExecution implements
+               DependencyInitializationAwareBeanPostProcessor, ApplicationContextAware {
+       /** If non empty, restricts to these beans */
+       private List<String> beanNames = new ArrayList<String>();
+
+       public Object postProcessBeforeInitialization(Object bean, String beanName)
+                       throws BeansException {
+               if (beanNames.size() == 0 || beanNames.contains(beanName))
+                       authenticateAsSystem();
+               return bean;
+       }
+
+       public Object postProcessAfterInitialization(Object bean, String beanName)
+                       throws BeansException {
+               if (beanNames.size() == 0 || beanNames.contains(beanName))
+                       deauthenticateAsSystem();
+               return bean;
+       }
+
+       public void setBeanNames(List<String> beanNames) {
+               this.beanNames = beanNames;
+       }
+
+       @Override
+       public void setApplicationContext(ApplicationContext applicationContext)
+                       throws BeansException {
+               if (applicationContext.getAutowireCapableBeanFactory() instanceof AbstractBeanFactory) {
+                       final AbstractBeanFactory beanFactory = ((AbstractBeanFactory) applicationContext
+                                       .getAutowireCapableBeanFactory());
+                       // retrieve subject's access control context
+                       // and set it as the bean factory security context
+                       Subject.doAs(getSubject(), new PrivilegedAction<Void>() {
+                               @Override
+                               public Void run() {
+                                       SecurityContextProvider scp = new SimpleSecurityContextProvider(
+                                                       AccessController.getContext());
+                                       beanFactory.setSecurityContextProvider(scp);
+                                       return null;
+                               }
+                       });
+               }
+       }
+}
diff --git a/pom.xml b/pom.xml
index 572202b33f9680850fd8b63a6e0b17d17be25ddd..6cee4d3e1dc12587da01f794fb1a2a0b147bd5f8 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                <version.argeo-commons-legacy>2.1.86-SNAPSHOT</version.argeo-commons-legacy>
        </properties>
        <modules>
-               <!-- Runtime -->
                <module>org.argeo.slc.api</module>
-               <module>org.argeo.slc.core</module>
+
+               <!-- Runtime -->
+               <module>org.argeo.slc.spring</module>
                <module>org.argeo.slc.unit</module>
                <module>org.argeo.slc.support</module>
                <module>org.argeo.slc.repo</module>