Merge JCR, OSGi and Ant support into SLC Core
authorMathieu Baudier <mbaudier@argeo.org>
Fri, 13 Feb 2015 09:25:26 +0000 (09:25 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Fri, 13 Feb 2015 09:25:26 +0000 (09:25 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@7837 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

75 files changed:
org.argeo.slc.core/bin/log4j.properties [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/deploy/DefaultResourceSetTest.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/deploy/data/file1.txt [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/deploy/data/subdir/file2.txt [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/deploy/relativeResourceSet.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/AbstractExecutionFlowTestCase.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/BasicExecutionFlowTest.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/DefaultAgentCliTest.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/ExceptionIfInitCalledTwice.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/FileExecutionResourcesSpringTest.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/FileExecutionResourcesTest.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/ParameterRefTest.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/applicationContext.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/canonic-001.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/canonic-002.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/canonic-003.error.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/canonic-004.error.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/canonic.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/executionResources.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/imports.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/listSetMap.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/listSetMapMultipleFlow.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/minimal.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/multipleFlow.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/parameterRef.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/placeHolders.cascading.exec.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/placeHolders.cascading.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/specOverriding.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/tasks/SystemCallTest.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/tasks/systemCall.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/test.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/xml/FlowNamespaceTest.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/xml/advanced.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/xml/canonic-ns-001.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/xml/canonic-ns-002.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/xml/canonic-ns.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/xml/containers.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/execution/xml/tests.xml [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/test/context/AbstractInternalSpringTestCase.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/test/context/ContextTest.class [deleted file]
org.argeo.slc.core/bin/org/argeo/slc/core/test/context/applicationContext.xml [deleted file]
org.argeo.slc.core/bnd.bnd
org.argeo.slc.core/src/org/argeo/slc/ant/AntFlowGenerator.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/ant/AntRun.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/JcrMetadataWriter.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/JcrTestResult.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrConstants.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrResultUtils.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/SlcJcrUtils.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/SlcNames.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/SlcTypes.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrAgent.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrAttachmentUploader.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrExecutionProcess.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrProcessThread.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrRealizedFlow.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/jcr/slc.cnd [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/BundleRegister.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/BundlesManager.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/FileSystemBundleRegister.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiBundle.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionModule.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionModulesManager.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionResources.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiRuntime.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/AbstractOsgiModularDistribution.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/BundleModularDistribution.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSite.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSiteCategory.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/EclipseUpdateSiteFeature.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/build/OsgiRuntimeModularDistribution.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/deploy/OsgiResourceSet.java [new file with mode: 0644]
org.argeo.slc.core/src/org/argeo/slc/osgi/execution.xml [new file with mode: 0644]

diff --git a/org.argeo.slc.core/bin/log4j.properties b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/deploy/DefaultResourceSetTest.class b/org.argeo.slc.core/bin/org/argeo/slc/core/deploy/DefaultResourceSetTest.class
deleted file mode 100644 (file)
index 296f6ef..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/deploy/DefaultResourceSetTest.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/deploy/data/file1.txt b/org.argeo.slc.core/bin/org/argeo/slc/core/deploy/data/file1.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/deploy/data/subdir/file2.txt b/org.argeo.slc.core/bin/org/argeo/slc/core/deploy/data/subdir/file2.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/deploy/relativeResourceSet.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/AbstractExecutionFlowTestCase.class b/org.argeo.slc.core/bin/org/argeo/slc/core/execution/AbstractExecutionFlowTestCase.class
deleted file mode 100644 (file)
index 8fdcba1..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/AbstractExecutionFlowTestCase.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/BasicExecutionFlowTest.class b/org.argeo.slc.core/bin/org/argeo/slc/core/execution/BasicExecutionFlowTest.class
deleted file mode 100644 (file)
index 6a1b817..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/BasicExecutionFlowTest.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/DefaultAgentCliTest.class b/org.argeo.slc.core/bin/org/argeo/slc/core/execution/DefaultAgentCliTest.class
deleted file mode 100644 (file)
index a1e3b70..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/DefaultAgentCliTest.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/ExceptionIfInitCalledTwice.class b/org.argeo.slc.core/bin/org/argeo/slc/core/execution/ExceptionIfInitCalledTwice.class
deleted file mode 100644 (file)
index e555323..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/ExceptionIfInitCalledTwice.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/FileExecutionResourcesSpringTest.class b/org.argeo.slc.core/bin/org/argeo/slc/core/execution/FileExecutionResourcesSpringTest.class
deleted file mode 100644 (file)
index 59737ac..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/FileExecutionResourcesSpringTest.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/FileExecutionResourcesTest.class b/org.argeo.slc.core/bin/org/argeo/slc/core/execution/FileExecutionResourcesTest.class
deleted file mode 100644 (file)
index 6371da2..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/FileExecutionResourcesTest.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/ParameterRefTest.class b/org.argeo.slc.core/bin/org/argeo/slc/core/execution/ParameterRefTest.class
deleted file mode 100644 (file)
index f0913e5..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/ParameterRefTest.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/applicationContext.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/canonic-001.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/canonic-002.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/canonic-003.error.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/canonic-004.error.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/canonic.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/executionResources.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/imports.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/listSetMap.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/listSetMapMultipleFlow.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/minimal.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/multipleFlow.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/parameterRef.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/placeHolders.cascading.exec.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/placeHolders.cascading.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/specOverriding.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/tasks/SystemCallTest.class b/org.argeo.slc.core/bin/org/argeo/slc/core/execution/tasks/SystemCallTest.class
deleted file mode 100644 (file)
index fe381e4..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/tasks/SystemCallTest.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/tasks/systemCall.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/test.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/xml/FlowNamespaceTest.class b/org.argeo.slc.core/bin/org/argeo/slc/core/execution/xml/FlowNamespaceTest.class
deleted file mode 100644 (file)
index 3e0cd7c..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/xml/FlowNamespaceTest.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/execution/xml/advanced.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/xml/canonic-ns-001.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/xml/canonic-ns-002.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/xml/canonic-ns.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/xml/containers.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/execution/xml/tests.xml b/org.argeo.slc.core/bin/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/bin/org/argeo/slc/core/test/context/AbstractInternalSpringTestCase.class b/org.argeo.slc.core/bin/org/argeo/slc/core/test/context/AbstractInternalSpringTestCase.class
deleted file mode 100644 (file)
index 0cad464..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/test/context/AbstractInternalSpringTestCase.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/test/context/ContextTest.class b/org.argeo.slc.core/bin/org/argeo/slc/core/test/context/ContextTest.class
deleted file mode 100644 (file)
index 4146eca..0000000
Binary files a/org.argeo.slc.core/bin/org/argeo/slc/core/test/context/ContextTest.class and /dev/null differ
diff --git a/org.argeo.slc.core/bin/org/argeo/slc/core/test/context/applicationContext.xml b/org.argeo.slc.core/bin/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
index 40b504bd2afa9c2237cd6d24cea0600261075443..3c198f97f2dd65bca021e2f20e64474dce0c786f 100644 (file)
@@ -1,8 +1,4 @@
-Import-Package: org.w3c.dom;version="0.0.0",\
-org.dbunit;resolution:="optional",\
-org.dbunit.database;resolution:="optional",\
-org.dbunit.dataset;resolution:="optional",\
-org.dbunit.dataset.xml;resolution:="optional",\
-org.dbunit.operation;resolution:="optional",\
+Import-Package: javax.jcr.nodetype,\
+org.apache.tools.ant.*;resolution:="optional",\
 junit.framework;resolution:="optional",\
 *
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
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.core/src/org/argeo/slc/ant/AntRun.java b/org.argeo.slc.core/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.core/src/org/argeo/slc/jcr/JcrMetadataWriter.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/JcrMetadataWriter.java
new file mode 100644 (file)
index 0000000..19db9cb
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+/**
+ * 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
new file mode 100644 (file)
index 0000000..e3394e0
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * 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.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
new file mode 100644 (file)
index 0000000..179a081
--- /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.jcr;
+
+/** 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
new file mode 100644 (file)
index 0000000..729c2d7
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * 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.jcr.UserJcrUtils;
+import org.argeo.slc.SlcException;
+
+/**
+ * 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 = UserJcrUtils.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 = UserJcrUtils.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
new file mode 100644 (file)
index 0000000..5c00bcf
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * 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.jcr.UserJcrUtils;
+import org.argeo.slc.BasicNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+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 BasicNameVersion(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 = UserJcrUtils.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/SlcNames.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/SlcNames.java
new file mode 100644 (file)
index 0000000..15213fc
--- /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.jcr;
+
+/** JCR names used by SLC */
+public interface SlcNames {
+       public final static String SLC_ = "slc:";
+
+       /*
+        * GENERAL
+        */
+       public final static String SLC_UUID = "slc:uuid";
+       public final static String SLC_STATUS = "slc:status";
+       // generic name for result parts of a given test result (slc:testResult)
+       // note that corresponding nodes can be retrieved using
+       // myTestResultNode.getNodes(SLC_RESULT_PART+"*") method
+       public final static String SLC_RESULT_PART = "slc:resultPart";
+       // Fixed name of the child node of a slc:testResult of type
+       // slc:check that aggregate status of all result parts of a given test
+       // result
+       public final static String SLC_AGGREGATED_STATUS = "slc:aggregatedStatus";
+
+       public final static String SLC_TYPE = "slc:type";
+       public final static String SLC_NAME = "slc:name";
+       public final static String SLC_VERSION = "slc:version";
+       public final static String SLC_CATEGORY = "slc:category";
+       public final static String SLC_VALUE = "slc:value";
+       public final static String SLC_ADDRESS = "slc:address";
+       public final static String SLC_METADATA = "slc:metadata";
+
+       public final static String SLC_TIMESTAMP = "slc:timestamp";
+       public final static String SLC_STARTED = "slc:started";
+       public final static String SLC_COMPLETED = "slc:completed";
+
+       public final static String SLC_VM = "slc:vm";
+       /*
+        * SLC RUNTIME
+        */
+       // execution
+       public final static String SLC_SPEC = "slc:spec";
+       public final static String SLC_EXECUTION_SPECS = "slc:executionSpecs";
+       public final static String SLC_FLOW = "slc:flow";
+       public final static String SLC_LOG = "slc:log";
+       public final static String SLC_AGENTS = "slc:agents";
+
+       // spec attribute
+       public final static String SLC_IS_IMMUTABLE = "slc:isImmutable";
+       public final static String SLC_IS_CONSTANT = "slc:isConstant";
+       public final static String SLC_IS_HIDDEN = "slc:isHidden";
+
+       // base directories
+       public final static String SLC_SYSTEM = "slc:system";
+       public final static String SLC_RESULTS = "slc:results";
+       public final static String SLC_MY_RESULTS = "slc:myResults";
+       public final static String SLC_PROCESSES = "slc:processes";
+
+       // result
+       public final static String SLC_SUCCESS = "slc:success";
+       public final static String SLC_MESSAGE = "slc:message";
+       public final static String SLC_TAG = "slc:tag";
+       public final static String SLC_ERROR_MESSAGE = "slc:errorMessage";
+       public final static String SLC_TEST_CASE = "slc:testCase";
+       public final static String SLC_TEST_CASE_TYPE = "slc:testCaseType";
+
+       // diff result
+       public final static String SLC_SUMMARY = "slc:summary";
+       public final static String SLC_ISSUES = "slc:issues";
+
+       /*
+        * SLC REPO
+        */
+       // shared
+       public final static String SLC_URL = "slc:url";
+       public final static String SLC_OPTIONAL = "slc:optional";
+       public final static String SLC_AS_STRING = "slc:asString";
+
+       // origin
+       public final static String SLC_ORIGIN = "slc:origin";
+       public final static String SLC_PROXY = "slc:proxy";
+
+       // slc:artifact
+       public final static String SLC_ARTIFACT_ID = "slc:artifactId";
+       public final static String SLC_GROUP_ID = "slc:groupId";
+       public final static String SLC_GROUP_BASE_ID = "slc:groupBaseId";
+       public final static String SLC_ARTIFACT_VERSION = "slc:artifactVersion";
+       public final static String SLC_ARTIFACT_EXTENSION = "slc:artifactExtension";
+       public final static String SLC_ARTIFACT_CLASSIFIER = "slc:artifactClassifier";
+
+       // slc:jarArtifact
+       public final static String SLC_MANIFEST = "slc:manifest";
+
+       // shared OSGi
+       public final static String SLC_SYMBOLIC_NAME = "slc:symbolic-name";
+       public final static String SLC_BUNDLE_VERSION = "slc:bundle-version";
+
+       // slc:osgiBaseVersion
+       public final static String SLC_MAJOR = "slc:major";
+       public final static String SLC_MINOR = "slc:minor";
+       public final static String SLC_MICRO = "slc:micro";
+       // slc:osgiVersion
+       public final static String SLC_QUALIFIER = "slc:qualifier";
+
+       // slc:exportedPackage
+       public final static String SLC_USES = "slc:uses";
+
+       // slc:modularDistribution
+       public final static String SLC_MODULES = "slc:modules";
+
+       // RPM
+       // slc:rpm
+       public final static String SLC_RPM_VERSION = "slc:rpmVersion";
+       public final static String SLC_RPM_RELEASE = "slc:rpmRelease";
+       public final static String SLC_RPM_ARCH = "slc:rpmArch";
+       public final static String SLC_RPM_ARCHIVE_SIZE = "slc:rpmArchiveSize";
+}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/jcr/SlcTypes.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/SlcTypes.java
new file mode 100644 (file)
index 0000000..5cb6a13
--- /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.jcr;
+
+/** JCR node types used by SLC */
+public interface SlcTypes {
+
+       public final static String SLC_NAME_VERSION = "slc:nameVersion";
+       public final static String SLC_CATEGORIZED_NAME_VERSION = "slc:categorizedNameVersion";
+
+       public final static String SLC_AGENT_FACTORY = "slc:agentFactory";
+       public final static String SLC_AGENT = "slc:agent";
+       public final static String SLC_MODULE = "slc:module";
+       public final static String SLC_EXECUTION_MODULE = "slc:executionModule";
+       public final static String SLC_EXECUTION_SPEC = "slc:executionSpec";
+       public final static String SLC_EXECUTION_FLOW = "slc:executionFlow";
+       public final static String SLC_PROCESS = "slc:process";
+       public final static String SLC_REALIZED_FLOW = "slc:realizedFlow";
+
+       public final static String SLC_EXECUTION_SPEC_ATTRIBUTE = "slc:executionSpecAttribute";
+       public final static String SLC_PRIMITIVE_SPEC_ATTRIBUTE = "slc:primitiveSpecAttribute";
+       public final static String SLC_REF_SPEC_ATTRIBUTE = "slc:refSpecAttribute";
+
+       public final static String SLC_TEST_RESULT = "slc:testResult";
+       public final static String SLC_CHECK = "slc:check";
+       public final static String SLC_PROPERTY = "slc:property";
+       public final static String SLC_DIFF_RESULT = "slc:diffResult";
+
+       // Node types used for user defined and managed result UI tree
+       public final static String SLC_MY_RESULT_ROOT_FOLDER = "slc:myResultRootFolder";
+       public final static String SLC_RESULT_FOLDER = "slc:resultFolder";
+
+       // Log levels
+       public final static String SLC_LOG_ENTRY = "slc:logEntry";
+       public final static String SLC_LOG_TRACE = "slc:logTrace";
+       public final static String SLC_LOG_DEBUG = "slc:logDebug";
+       public final static String SLC_LOG_INFO = "slc:logInfo";
+       public final static String SLC_LOG_WARNING = "slc:logWarning";
+       public final static String SLC_LOG_ERROR = "slc:logError";
+
+       /*
+        * REPO
+        */
+       public final static String SLC_ARTIFACT = "slc:artifact";
+       public final static String SLC_ARTIFACT_VERSION_BASE = "slc:artifactVersion";
+       public final static String SLC_ARTIFACT_BASE = "slc:artifactBase";
+       public final static String SLC_GROUP_BASE = "slc:groupBase";
+       public final static String SLC_JAR_FILE = "slc:jarFile";
+       public final static String SLC_BUNDLE_ARTIFACT = "slc:bundleArtifact";
+       public final static String SLC_OSGI_VERSION = "slc:osgiVersion";
+       public final static String SLC_JAVA_PACKAGE = "slc:javaPackage";
+       public final static String SLC_EXPORTED_PACKAGE = "slc:exportedPackage";
+       public final static String SLC_IMPORTED_PACKAGE = "slc:importedPackage";
+       public final static String SLC_DYNAMIC_IMPORTED_PACKAGE = "slc:dynamicImportedPackage";
+       public final static String SLC_REQUIRED_BUNDLE = "slc:requiredBundle";
+       public final static String SLC_FRAGMENT_HOST = "slc:fragmentHost";
+
+       // Distribution management
+       // public final static String SLC_CATEGORY = "slc:category";
+       public final static String SLC_MODULAR_DISTRIBUTION_BASE = "slc:modularDistributionBase";
+       public final static String SLC_MODULAR_DISTRIBUTION = "slc:modularDistribution";
+       public final static String SLC_MODULE_COORDINATES = "slc:moduleCoordinates";
+
+       // origin
+       public final static String SLC_KNOWN_ORIGIN = "slc:knownOrigin";
+       public final static String SLC_PROXIED = "slc:proxied";
+
+       // rpm
+       public final static String SLC_RPM = "slc:rpm";
+}
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
new file mode 100644 (file)
index 0000000..1c00b47
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * 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 org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+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;
+import org.argeo.slc.jcr.SlcNames;
+import org.argeo.slc.jcr.SlcTypes;
+
+/** 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);
+                       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
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.core/src/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java b/org.argeo.slc.core/src/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java
new file mode 100644 (file)
index 0000000..ea734a8
--- /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.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;
+import org.argeo.slc.jcr.SlcNames;
+import org.argeo.slc.jcr.SlcTypes;
+
+/**
+ * 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
new file mode 100644 (file)
index 0000000..180d8f0
--- /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.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;
+import org.argeo.slc.jcr.SlcNames;
+import org.argeo.slc.jcr.SlcTypes;
+
+/** 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
new file mode 100644 (file)
index 0000000..8755829
--- /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.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+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;
+import org.argeo.slc.jcr.SlcNames;
+
+/** 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 ArgeoException("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
new file mode 100644 (file)
index 0000000..2dd56e3
--- /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.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;
+import org.argeo.slc.jcr.SlcNames;
+import org.argeo.slc.jcr.SlcTypes;
+
+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/jcr/slc.cnd b/org.argeo.slc.core/src/org/argeo/slc/jcr/slc.cnd
new file mode 100644 (file)
index 0000000..6e23cf5
--- /dev/null
@@ -0,0 +1,139 @@
+<slc = 'http://www.argeo.org/ns/slc'>
+
+// COMMON
+[slc:nameVersion] > nt:base
+mixin
+- slc:name (STRING) m
+- slc:version (STRING) m
+
+[slc:categorizedNameVersion] > slc:nameVersion
+mixin
+// define as mandatory?
+- slc:category (STRING)
+
+// AGENT
+[slc:agentFactory] > nt:unstructured, mix:title
++ * (slc:agent)
+
+[slc:agent] > nt:unstructured, mix:title
++ * (slc:module)
+
+[slc:module] > slc:nameVersion, mix:title
+mixin
+
+[slc:activableModule] > slc:module
+mixin
+
+[slc:executionModule] > slc:activableModule
+mixin
+
+[slc:executionSpec] > nt:unstructured, mix:referenceable, mix:title
+- slc:name (STRING) m
++ * (slc:executionSpecAttribute) *
+
+[slc:executionSpecAttribute] > nt:base
+mixin abstract
+- slc:isImmutable (BOOLEAN) 
+- slc:isConstant (BOOLEAN) 
+- slc:isHidden (BOOLEAN) 
+
+[slc:primitiveSpecAttribute] > slc:executionSpecAttribute
+mixin
+- slc:type (STRING) 
+- slc:value (UNDEFINED)
+
+[slc:refSpecAttribute] > slc:executionSpecAttribute
+orderable
+mixin
+// typically a class name
+- slc:type (STRING)
+- slc:value (UNDEFINED)
++ * (mix:title)
+
+[slc:executionFlow] > nt:unstructured, mix:title
+- slc:name (STRING) ! m
+// if the execution spec is a referenceable node
+- slc:spec (REFERENCE)
+// if the execution spec is internal (without name)
++ * (slc:executionSpecAttribute) *
+
+// PROCESS
+[slc:process] > nt:unstructured, mix:created, mix:lastModified
+orderable
+- slc:uuid (STRING) ! m
+- slc:status (STRING) m
++ slc:flow (slc:realizedFlow)
++ slc:log
+
+// The first part of the relative path is the thread name, rest is location
+[slc:logEntry] > nt:unstructured
+abstract
+- slc:message (STRING) !
+- slc:timestamp (STRING)
+
+// Log levels are set via types.
+// Querying one level also queries the higher levels thanks to the inheritance
+// e.g. 'select * from [slc:logWarn]' also returns errors 
+[slc:logTrace] > slc:logEntry
+
+[slc:logDebug] > slc:logTrace
+
+[slc:logInfo] > slc:logDebug
+
+[slc:logWarning] > slc:logInfo
+
+[slc:logError] > slc:logWarning
+
+[slc:realizedFlow] > nt:base
+orderable
+mixin
+// the name of the flow
+// - slc:flow (STRING)
+// the name of the execution spec
+// - slc:spec (STRING)
+- slc:started (DATE)
+- slc:completed (DATE)
+//- slc:status (STRING)
++ slc:address (nt:address)
++ slc:flow (slc:realizedFlow) *
+// the realized execution spec attributes
++ * (slc:executionSpecAttribute) *
+
+// RESULT
+[slc:testResult] > nt:unstructured, mix:created, mix:lastModified
+- slc:uuid (STRING) ! m
+- slc:testCase (STRING)
+- slc:completed (DATE)
+// Helper to keep a centralize place to have testResultStatus
+// when adding more than one result part to a given testResult 
++ slc:aggregatedStatus (slc:check)
+// DEPRECATED - FOR COMPATIBILITY - DO NOT USE
++ slc:testStatus (slc:check)
+
+[slc:diffResult] > slc:testResult
++ slc:summary
++ slc:issues
+
+[slc:resultFolder] > nt:unstructured
++ slc:folderStatus (slc:check)
++ * (slc:resultFolder) *
++ * (slc:testResult) *
+
+// base node for user defined and managed result tree
+// simplify UI management
+[slc:myResultRootFolder] > nt:unstructured
++ * (slc:resultFolder) *
++ * (slc:testResult) *
+
+[slc:check] > nt:unstructured
+// true for PASSED, false for FAILED or ERROR
+- slc:success (BOOLEAN) ! m
+- slc:message (STRING)
+// ERROR if set, the check could not be performed because of an unexpected exception
+- slc:errorMessage (STRING)
+// to ease transition with legacy approach
++ * (slc:property) *
+
+[slc:property] > nt:unstructured
+- slc:name (STRING) ! m
+- slc:value (STRING) m
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
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.core/src/org/argeo/slc/osgi/BundlesManager.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/BundlesManager.java
new file mode 100644 (file)
index 0000000..8c975ee
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+ * 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.SlcException;
+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.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.springframework.util.Assert;
+
+/** Wraps low-level access to a {@link BundleContext} */
+public class BundlesManager implements BundleContextAware, FrameworkListener,
+               InitializingBean, DisposableBean, OsgiBundleApplicationContextListener {
+       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
+                       ServiceReference[] srs = getServiceRefSynchronous(
+                                       ApplicationContext.class.getName(), filter);
+                       ServiceReference sr = srs[0];
+                       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 packageAdminRef = bundleContext
+                               .getServiceReference(PackageAdmin.class.getName());
+               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 ServiceReference[] getServiceRefSynchronous(String clss,
+                       String filter) throws InvalidSyntaxException {
+               if (log.isTraceEnabled())
+                       log.debug("Filter: '" + filter + "'");
+               ServiceReference[] 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 ServiceTracker newTracker(Class<?> clss) {
+               ServiceTracker st = new ServiceTracker(bundleContext, clss.getName(),
+                               null);
+               st.open();
+               return st;
+       }
+
+       @SuppressWarnings(value = { "unchecked" })
+       public <T> T getSingleService(Class<T> clss, String filter,
+                       Boolean synchronous) {
+               if (filter != null)
+                       Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter");
+               ServiceReference[] sfs;
+               try {
+                       if (synchronous)
+                               sfs = getServiceRefSynchronous(clss.getName(), filter);
+                       else
+                               sfs = bundleContext
+                                               .getServiceReferences(clss.getName(), filter);
+               } catch (InvalidSyntaxException e) {
+                       throw new SlcException("Cannot retrieve service reference for "
+                                       + filter, e);
+               }
+
+               if (sfs == null || sfs.length == 0)
+                       return null;
+               else if (sfs.length > 1)
+                       throw new SlcException("More than one execution flow found for "
+                                       + filter);
+               return (T) bundleContext.getService(sfs[0]);
+       }
+
+       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
new file mode 100644 (file)
index 0000000..a068a4f
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * 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.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 {
+                               try {
+                                       JarFile 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();
+                               }
+                       }
+               }
+               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
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.core/src/org/argeo/slc/osgi/OsgiBundle.java b/org.argeo.slc.core/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.core/src/org/argeo/slc/osgi/OsgiExecutionModule.java b/org.argeo.slc.core/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.core/src/org/argeo/slc/osgi/OsgiExecutionModulesManager.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionModulesManager.java
new file mode 100644 (file)
index 0000000..68fcead
--- /dev/null
@@ -0,0 +1,696 @@
+/*
+ * 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.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;
+import org.eclipse.gemini.blueprint.service.importer.OsgiServiceLifecycleListener;
+
+/** 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.getName(), 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) {
+               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) {
+               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);
+               }
+       }
+
+       @SuppressWarnings("deprecation")
+       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
new file mode 100644 (file)
index 0000000..57f33cf
--- /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.osgi.framework.BundleContext;
+import org.springframework.core.io.Resource;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+import org.eclipse.gemini.blueprint.io.OsgiBundleResource;
+
+/** 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
new file mode 100644 (file)
index 0000000..2414649
--- /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.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;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+
+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
new file mode 100644 (file)
index 0000000..a38adad
--- /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.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.springframework.beans.factory.InitializingBean;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+
+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
new file mode 100644 (file)
index 0000000..5159575
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * 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";
+
+       @SuppressWarnings(value = { "unchecked" })
+       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
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.core/src/org/argeo/slc/osgi/build/EclipseUpdateSiteCategory.java b/org.argeo.slc.core/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.core/src/org/argeo/slc/osgi/build/EclipseUpdateSiteFeature.java b/org.argeo.slc.core/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.core/src/org/argeo/slc/osgi/build/OsgiRuntimeModularDistribution.java b/org.argeo.slc.core/src/org/argeo/slc/osgi/build/OsgiRuntimeModularDistribution.java
new file mode 100644 (file)
index 0000000..434ef0e
--- /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.osgi.framework.Bundle;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.eclipse.gemini.blueprint.util.OsgiBundleUtils;
+
+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
new file mode 100644 (file)
index 0000000..d95137e
--- /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.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.springframework.core.io.ResourceLoader;
+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;
+
+/**
+ * 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
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