<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src"/>
+ <classpathentry kind="src" path="ext/test"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>>>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="output" path="bin"/>
</classpath>
--- /dev/null
+http\://www.argeo.org/schema/slc-flow=org.argeo.slc.core.execution.xml.FlowNamespaceHandler
\ No newline at end of file
--- /dev/null
+http\://www.argeo.org/schema/slc-flow.xsd=org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd
+http\://www.argeo.org/schema/slc-flow-1.2.xsd=org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd
+http\://www.argeo.org/schema/slc-flow-0.12.xsd=org/argeo/slc/core/execution/xml/slc-flow-0.12.xsd
--- /dev/null
+# 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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
+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",\
+junit.framework;resolution:="optional",\
+*
--- /dev/null
+additional.bundles = org.springframework.context
--- /dev/null
+# 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
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.core.test.context.AbstractInternalSpringTestCase;
+import org.springframework.core.io.Resource;
+
+public class DefaultResourceSetTest extends AbstractInternalSpringTestCase {
+ private final static Log log = LogFactory
+ .getLog(DefaultResourceSetTest.class);
+
+ public void testListResources() {
+ DefaultResourceSet rrs = getBean("relativeResourceSet");
+ Map<String, Resource> res = rrs.listResources();
+ for (String relativePath : res.keySet())
+ log.debug(relativePath + "=" + res.get(relativePath));
+ assertEquals(2, res.size());
+ }
+
+ @Override
+ protected String getApplicationContextLocation() {
+ return inPackage("relativeResourceSet.xml");
+ }
+
+}
--- /dev/null
+<?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
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution;\r
+\r
+import junit.framework.TestCase;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.core.test.SimpleTestResult;\r
+import org.argeo.slc.execution.ExecutionFlow;\r
+import org.argeo.slc.test.TestResultPart;\r
+import org.argeo.slc.test.TestStatus;\r
+import org.springframework.context.ConfigurableApplicationContext;\r
+import org.springframework.context.support.ClassPathXmlApplicationContext;\r
+\r
+public abstract class AbstractExecutionFlowTestCase extends TestCase {\r
+\r
+ protected final Log log = LogFactory.getLog(getClass());\r
+\r
+ protected void logException(Throwable ex) {\r
+ log.info("Got Exception of class " + ex.getClass().toString()\r
+ + " with message '" + ex.getMessage() + "'.");\r
+ }\r
+\r
+ protected void validateTestResult(SimpleTestResult testResult) {\r
+ validateTestResult(testResult, TestStatus.PASSED);\r
+ }\r
+\r
+ protected void validateTestResult(SimpleTestResult testResult,\r
+ int expectedStatus) {\r
+ for (TestResultPart part : testResult.getParts()) {\r
+ if (part.getStatus() != expectedStatus) {\r
+ fail("Error found in TestResult: " + part.getMessage());\r
+ }\r
+ }\r
+ }\r
+\r
+ protected ConfigurableApplicationContext createApplicationContext(\r
+ String applicationContextSuffix) {\r
+ ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext(\r
+ inPackage(applicationContextSuffix));\r
+ // applicationContext.start();\r
+ return applicationContext;\r
+ }\r
+\r
+ protected void configureAndExecuteSlcFlow(String applicationContextSuffix,\r
+ String beanName) {\r
+ ConfigurableApplicationContext applicationContext = createApplicationContext(applicationContextSuffix);\r
+ ExecutionFlow executionFlow = (ExecutionFlow) applicationContext\r
+ .getBean(beanName);\r
+ executionFlow.run();\r
+ applicationContext.close();\r
+ }\r
+\r
+ protected String inPackage(String suffix) {\r
+ String prefix = getClass().getPackage().getName().replace('.', '/');\r
+ return prefix + '/' + suffix;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.argeo.slc.core.test.SimpleTestResult;\r
+import org.argeo.slc.execution.ExecutionContext;\r
+import org.argeo.slc.execution.ExecutionFlow;\r
+import org.argeo.slc.test.TestStatus;\r
+import org.springframework.beans.factory.BeanCreationException;\r
+import org.springframework.context.ConfigurableApplicationContext;\r
+\r
+public class BasicExecutionFlowTest extends AbstractExecutionFlowTestCase {\r
+ // TO TEST\r
+ // - post-processing for @{} replacement in beans with complex properties\r
+ // - bean of scope other than execution are not resolved at execution\r
+\r
+ // public void testMyTest() throws Exception {\r
+ // ConfigurableApplicationContext applicationContext =\r
+ // createApplicationContext("test.xml");\r
+ // log.info("Start Execution");\r
+ // ((ExecutionFlow) applicationContext.getBean("flow1")).execute();\r
+ // applicationContext.close();\r
+ // }\r
+\r
+ public void testSpecOverriding() throws Exception {\r
+ ConfigurableApplicationContext applicationContext = createApplicationContext("specOverriding.xml");\r
+ ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
+ SimpleTestResult res = (SimpleTestResult) applicationContext\r
+ .getBean("myTestResult");\r
+ validateTestResult(res);\r
+ }\r
+\r
+ public void testMultipleFlows() throws Exception {\r
+ ConfigurableApplicationContext applicationContext = createApplicationContext("multipleFlow.xml");\r
+ ((ExecutionFlow) applicationContext.getBean("flow1")).run();\r
+ SimpleTestResult res = (SimpleTestResult) applicationContext\r
+ .getBean("myTestResult");\r
+ validateTestResult(res);\r
+ res.getParts().clear();\r
+ ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
+ validateTestResult(res, TestStatus.FAILED);\r
+ applicationContext.close();\r
+ }\r
+\r
+ /**\r
+ * Test placeholder resolution in a context without scope execution or proxy\r
+ * and with cascading flows (the flow A contains the flow B)\r
+ * \r
+ * @throws Exception\r
+ */\r
+ public void testPlaceHolders() throws Exception {\r
+ ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.xml");\r
+ ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
+ validateTestResult((SimpleTestResult) applicationContext\r
+ .getBean("myTestResult"));\r
+ applicationContext.close();\r
+ }\r
+\r
+ /**\r
+ * Test placeholder resolution in a context without scope execution or proxy\r
+ * and with cascading flows (the flow A contains the flow B) setting\r
+ * execution values (should have no effect)\r
+ * \r
+ * @throws Exception\r
+ */\r
+ public void testPlaceHoldersWithExecutionValues() throws Exception {\r
+ ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.xml");\r
+\r
+ ExecutionContext executionContext = (ExecutionContext) applicationContext\r
+ .getBean("executionContext");\r
+ Map<String, String> executionParameters = new HashMap<String, String>();\r
+ executionParameters.put("p1", "e1");\r
+ executionParameters.put("p2", "e2");\r
+ executionParameters.put("p3", "e3");\r
+ executionParameters.put("p4", "e4");\r
+ executionParameters.put("p5", "e5");\r
+ executionParameters.put("p6", "e6");\r
+ executionParameters.put("p7", "e7");\r
+ executionParameters.put("p8", "e8");\r
+ addVariables(executionContext, executionParameters);\r
+\r
+ ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
+ validateTestResult((SimpleTestResult) applicationContext\r
+ .getBean("myTestResult"));\r
+ applicationContext.close();\r
+ }\r
+\r
+ public void testPlaceHoldersExec() throws Exception {\r
+ ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.exec.xml");\r
+\r
+ ExecutionContext executionContext = (ExecutionContext) applicationContext\r
+ .getBean("executionContext");\r
+ Map<String, String> executionParameters = new HashMap<String, String>();\r
+ executionParameters.put("p1", "e1");\r
+ executionParameters.put("p2", "e2");\r
+ executionParameters.put("p3", "e3");\r
+ executionParameters.put("p4", "e4");\r
+ executionParameters.put("p5", "e5");\r
+ executionParameters.put("p6", "e6");\r
+ addVariables(executionContext, executionParameters);\r
+\r
+ ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
+ validateTestResult((SimpleTestResult) applicationContext\r
+ .getBean("myTestResult"));\r
+ applicationContext.close();\r
+ }\r
+\r
+ public void testCanonicFlowParameters() throws Exception {\r
+ configureAndExecuteSlcFlow("canonic-001.xml", "canonic.001");\r
+ }\r
+\r
+ public void testCanonicDefaultValues() throws Exception {\r
+ configureAndExecuteSlcFlow("canonic-002.xml", "canonic.002");\r
+ }\r
+\r
+ public void testCanonicMissingValues() throws Exception {\r
+ try {\r
+ configureAndExecuteSlcFlow("canonic-003.error.xml", "canonic.003");\r
+ fail("Parameter not set - should be rejected.");\r
+ } catch (BeanCreationException e) {\r
+ // exception expected\r
+ logException(e);\r
+ }\r
+ }\r
+\r
+ public void testCanonicUnknownParameter() throws Exception {\r
+ try {\r
+ configureAndExecuteSlcFlow("canonic-004.error.xml", "canonic.004");\r
+ fail("Unknown parameter set - should be rejected.");\r
+ } catch (BeanCreationException e) {\r
+ // exception expected\r
+ logException(e);\r
+ }\r
+ }\r
+\r
+ public void testListSetMap() throws Exception {\r
+ ConfigurableApplicationContext applicationContext = createApplicationContext("listSetMap.xml");\r
+ ExecutionFlow executionFlow = (ExecutionFlow) applicationContext\r
+ .getBean("myFlow");\r
+ executionFlow.run();\r
+\r
+ validateTestResult((SimpleTestResult) applicationContext\r
+ .getBean("myTestResult"));\r
+\r
+ // BasicTestData res = (BasicTestData)\r
+ // applicationContext.getBean("cascadingComplex.testData");\r
+ // log.info("res=" + res.getReached().toString());\r
+\r
+ applicationContext.close();\r
+ }\r
+\r
+ public void testListSetMapMultipleFlows() throws Exception {\r
+ ConfigurableApplicationContext applicationContext = createApplicationContext("listSetMapMultipleFlow.xml");\r
+ ((ExecutionFlow) applicationContext.getBean("flow1")).run();\r
+ SimpleTestResult res = (SimpleTestResult) applicationContext\r
+ .getBean("myTestResult");\r
+ validateTestResult(res);\r
+ res.getParts().clear();\r
+ ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
+ validateTestResult(res, TestStatus.FAILED);\r
+ applicationContext.close();\r
+ }\r
+\r
+ protected void addVariables(ExecutionContext executionContext,\r
+ Map<String, String> vars) {\r
+ for (String key : vars.keySet())\r
+ executionContext.setVariable(key, vars.get(key));\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.execution;
+
+import java.net.URI;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public class DefaultAgentCliTest extends TestCase {
+ public void testArgsToUris() {
+ String[] args = { "org.argeo.slc.demo.minimal", "HelloWorld/WithVar",
+ "--testKey", "555" };
+ List<URI> uris = DefaultAgentCli.asURIs(args);
+ assertEquals(1, uris.size());
+ assertEquals(
+ "flow:/org.argeo.slc.demo.minimal/HelloWorld/WithVar?testKey=555",
+ uris.get(0).toString());
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.InitializingBean;
+
+public class ExceptionIfInitCalledTwice implements Runnable, InitializingBean {
+ private final static Log log = LogFactory
+ .getLog(ExceptionIfInitCalledTwice.class);
+
+ private Boolean calledOnce = false;
+
+ public void run() {
+ log.info(getClass().getSimpleName() + " ran properly");
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ log.info(getClass().getSimpleName() + " init method called");
+
+ if (calledOnce)
+ throw new SlcException(getClass().getSimpleName()
+ + "init method called twice.");
+ else
+ calledOnce = true;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+
+public class FileExecutionResourcesSpringTest extends
+ AbstractExecutionFlowTestCase {
+ private String basePath = FileExecutionResources.DEFAULT_EXECUTION_RESOURCES_TMP_PATH;
+
+ public void testSimple() throws Exception {
+ File file = getFile("subdir/writeTo");
+ try {
+ assertFalse(file.exists());
+ configureAndExecuteSlcFlow("executionResources.xml",
+ "executionResources.simple");
+ assertTrue(file.exists());
+ } finally {
+ file.deleteOnExit();
+ }
+ }
+
+ public void testPlaceholderPass() throws Exception {
+ File file = getFile("subdir/60");
+ try {
+ assertFalse(file.exists());
+ configureAndExecuteSlcFlow("executionResources.xml",
+ "executionResources.placeholderPass");
+ assertTrue(file.exists());
+ } finally {
+ file.deleteOnExit();
+ }
+ }
+
+ /**
+ * Test that it generate the wrong file because of issue when using
+ * execution placeholder in contructor-arg
+ */
+ public void testPlaceholderFail() throws Exception {
+ File file = getFile("subdir/@{var}");
+ try {
+ assertFalse(file.exists());
+ configureAndExecuteSlcFlow("executionResources.xml",
+ "executionResources.placeholderFail");
+ assertTrue(file.exists());
+ } finally {
+ file.deleteOnExit();
+ }
+ }
+
+ protected File getFile(String relativePath) {
+ return new File(basePath + File.separator
+ + relativePath.replace('/', File.separatorChar));
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.io.FileUtils;
+import org.argeo.slc.execution.ExecutionContext;
+import org.springframework.core.io.Resource;
+
+public class FileExecutionResourcesTest extends TestCase {
+ public void testGetWritableFile() throws Exception {
+ FileExecutionResources executionResources = new FileExecutionResources();
+ ExecutionContext executionContext = new MapExecutionContext();
+ executionResources.setExecutionContext(executionContext);
+
+ String expected = "TEST";
+ String reached = "";
+ try {
+ // Resource
+ Resource resource = executionResources
+ .getWritableResource("subdir1/textRes.txt");
+ assertTrue(resource.getFile().getParentFile().exists());
+ assertFalse(resource.getFile().exists());
+ FileUtils.writeStringToFile(resource.getFile(), expected);
+ reached = FileUtils.readFileToString(resource.getFile());
+ assertEquals(expected, reached);
+
+ // File
+ File file = executionResources.getFile("subdir2/textFile.txt");
+ assertFalse(file.getParentFile().exists());
+ assertFalse(file.exists());
+ FileUtils.writeStringToFile(file, expected);
+ reached = FileUtils.readFileToString(file);
+ assertEquals(expected, reached);
+ } finally {
+ if (executionResources.getBaseDir() != null
+ && executionResources.getBaseDir().exists())
+ FileUtils.deleteDirectory(executionResources.getBaseDir());
+ }
+
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.argeo.slc.core.test.SimpleTestResult;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.test.TestStatus;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class ParameterRefTest extends AbstractExecutionFlowTestCase {
+ public void test001() throws Exception {
+ ConfigurableApplicationContext applicationContext = createApplicationContext("parameterRef.xml");
+ ((ExecutionFlow) applicationContext.getBean("parameterRef.001")).run();
+
+ SimpleTestResult res = (SimpleTestResult) applicationContext
+ .getBean("parameterRef.testResult");
+ assertEquals(res.getParts().get(0).getStatus(), TestStatus.PASSED);
+ assertEquals(res.getParts().get(1).getStatus(), TestStatus.FAILED);
+
+ applicationContext.close();
+ }
+
+}
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.core.execution.AbstractExecutionFlowTestCase;
+
+public class SystemCallTest extends AbstractExecutionFlowTestCase {
+ private final static Log log = LogFactory.getLog(SystemCallTest.class);
+
+ private final String defFile = "systemCall.xml";
+
+ public void testSystemCallSimple() throws Exception {
+ if (isOsSupported())
+ configureAndExecuteSlcFlow(defFile, "systemCallSimple");
+ }
+
+ public void testSystemCallList() throws Exception {
+ if (isOsSupported())
+ configureAndExecuteSlcFlow(defFile, "systemCallList");
+ }
+
+ public void testSystemCallOsSpecific() throws Exception {
+ if (isOsSupported())
+ configureAndExecuteSlcFlow(defFile, "systemCallOsSpecific");
+ }
+
+ public void testSystemCallWithVar() throws Exception {
+ if (isOsSupported())
+ configureAndExecuteSlcFlow(defFile, "systemCallWithVar");
+ }
+
+ protected boolean isOsSupported() {
+ String osName = System.getProperty("os.name");
+ final Boolean ret;
+ if (osName.contains("Windows"))
+ ret = false;
+ else
+ ret = true;
+
+ if (ret == false)
+ log.warn("Skip test because OS '" + osName + "' is not supported.");
+ return ret;
+ }
+}
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import org.argeo.slc.core.execution.AbstractExecutionFlowTestCase;
+import org.argeo.slc.core.test.SimpleTestResult;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class FlowNamespaceTest extends AbstractExecutionFlowTestCase {
+ public void testCanonical() throws Exception {
+ ConfigurableApplicationContext applicationContext = createApplicationContext("canonic-ns.xml");
+ ((ExecutionFlow) applicationContext.getBean("canonic-ns.001")).run();
+ ((ExecutionFlow) applicationContext.getBean("canonic-ns.002")).run();
+ }
+
+ public void testAdvanced() throws Exception {
+ ConfigurableApplicationContext applicationContext = createApplicationContext("advanced.xml");
+ ((ExecutionFlow) applicationContext.getBean("flow1")).run();
+ ((ExecutionFlow) applicationContext.getBean("flow2")).run();
+ ((ExecutionFlow) applicationContext.getBean("flow3")).run();
+
+ validateTestResult((SimpleTestResult) applicationContext
+ .getBean("testResult"));
+ }
+
+ public void testAdvancedExecution() throws Exception {
+ ConfigurableApplicationContext applicationContext = createApplicationContext("advanced.xml");
+
+ ExecutionContext executionContext = (ExecutionContext) applicationContext
+ .getBean("executionContext");
+ executionContext.setVariable("param2", 4);
+
+ ((ExecutionFlow) applicationContext.getBean("flow4")).run();
+
+ validateTestResult((SimpleTestResult) applicationContext
+ .getBean("testResult"));
+ }
+
+ // These tests causes pb when using Spring 3
+
+ // public void testContainers() throws Exception {
+ // ConfigurableApplicationContext applicationContext =
+ // createApplicationContext("containers.xml");
+ // ((ExecutionFlow) applicationContext.getBean("test.list.flow1")).run();
+ // ((ExecutionFlow) applicationContext.getBean("test.list.flow2")).run();
+ //
+ // validateTestResult((SimpleTestResult) applicationContext
+ // .getBean("testResult"));
+ // }
+}
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Map;\r
+\r
+import junit.framework.TestCase;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.SlcException;\r
+import org.springframework.beans.factory.BeanFactoryUtils;\r
+import org.springframework.beans.factory.ListableBeanFactory;\r
+import org.springframework.context.ConfigurableApplicationContext;\r
+import org.springframework.context.support.ClassPathXmlApplicationContext;\r
+\r
+/** Helper for tests using a Spring application context. */\r
+public abstract class AbstractInternalSpringTestCase extends TestCase {\r
+ protected final Log log = LogFactory.getLog(getClass());\r
+ private ConfigurableApplicationContext context;\r
+\r
+ /**\r
+ * Gets (and create if necessary) the application context to use. Default\r
+ * implementation uses a class path xml application context and calls\r
+ * {@link #getApplicationContextLocation()}.\r
+ */\r
+ protected ConfigurableApplicationContext getContext() {\r
+ if (context == null) {\r
+ context = new ClassPathXmlApplicationContext(\r
+ getApplicationContextLocation());\r
+ }\r
+ return context;\r
+ }\r
+\r
+ /** Returns a bean from the underlying context */\r
+ @SuppressWarnings(value = { "unchecked" })\r
+ protected <T> T getBean(String beanId) {\r
+ return (T) getContext().getBean(beanId);\r
+ }\r
+\r
+ protected <T> T getBean(Class<? extends T> clss) {\r
+ T bean = loadSingleFromContext(getContext(), clss);\r
+ if (bean == null) {\r
+ throw new SlcException("Cannot retrieve a unique bean of type "\r
+ + clss);\r
+ } else {\r
+ return bean;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Th location of the application to load. The default implementation\r
+ * returns <i>applicationContext.xml</i> found in the same package as the\r
+ * test.\r
+ */\r
+ protected String getApplicationContextLocation() {\r
+ return inPackage("applicationContext.xml");\r
+ }\r
+\r
+ /**\r
+ * Prefixes the package of the class after converting the '.' to '/' in\r
+ * order to have a resource path.\r
+ */\r
+ protected String inPackage(String suffix) {\r
+ String prefix = getClass().getPackage().getName().replace('.', '/');\r
+ return prefix + '/' + suffix;\r
+ }\r
+\r
+ @SuppressWarnings(value = { "unchecked" })\r
+ protected <T> T loadSingleFromContext(ListableBeanFactory context,\r
+ Class<T> clss) {\r
+ Map<String, T> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(\r
+ context, clss, false, false);\r
+ if (beans.size() == 1) {\r
+ return beans.values().iterator().next();\r
+ } else if (beans.size() > 1) {\r
+ if (log.isDebugEnabled()) {\r
+ log\r
+ .debug(("Found more that on bean for type " + clss\r
+ + ": " + beans.keySet()));\r
+ }\r
+ return null;\r
+ } else {\r
+ return null;\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.List;\r
+\r
+import org.argeo.slc.core.test.SimpleTestResult;\r
+import org.argeo.slc.test.TestResultPart;\r
+import org.argeo.slc.test.TestStatus;\r
+import org.argeo.slc.test.context.ContextAware;\r
+\r
+public class ContextTest extends AbstractInternalSpringTestCase {\r
+\r
+ public void testComplexContext() {\r
+ SimpleTestResult testResult = new SimpleTestResult();\r
+ ContextUtils.compareReachedExpected(\r
+ (ContextAware) getBean("context.c1"), testResult);\r
+ ContextUtils.compareReachedExpected(\r
+ (ContextAware) getBean("context.c2"), testResult);\r
+ ContextUtils.compareReachedExpected(\r
+ (ContextAware) getBean("context.c3"), testResult);\r
+\r
+ List<TestResultPart> parts = testResult.getParts();\r
+ assertEquals(6, parts.size());\r
+ assertEquals(TestStatus.PASSED, parts.get(0).getStatus());\r
+ assertEquals(TestStatus.PASSED, parts.get(1).getStatus());\r
+ assertEquals(TestStatus.PASSED, parts.get(2).getStatus());\r
+ assertEquals(TestStatus.FAILED, parts.get(3).getStatus());\r
+ assertEquals(TestStatus.PASSED, parts.get(4).getStatus());\r
+ assertEquals(TestStatus.PASSED, parts.get(5).getStatus());\r
+ }\r
+}\r
--- /dev/null
+<?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
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.argeo.slc</groupId>
</parent>
<artifactId>org.argeo.slc.core</artifactId>
<name>SLC Runtime</name>
+ <dependencies>
+ <!-- Commons -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.util</artifactId>
+ <version>${version.argeo-commons}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.security.core</artifactId>
+ <version>${version.argeo-commons}</version>
+ </dependency>
+
+ <!-- SLC -->
+ <dependency>
+ <groupId>org.argeo.slc</groupId>
+ <artifactId>org.argeo.slc.api</artifactId>
+ <version>2.1.1-SNAPSHOT</version>
+ </dependency>
+
+ </dependencies>
</project>
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+public interface Attachment {
+ public String getUuid();
+
+ public void setUuid(String uuid);
+
+ public String getName();
+
+ public String getContentType();
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+import org.springframework.core.io.Resource;
+
+public interface AttachmentUploader {
+ public void upload(Attachment attachment, Resource resource);
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+public interface AttachmentsEnabled {
+ public void addAttachment(Attachment attachment);
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public interface AttachmentsStorage {
+ public void retrieveAttachment(Attachment attachment,
+ OutputStream outputStream);
+
+ /** Does NOT close the provided input stream. */
+ public void storeAttachment(Attachment attachment, InputStream inputStream);
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.io.Resource;
+
+public class FileAttachmentsStorage implements AttachmentsStorage,
+ AttachmentUploader, InitializingBean {
+ private final static Log log = LogFactory
+ .getLog(FileAttachmentsStorage.class);
+
+ private File attachmentsDirectory;
+
+ private String attachmentsTocFileName = "attachmentsToc.csv";
+
+ private DateFormat dateFormatDay = new SimpleDateFormat("yyyy-MM-dd");
+ private DateFormat dateFormatTime = new SimpleDateFormat("HH:mm:ss");
+
+ public void afterPropertiesSet() {
+ if (attachmentsDirectory == null) {
+
+ String osgiInstanceArea = System.getProperty("osgi.instance.area");
+ if (osgiInstanceArea != null) {
+ if (osgiInstanceArea.startsWith("file:"))
+ osgiInstanceArea = osgiInstanceArea.substring("file:"
+ .length());
+ attachmentsDirectory = new File(osgiInstanceArea
+ + File.separator + "slcAttachments");
+ }
+
+ if (attachmentsDirectory == null) {
+ String tempDir = System.getProperty("java.io.tmpdir");
+ attachmentsDirectory = new File(tempDir + File.separator
+ + "slcAttachments");
+ }
+ }
+ if (!attachmentsDirectory.exists())
+ attachmentsDirectory.mkdirs();
+ if (log.isDebugEnabled())
+ log.debug("File attachment storage initialized in directory "
+ + attachmentsDirectory);
+ }
+
+ public void retrieveAttachment(Attachment attachment,
+ OutputStream outputStream) {
+ File file = getFile(attachment);
+ InputStream in = null;
+ try {
+ byte[] buffer = new byte[1024 * 1024];
+ in = new FileInputStream(file);
+ int read = -1;
+ while ((read = in.read(buffer)) >= 0) {
+ outputStream.write(buffer, 0, read);
+ }
+ if (log.isTraceEnabled())
+ log.trace("Read " + attachment + " from " + file);
+ } catch (IOException e) {
+ throw new SlcException("Cannot write attachment " + attachment
+ + " to " + file, e);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ public void storeAttachment(Attachment attachment, InputStream inputStream) {
+ File file = getFile(attachment);
+ FileOutputStream out = null;
+ try {
+ byte[] buffer = new byte[1024 * 1024];
+ out = new FileOutputStream(file);
+ int read = -1;
+ while ((read = inputStream.read(buffer)) >= 0) {
+ out.write(buffer, 0, read);
+ }
+ if (log.isTraceEnabled())
+ log.trace("Wrote " + attachment + " to " + file);
+ updateAttachmentToc(attachment, file);
+ } catch (IOException e) {
+ throw new SlcException("Cannot write attachment " + attachment
+ + " to " + file, e);
+ } finally {
+ IOUtils.closeQuietly(out);
+ }
+
+ }
+
+ public void upload(Attachment attachment, Resource resource) {
+ try {
+ storeAttachment(attachment, resource.getInputStream());
+ } catch (IOException e) {
+ throw new SlcException("Cannot upload attachment " + attachment, e);
+ }
+ }
+
+ /** For monitoring purposes only */
+ protected void updateAttachmentToc(Attachment attachment, File file) {
+ Date date = new Date(file.lastModified());
+ FileWriter writer = null;
+ try {
+ writer = new FileWriter(attachmentsDirectory + File.separator
+ + attachmentsTocFileName, true);
+ writer.append(dateFormatDay.format(date));
+ writer.append(',');
+ writer.append(dateFormatTime.format(date));
+ writer.append(',');
+ writer.append(attachment.getUuid());
+ writer.append(',');
+ writer.append(attachment.getName());
+ writer.append(',');
+ writer.append(attachment.getContentType());
+ writer.append(',');
+ writer.append(Long.toString(file.length()));
+ writer.append(',');
+ writer.append(file.getCanonicalPath());
+ writer.append('\n');
+ } catch (IOException e) {
+ log.warn("Could not update attachments TOC for " + attachment
+ + " and file " + file, e);
+ } finally {
+ IOUtils.closeQuietly(writer);
+ }
+
+ }
+
+ protected File getFile(Attachment attachment) {
+ File file = new File(attachmentsDirectory + File.separator
+ + attachment.getUuid());
+ return file;
+ }
+
+ public void setAttachmentsDirectory(File attachmentsDirectory) {
+ this.attachmentsDirectory = attachmentsDirectory;
+ }
+
+ public void setAttachmentsTocFileName(String attachmentsTocFileName) {
+ this.attachmentsTocFileName = attachmentsTocFileName;
+ }
+
+ public void setDateFormatDay(DateFormat dateFormatDay) {
+ this.dateFormatDay = dateFormatDay;
+ }
+
+ public void setDateFormatTime(DateFormat dateFormatTime) {
+ this.dateFormatTime = dateFormatTime;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.attachment;
+
+import java.io.Serializable;
+import java.util.UUID;
+
+public class SimpleAttachment implements Attachment, Serializable {
+ private static final long serialVersionUID = 6615155908800610606L;
+ private String uuid = UUID.randomUUID().toString();
+ private String name;
+ private String contentType = "";
+
+ public SimpleAttachment() {
+ }
+
+ public SimpleAttachment(String uuid, String name, String contentType) {
+ super();
+ this.uuid = uuid;
+ this.name = name;
+ this.contentType = contentType;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ public String toString() {
+ return "Attachment #" + uuid + "(" + name + ", " + contentType + ")";
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof Attachment) {
+ Attachment attachment = (Attachment) obj;
+ if (uuid != null && attachment.getUuid() != null)
+ return uuid.equals(attachment.getUuid());
+
+ if (name != null && attachment.getName() != null)
+ return name.equals(attachment.getName());
+
+ return hashCode() == attachment.hashCode();
+ }
+ return false;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.build;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.StreamReadable;
+import org.argeo.slc.build.Distribution;
+import org.springframework.core.io.Resource;
+
+/** A software distribution archive accessible via a {@link Resource}. */
+public class ResourceDistribution implements Distribution, StreamReadable {
+ private Resource resource;
+
+ public ResourceDistribution() {
+ }
+
+ public ResourceDistribution(Resource location) {
+ this.resource = location;
+ }
+
+ public String getDistributionId() {
+ return resource.toString();
+ }
+
+ public Resource getResource() {
+ return resource;
+ }
+
+ public void setResource(Resource resource) {
+ this.resource = resource;
+ }
+
+ public InputStream getInputStream() {
+ try {
+ return resource.getInputStream();
+ } catch (IOException e) {
+ throw new SlcException("Cannot get input stream", e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return resource.toString();
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.build;\r
+\r
+import java.util.StringTokenizer;\r
+\r
+/**\r
+ * <p>\r
+ * An implementation of the distribution id using the standard\r
+ * Major.Minor.Release notation. And additional arbitrary string can also be\r
+ * added.\r
+ * </p>\r
+ * \r
+ * <p>\r
+ * <b>Examples:</b><br>\r
+ * 0.2.6<br>\r
+ * 2.4.12.RC1\r
+ * </p>\r
+ */\r
+public class VersionDistributionId {\r
+\r
+ private Integer major;\r
+ private Integer minor;\r
+ private Integer release;\r
+ private String additional;\r
+\r
+ /** Parse the provided string in order to set the various components. */\r
+ public void setVersionString(String str) {\r
+ StringTokenizer st = new StringTokenizer(str, ".");\r
+ if (st.hasMoreTokens())\r
+ major = Integer.parseInt(st.nextToken());\r
+ if (st.hasMoreTokens())\r
+ minor = Integer.parseInt(st.nextToken());\r
+ if (st.hasMoreTokens())\r
+ release = Integer.parseInt(st.nextToken());\r
+ if (st.hasMoreTokens())\r
+ additional = st.nextToken();\r
+ }\r
+\r
+ public Integer getMajor() {\r
+ return major;\r
+ }\r
+\r
+ public void setMajor(Integer major) {\r
+ this.major = major;\r
+ }\r
+\r
+ public Integer getMinor() {\r
+ return minor;\r
+ }\r
+\r
+ public void setMinor(Integer minor) {\r
+ this.minor = minor;\r
+ }\r
+\r
+ public Integer getRelease() {\r
+ return release;\r
+ }\r
+\r
+ public void setRelease(Integer release) {\r
+ this.release = release;\r
+ }\r
+\r
+ public String getAdditional() {\r
+ return additional;\r
+ }\r
+\r
+ public void setAdditional(String additional) {\r
+ this.additional = additional;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ // TODO Auto-generated method stub\r
+ return super.equals(obj);\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return major + "." + minor + "." + release\r
+ + (additional != null ? "." + additional : "");\r
+ }\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.build;
+
+import org.argeo.slc.NameVersion;
+import org.springframework.core.io.Resource;
+
+/**
+ * The distribution of a software package (jar, zip, RPM, etc.) which is
+ * versioned. The archive itself is accessible via a {@link Resource}.
+ */
+public class VersionedResourceDistribution extends ResourceDistribution
+ implements NameVersion {
+ private String name;
+ private String version;
+
+ public VersionedResourceDistribution() {
+ super();
+ }
+
+ public VersionedResourceDistribution(NameVersion nameVersion,
+ Resource resource) {
+ this(nameVersion.getName(), nameVersion.getVersion(), resource);
+ }
+
+ public VersionedResourceDistribution(String name, String version,
+ Resource resource) {
+ super(resource);
+ this.name = name;
+ this.version = version;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+}
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+SLC Build: building of software systems.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.PathMatcher;
+
+public class DefaultResourceSet implements ResourceLoaderAware,
+ InitializingBean, ResourceSet {
+ private final static Log log = LogFactory.getLog(DefaultResourceSet.class);
+ public final static String DEFAULT_EXCLUDES = "**/.svn/**";
+
+ private String base;
+ private String include;
+ private List<String> includes = new ArrayList<String>();
+ private String exclude;
+ private List<String> excludes = new ArrayList<String>();
+ private Boolean useDefaultExcludes = true;
+ private ResourcePatternResolver resourcePatternResolver;
+ private PathMatcher excludePathMatcher = new AntPathMatcher();
+
+ private ResourceLoader resourceLoader;
+
+ /** List the resources, identified by their relative path. */
+ public Map<String, Resource> listResources() {
+ try {
+ Map<String, Resource> res = new TreeMap<String, Resource>();
+ if (base == null)
+ return res;
+ String baseResUrl = getResourceLoaderToUse().getResource(base)
+ .getURL().toString();
+ for (String includePattern : includes)
+ processInclude(res, includePattern, baseResUrl);
+ return res;
+ } catch (IOException e) {
+ throw new SlcException("Cannot list resource from " + base, e);
+ }
+ }
+
+ protected void processInclude(Map<String, Resource> res, String include,
+ String baseResUrl) throws IOException {
+ String pattern = base + "/" + include;
+ if (log.isTraceEnabled())
+ log.trace("Look for resources with pattern '" + pattern
+ + "' in base url " + baseResUrl);
+ Resource[] resources = resourcePatternResolver.getResources(pattern);
+ resources: for (Resource resource : resources) {
+ String url = resource.getURL().toString();
+ String relPath = url.substring(baseResUrl.length());
+
+ // skip dir
+ if (relPath.charAt(relPath.length() - 1) == '/') {
+ if (log.isTraceEnabled())
+ log.trace("Skip directory " + relPath + "=" + resource);
+ continue resources;
+ }
+
+ // make sure there is not starting '/'
+ if (relPath.charAt(0) == '/')
+ relPath = relPath.substring(1);
+
+ // skip excludes
+ for (String exclude : excludes)
+ if (excludePathMatcher.match(exclude, relPath)) {
+ if (log.isTraceEnabled())
+ log.trace("Exclude " + relPath + "=" + resource);
+ continue resources;
+ }
+
+ // check if already exists
+ if (res.containsKey(relPath))
+ log.warn(relPath + " already matched by " + res.get(relPath)
+ + ", " + resource + " will override it.");
+
+ // store the marched resource
+ res.put(relPath, resource);
+ if (log.isTraceEnabled())
+ log.trace(relPath + "=" + resource);
+ }
+
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ if (resourcePatternResolver == null)
+ resourcePatternResolver = new PathMatchingResourcePatternResolver(
+ getResourceLoaderToUse());
+ if (include != null)
+ addCommaSeparatedToList(include, includes);
+ if (exclude != null)
+ addCommaSeparatedToList(exclude, excludes);
+
+ if (includes.size() == 0)
+ includes.add("**");
+
+ if (useDefaultExcludes)
+ addCommaSeparatedToList(DEFAULT_EXCLUDES, excludes);
+ }
+
+ private void addCommaSeparatedToList(String str, List<String> lst) {
+ StringTokenizer st = new StringTokenizer(str, ",");
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ if (!lst.contains(token))
+ lst.add(token);
+ }
+ }
+
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+
+ /**
+ * Can be overridden in order to provide the proper resource loader used to
+ * resolve resources.
+ */
+ public ResourceLoader getResourceLoaderToUse() {
+ return resourceLoader;
+ }
+
+ public void setBase(String base) {
+ this.base = base;
+ }
+
+ public void setInclude(String include) {
+ this.include = include;
+ }
+
+ public void setIncludes(List<String> includes) {
+ this.includes = includes;
+ }
+
+ public void setExclude(String exclude) {
+ this.exclude = exclude;
+ }
+
+ public void setExcludes(List<String> excludes) {
+ this.excludes = excludes;
+ }
+
+ public void setUseDefaultExcludes(Boolean useDefaultExcludes) {
+ this.useDefaultExcludes = useDefaultExcludes;
+ }
+
+ public void setExcludePathMatcher(PathMatcher excludePathMatcher) {
+ this.excludePathMatcher = excludePathMatcher;
+ }
+
+ public void setResourcePatternResolver(
+ ResourcePatternResolver resourcePatternResolver) {
+ this.resourcePatternResolver = resourcePatternResolver;
+ }
+
+ public ResourcePatternResolver getResourcePatternResolver() {
+ return resourcePatternResolver;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.argeo.slc.SlcException;
+import org.argeo.util.security.DigestUtils;
+import org.springframework.core.io.Resource;
+
+/** Add Spring capabilities to {@link DigestUtils} */
+public class DigestCheck extends DigestUtils {
+ public static String digest(String algorithm, Resource resource) {
+ try {
+ File file = resource.getFile();
+ return digest(algorithm, file);
+ } catch (IOException e) {
+ try {
+ return digest(algorithm, resource.getInputStream());
+ } catch (IOException e1) {
+ throw new SlcException("Cannot digest " + resource
+ + " with algorithm " + algorithm, e);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.argeo.slc.SlcException;
+import org.springframework.core.io.Resource;
+
+public class LocalFilesDeployment implements Runnable {
+ private String targetBase = "";
+ private ResourceSet resourceSet;
+
+ public LocalFilesDeployment() {
+ }
+
+ public LocalFilesDeployment(ResourceSet resourceSet) {
+ this.resourceSet = resourceSet;
+ }
+
+ public void run() {
+ Map<String, Resource> resources = resourceSet.listResources();
+ for (String relPath : resources.keySet()) {
+ File targetFile = new File(targetBase + File.separator + relPath);
+ File parentDir = targetFile.getParentFile();
+ if (!parentDir.exists())
+ parentDir.mkdirs();
+
+ Resource resource = resources.get(relPath);
+
+ InputStream in = null;
+ OutputStream out = null;
+ try {
+ in = resource.getInputStream();
+ out = FileUtils.openOutputStream(targetFile);
+ IOUtils.copy(in, out);
+ } catch (IOException e) {
+ throw new SlcException("Cannot extract " + resource + " to "
+ + targetFile, e);
+ } finally {
+ IOUtils.closeQuietly(in);
+ IOUtils.closeQuietly(out);
+ }
+ }
+ }
+
+ public void setTargetBase(String targetBase) {
+ this.targetBase = targetBase;
+ }
+
+ public void setResourceSet(ResourceSet resourceSet) {
+ this.resourceSet = resourceSet;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.core.io.Resource;
+
+public class MultiResourceSet implements ResourceSet {
+ private List<ResourceSet> resourceSets = new ArrayList<ResourceSet>();
+
+ public Map<String, Resource> listResources() {
+ Map<String, Resource> res = new HashMap<String, Resource>();
+ for (ResourceSet resourceSet : resourceSets) {
+ res.putAll(resourceSet.listResources());
+ }
+ return res;
+ }
+
+ /** Last listed override previous for the same relative paths. */
+ public void setResourceSets(List<ResourceSet> resourceSets) {
+ this.resourceSets = resourceSets;
+ }
+
+ public List<ResourceSet> getResourceSets() {
+ return resourceSets;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.util.Map;
+
+import org.springframework.core.io.Resource;
+
+public interface ResourceSet {
+ /**
+ * List the resources, identified by their relative path. Relative paths
+ * must NOT start with a '/'.
+ */
+ public Map<String, Resource> listResources();
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.io.File;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.deploy.DeploymentData;
+import org.argeo.slc.deploy.InstalledExecutables;
+import org.argeo.slc.deploy.TargetData;
+
+public class SimpleExecutables implements InstalledExecutables {
+ private final static Log log = LogFactory.getLog(SimpleExecutables.class);
+
+ private String baseDir;
+ private Map<String, String> paths = new TreeMap<String, String>();
+
+ private Distribution distribution;
+
+ public String getExecutablePath(String key) {
+ String path = paths.get(key);
+ if (path == null) {
+ if (log.isDebugEnabled())
+ log.debug("No executable path found for key " + key
+ + ", using the key as executable name.");
+ path = key;
+ }
+
+ if (baseDir != null)
+ path = baseDir + File.separator + path;
+ return path;
+ }
+
+ public String getDeployedSystemId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public DeploymentData getDeploymentData() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Distribution getDistribution() {
+ return distribution;
+ }
+
+ public TargetData getTargetData() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getBaseDir() {
+ return baseDir;
+ }
+
+ public void setBaseDir(String baseDir) {
+ this.baseDir = baseDir;
+ }
+
+ public Map<String, String> getPaths() {
+ return paths;
+ }
+
+ public void setPaths(Map<String, String> paths) {
+ this.paths = paths;
+ }
+
+ public void setDistribution(Distribution distribution) {
+ this.distribution = distribution;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.deploy;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.deploy.VersioningDriver;
+
+/**
+ * Synchronizes an URL to a local directory, taking into account versioning
+ * information if possible.
+ */
+public class VersionedDirSync implements Runnable {
+ private final static Log log = LogFactory.getLog(VersionedDirSync.class);
+
+ private VersioningDriver versioningDriver;
+ private File dir;
+ private String url;
+ private Boolean clean = false;
+
+ private Boolean changed = null;
+
+ public void run() {
+ changed = null;
+ if (clean) {
+ try {
+ log.info("Clean " + dir);
+ FileUtils.deleteDirectory(dir);
+ } catch (IOException e) {
+ throw new SlcException("Cannot delete checkout directory "
+ + dir, e);
+ }
+ dir.mkdirs();
+ }
+ log.info("Checkout " + url + " to " + dir);
+ changed = versioningDriver.checkout(url, dir, true);
+ if (log.isDebugEnabled())
+ log.debug("Synchronized " + url + " to " + dir);
+ }
+
+ public void setVersioningDriver(VersioningDriver versioningDriver) {
+ this.versioningDriver = versioningDriver;
+ }
+
+ public void setDir(File dir) {
+ this.dir = dir;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ /** Delete before checkout */
+ public void setClean(Boolean clean) {
+ this.clean = clean;
+ }
+
+ /** Whether last call has changed the directory */
+ public Boolean getChanged() {
+ if (changed == null)
+ throw new SlcException("Sync has not run");
+ return changed;
+ }
+
+}
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+SLC Deploy: deployment of software systems.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.GenericBeanDefinition;
+import org.springframework.core.Ordered;
+import org.springframework.core.PriorityOrdered;
+
+public abstract class AbstractExecutionFlowGenerator implements
+ BeanFactoryPostProcessor, PriorityOrdered {
+ private final Log log = LogFactory.getLog(getClass());
+
+ protected abstract Map<String, BeanDefinition> createExecutionFlowDefinitions(
+ ConfigurableListableBeanFactory beanFactory);
+
+ public void postProcessBeanFactory(
+ ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ if (!(beanFactory instanceof BeanDefinitionRegistry)) {
+ throw new SlcException("Can only work on "
+ + BeanDefinitionRegistry.class);
+ }
+
+ Map<String, BeanDefinition> definitions = createExecutionFlowDefinitions(beanFactory);
+
+ for (String beanName : definitions.keySet()) {
+ if (log.isTraceEnabled())
+ log.debug("Registering execution flow " + beanName);
+ ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(
+ beanName, definitions.get(beanName));
+ }
+ }
+
+ protected GenericBeanDefinition createDefaultFlowDefinition(
+ List<Runnable> executables) {
+ GenericBeanDefinition bd = new GenericBeanDefinition();
+ bd.setBeanClass(DefaultExecutionFlow.class);
+
+ MutablePropertyValues mpv = new MutablePropertyValues();
+ mpv.addPropertyValue("executables", executables);
+
+ bd.setPropertyValues(mpv);
+ return bd;
+ }
+
+ public int getOrder() {
+ return Ordered.HIGHEST_PRECEDENCE;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.RealizedFlow;
+
+/** Provides the base feature of an execution module manager. */
+public abstract class AbstractExecutionModulesManager implements
+ ExecutionModulesManager {
+ private final static Log log = LogFactory
+ .getLog(AbstractExecutionModulesManager.class);
+
+// private List<FilteredNotifier> filteredNotifiers = Collections
+// .synchronizedList(new ArrayList<FilteredNotifier>());
+
+ protected abstract ExecutionFlow findExecutionFlow(String moduleName,
+ String moduleVersion, String flowName);
+
+ protected abstract ExecutionContext findExecutionContext(String moduleName,
+ String moduleVersion);
+
+ protected abstract ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
+ String moduleName, String moduleVersion);
+
+ public void execute(RealizedFlow realizedFlow) {
+ if (log.isTraceEnabled())
+ log.trace("Executing " + realizedFlow);
+
+ String moduleName = realizedFlow.getModuleName();
+ String moduleVersion = realizedFlow.getModuleVersion();
+
+ Map<? extends String, ? extends Object> variablesToAdd = getExecutionFlowDescriptorConverter(
+ moduleName, moduleVersion).convertValues(
+ realizedFlow.getFlowDescriptor());
+ ExecutionContext executionContext = findExecutionContext(moduleName,
+ moduleVersion);
+ for (String key : variablesToAdd.keySet())
+ executionContext.setVariable(key, variablesToAdd.get(key));
+
+ ExecutionFlow flow = findExecutionFlow(moduleName, moduleVersion,
+ realizedFlow.getFlowDescriptor().getName());
+
+ //
+ // Actually runs the flow, IN THIS THREAD
+ //
+ flow.run();
+ //
+ //
+ //
+ }
+
+// public void dispatchUpdateStatus(ExecutionProcess process,
+// String oldStatus, String newStatus) {
+// // filtered notifiers
+// for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
+// .hasNext();) {
+// FilteredNotifier filteredNotifier = it.next();
+// if (filteredNotifier.receiveFrom(process))
+// filteredNotifier.getNotifier().updateStatus(process, oldStatus,
+// newStatus);
+// }
+//
+// }
+
+// public void dispatchAddSteps(ExecutionProcess process,
+// List<ExecutionStep> steps) {
+// process.addSteps(steps);
+// for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
+// .hasNext();) {
+// FilteredNotifier filteredNotifier = it.next();
+// if (filteredNotifier.receiveFrom(process))
+// filteredNotifier.getNotifier().addSteps(process, steps);
+// }
+// }
+
+// public void registerProcessNotifier(ExecutionProcessNotifier notifier,
+// Map<String, String> properties) {
+// filteredNotifiers.add(new FilteredNotifier(notifier, properties));
+// }
+//
+// public void unregisterProcessNotifier(ExecutionProcessNotifier notifier,
+// Map<String, String> properties) {
+// filteredNotifiers.remove(notifier);
+// }
+
+// protected class FilteredNotifier {
+// private final ExecutionProcessNotifier notifier;
+// private final String processId;
+//
+// public FilteredNotifier(ExecutionProcessNotifier notifier,
+// Map<String, String> properties) {
+// super();
+// this.notifier = notifier;
+// if (properties == null)
+// properties = new HashMap<String, String>();
+// if (properties.containsKey(SLC_PROCESS_ID))
+// processId = properties.get(SLC_PROCESS_ID);
+// else
+// processId = null;
+// }
+//
+// /**
+// * Whether event from this process should be received by this listener.
+// */
+// public Boolean receiveFrom(ExecutionProcess process) {
+// if (processId != null)
+// if (process.getUuid().equals(processId))
+// return true;
+// else
+// return false;
+// return true;
+// }
+//
+// @Override
+// public int hashCode() {
+// return notifier.hashCode();
+// }
+//
+// @Override
+// public boolean equals(Object obj) {
+// if (obj instanceof FilteredNotifier) {
+// FilteredNotifier fn = (FilteredNotifier) obj;
+// return notifier.equals(fn.notifier);
+// } else if (obj instanceof ExecutionProcessNotifier) {
+// ExecutionProcessNotifier epn = (ExecutionProcessNotifier) obj;
+// return notifier.equals(epn);
+// } else
+// return false;
+// }
+//
+// public ExecutionProcessNotifier getNotifier() {
+// return notifier;
+// }
+//
+// }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.Serializable;
+
+/** Value to be used by an execution */
+public abstract class AbstractExecutionValue implements Serializable {
+ private static final long serialVersionUID = 1558444746120706961L;
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.Serializable;
+
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+
+/** Canonical implementation of the execution spec attribute booleans. */
+public abstract class AbstractSpecAttribute implements ExecutionSpecAttribute,
+ Serializable {
+ private static final long serialVersionUID = 6494963738891709440L;
+ private Boolean isImmutable = false;
+ private Boolean isConstant = false;
+ private Boolean isHidden = false;
+
+ private String description;
+
+ /** Has to be set at instantiation */
+ public Boolean getIsImmutable() {
+ return isImmutable;
+ }
+
+ public void setIsImmutable(Boolean isImmutable) {
+ this.isImmutable = isImmutable;
+ }
+
+ /** Cannot be overridden at runtime */
+ public Boolean getIsConstant() {
+ return isConstant;
+ }
+
+ public void setIsConstant(Boolean isConstant) {
+ this.isConstant = isConstant;
+ }
+
+ /** Should not be shown to the end user */
+ public Boolean getIsHidden() {
+ return isHidden;
+ }
+
+ public void setIsHidden(Boolean isHidden) {
+ this.isHidden = isHidden;
+ }
+
+ /*
+ * DEPRECATED
+ */
+ /** @deprecated use {@link #getIsImmutable()} instead */
+ public Boolean getIsParameter() {
+ return isImmutable;
+ }
+
+ /** @deprecated use {@link #getIsConstant()} instead */
+ public Boolean getIsFrozen() {
+ return isConstant;
+ }
+
+ /** @deprecated use {@link #setIsImmutable(Boolean)} instead */
+ public void setIsParameter(Boolean isParameter) {
+ this.isImmutable = isParameter;
+ }
+
+ /** @deprecated use {@link #setIsConstant(Boolean)} instead */
+ public void setIsFrozen(Boolean isFrozen) {
+ this.isConstant = isFrozen;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.argeo.slc.execution.ExecutionModule;
+
+@Deprecated
+public abstract class AbstractSpringExecutionModule implements ExecutionModule
+ {
+/*
+ protected ApplicationContext applicationContext;
+
+ protected ExecutionContext executionContext;
+
+ protected ExecutionFlowDescriptorConverter descriptorConverter = new DefaultDescriptorConverter();
+
+ public ExecutionModuleDescriptor getDescriptor() {
+ ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
+ md.setName(getName());
+ md.setVersion(getVersion());
+
+ Map<String, ExecutionFlow> executionFlows = listFlows();
+ for (String name : executionFlows.keySet()) {
+ ExecutionFlow executionFlow = executionFlows.get(name);
+
+ Assert.notNull(executionFlow.getName());
+ Assert.state(name.equals(executionFlow.getName()));
+
+ ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
+ Assert.notNull(executionSpec);
+ Assert.notNull(executionSpec.getName());
+
+ Map<String, Object> values = new TreeMap<String, Object>();
+ for (String key : executionSpec.getAttributes().keySet()) {
+ ExecutionSpecAttribute attribute = executionSpec
+ .getAttributes().get(key);
+
+ if (executionFlow.isSetAsParameter(key)) {
+ Object value = executionFlow.getParameter(key);
+ if (attribute instanceof PrimitiveSpecAttribute) {
+ PrimitiveValue primitiveValue = new PrimitiveValue();
+ primitiveValue
+ .setType(((PrimitiveSpecAttribute) attribute)
+ .getType());
+ primitiveValue.setValue(value);
+ values.put(key, primitiveValue);
+ } else if (attribute instanceof RefSpecAttribute) {
+ RefValue refValue = new RefValue();
+ if (value instanceof ScopedObject) {
+ refValue.setLabel("RUNTIME "
+ + value.getClass().getName());
+ } else {
+ refValue.setLabel("STATIC "
+ + value.getClass().getName());
+ }
+ values.put(key, refValue);
+ } else if (attribute instanceof ResourceSpecAttribute) {
+ PrimitiveValue primitiveValue = new PrimitiveValue();
+ primitiveValue
+ .setType(((ResourceSpecAttribute) attribute)
+ .getType());
+ primitiveValue.setValue(value);
+ values.put(key, primitiveValue);
+ } else {
+ throw new SlcException("Unkown spec attribute type "
+ + attribute.getClass());
+ }
+ }
+
+ }
+
+ ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name,
+ values, executionSpec);
+ if (executionFlow.getPath() != null)
+ efd.setPath(executionFlow.getPath());
+
+ // Add execution spec if necessary
+ if (!md.getExecutionSpecs().contains(executionSpec))
+ md.getExecutionSpecs().add(executionSpec);
+
+ // Add execution flow
+ md.getExecutionFlows().add(efd);
+ }
+
+ return md;
+ }
+
+ protected Map<String, ExecutionFlow> listFlows() {
+ GenericBeanFactoryAccessor accessor = new GenericBeanFactoryAccessor(
+ applicationContext);
+ Map<String, ExecutionFlow> executionFlows = accessor
+ .getBeansOfType(ExecutionFlow.class);
+ return executionFlows;
+ }
+
+ public void execute(ExecutionFlowDescriptor executionFlowDescriptor) {
+ if (descriptorConverter != null)
+ executionContext.addVariables(descriptorConverter
+ .convertValues(executionFlowDescriptor));
+ ExecutionFlow flow = (ExecutionFlow) applicationContext.getBean(
+ executionFlowDescriptor.getName(), ExecutionFlow.class);
+ flow.run();
+ }
+
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+ public void setExecutionContext(ExecutionContext executionContext) {
+ this.executionContext = executionContext;
+ }
+
+ public void setDescriptorConverter(
+ ExecutionFlowDescriptorConverter descriptorConverter) {
+ this.descriptorConverter = descriptorConverter;
+ }*/
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLDecoder;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.argeo.slc.BasicNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.SlcAgent;
+
+/** Implements the base methods of an SLC agent. */
+public class DefaultAgent implements SlcAgent {
+ // private final static Log log = LogFactory.getLog(DefaultAgent.class);
+ /** UTF-8 charset for encoding. */
+ private final static String UTF8 = "UTF-8";
+
+ private String agentUuid = null;
+ private ExecutionModulesManager modulesManager;
+
+ private ThreadGroup processesThreadGroup;
+ private Map<String, ProcessThread> runningProcesses = Collections
+ .synchronizedMap(new HashMap<String, ProcessThread>());
+
+ private String defaultModulePrefix = null;
+
+ /*
+ * LIFECYCLE
+ */
+ /** Initialization */
+ public void init() {
+ agentUuid = initAgentUuid();
+ processesThreadGroup = new ThreadGroup("SLC Processes of Agent #"
+ + agentUuid);
+ }
+
+ /** Clean up (needs to be called by overriding method) */
+ public void destroy() {
+ }
+
+ /**
+ * Called during initialization in order to determines the agent UUID. To be
+ * overridden. By default creates a new one per instance.
+ */
+ protected String initAgentUuid() {
+ return UUID.randomUUID().toString();
+ }
+
+ /*
+ * SLC AGENT
+ */
+ public void process(ExecutionProcess process) {
+ ProcessThread processThread = createProcessThread(processesThreadGroup,
+ modulesManager, process);
+ processThread.start();
+ runningProcesses.put(process.getUuid(), processThread);
+
+ // clean up old processes
+ Iterator<ProcessThread> it = runningProcesses.values().iterator();
+ while (it.hasNext()) {
+ ProcessThread pThread = it.next();
+ if (!pThread.isAlive())
+ it.remove();
+ }
+ }
+
+ public String process(List<URI> uris) {
+ DefaultProcess process = new DefaultProcess();
+ for (URI uri : uris) {
+ String[] path = uri.getPath().split("/");
+ if (path.length < 3)
+ throw new SlcException("Badly formatted URI: " + uri);
+ NameVersion nameVersion = new BasicNameVersion(path[1]);
+ StringBuilder flow = new StringBuilder();
+ for (int i = 2; i < path.length; i++)
+ flow.append('/').append(path[i]);
+
+ Map<String, Object> values = getQueryMap(uri.getQuery());
+ // Get execution module descriptor
+ ExecutionModuleDescriptor emd = getExecutionModuleDescriptor(
+ nameVersion.getName(), nameVersion.getVersion());
+ process.getRealizedFlows().add(
+ emd.asRealizedFlow(flow.toString(), values));
+ }
+ process(process);
+ return process.getUuid();
+ }
+
+ public void kill(String processUuid) {
+ if (runningProcesses.containsKey(processUuid)) {
+ runningProcesses.get(processUuid).interrupt();
+ } else {
+ // assume is finished
+ }
+ }
+
+ public void waitFor(String processUuid, Long millis) {
+ if (runningProcesses.containsKey(processUuid)) {
+ try {
+ if (millis != null)
+ runningProcesses.get(processUuid).join(millis);
+ else
+ runningProcesses.get(processUuid).join();
+ } catch (InterruptedException e) {
+ // silent
+ }
+ } else {
+ // assume is finished
+ }
+ }
+
+ /** Creates the thread which will coordinate the execution for this agent. */
+ protected ProcessThread createProcessThread(
+ ThreadGroup processesThreadGroup,
+ ExecutionModulesManager modulesManager, ExecutionProcess process) {
+ ProcessThread processThread = new ProcessThread(processesThreadGroup,
+ modulesManager, process);
+ return processThread;
+ }
+
+ public ExecutionModuleDescriptor getExecutionModuleDescriptor(
+ String moduleName, String moduleVersion) {
+ // Get execution module descriptor
+ ExecutionModuleDescriptor emd;
+ try {
+ modulesManager
+ .start(new BasicNameVersion(moduleName, moduleVersion));
+ emd = modulesManager.getExecutionModuleDescriptor(moduleName,
+ moduleVersion);
+ } catch (SlcException e) {
+ if (defaultModulePrefix != null) {
+ moduleName = defaultModulePrefix + "." + moduleName;
+ modulesManager.start(new BasicNameVersion(moduleName,
+ moduleVersion));
+ emd = modulesManager.getExecutionModuleDescriptor(moduleName,
+ moduleVersion);
+ } else
+ throw e;
+ }
+ return emd;
+ }
+
+ public List<ExecutionModuleDescriptor> listExecutionModuleDescriptors() {
+ return modulesManager.listExecutionModules();
+ }
+
+ public boolean ping() {
+ return true;
+ }
+
+ /*
+ * UTILITIES
+ */
+ /**
+ * @param query
+ * can be null
+ */
+ static Map<String, Object> getQueryMap(String query) {
+ Map<String, Object> map = new LinkedHashMap<String, Object>();
+ if (query == null)
+ return map;
+ String[] params = query.split("&");
+ for (String param : params) {
+ String[] arr = param.split("=");
+ String name = arr[0];
+ Object value = arr.length > 1 ? param.split("=")[1] : Boolean.TRUE;
+ try {
+ map.put(URLDecoder.decode(name, UTF8),
+ URLDecoder.decode(value.toString(), UTF8));
+ } catch (UnsupportedEncodingException e) {
+ throw new SlcException("Cannot decode '" + param + "'", e);
+ }
+ }
+ return map;
+ }
+
+ /*
+ * BEAN
+ */
+ public void setModulesManager(ExecutionModulesManager modulesManager) {
+ this.modulesManager = modulesManager;
+ }
+
+ public void setDefaultModulePrefix(String defaultModulePrefix) {
+ this.defaultModulePrefix = defaultModulePrefix;
+ }
+
+ public String getAgentUuid() {
+ return agentUuid;
+ }
+
+ @Override
+ public String toString() {
+ return "Agent #" + getAgentUuid();
+ }
+}
--- /dev/null
+package org.argeo.slc.core.execution;
+
+import java.net.URI;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.security.OsAuthenticationToken;
+import org.argeo.slc.BasicNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.argeo.slc.execution.SlcAgent;
+import org.argeo.slc.execution.SlcAgentCli;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+/**
+ * Authenticates thread and executes synchronously a command line execution.
+ * Reference implementation of args to URIs algorithm.
+ */
+public class DefaultAgentCli implements SlcAgentCli {
+ private final static Log log = LogFactory.getLog(DefaultAgentCli.class);
+
+ private final static String UTF8 = "UTF-8";
+ private SlcAgent agent;
+ private AuthenticationManager authenticationManager;
+
+ private Long timeout = 24 * 60 * 60 * 1000l;
+
+ public String process(String[] args) {
+ if (SecurityContextHolder.getContext().getAuthentication() == null) {
+ OsAuthenticationToken oat = new OsAuthenticationToken();
+ Authentication authentication = authenticationManager
+ .authenticate(oat);
+ SecurityContextHolder.getContext()
+ .setAuthentication(authentication);
+ }
+
+ if (args.length > 0 && args[0].equals("help")) {
+ StringBuilder buf = new StringBuilder();
+ help(args, buf);
+ log.info("\n" + buf);
+ return buf.toString();
+ } else {
+ List<URI> uris = asURIs(args);
+ String processUuid = agent.process(uris);
+ agent.waitFor(processUuid, timeout);
+ return processUuid;
+ }
+ }
+
+ protected void help(String[] rawArgs, StringBuilder buf) {
+ String[] args = Arrays.copyOfRange(rawArgs, 1, rawArgs.length);
+ if (args.length == 0) {// modules
+ for (ExecutionModuleDescriptor emd : agent
+ .listExecutionModuleDescriptors()) {
+ appendModule(emd, buf);
+ }
+ } else if (args.length == 1 && !args[0].contains("/")) {// single module
+ NameVersion nameVersion = new BasicNameVersion(args[0]);
+ ExecutionModuleDescriptor emd = agent.getExecutionModuleDescriptor(
+ nameVersion.getName(), nameVersion.getVersion());
+ appendModule(emd, buf);
+
+ // flows
+ for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) {
+ buf.append(" ").append(efd.getName());
+ if (efd.getDescription() != null
+ && !efd.getDescription().trim().equals(""))
+ buf.append(" : ").append(" ").append(efd.getDescription());
+ buf.append('\n');
+ }
+ return;
+ } else {
+ List<URI> uris = asURIs(args);
+ for (URI uri : uris) {
+ appendUriHelp(uri, buf);
+ }
+ }
+ }
+
+ protected void appendUriHelp(URI uri, StringBuilder buf) {
+ String[] path = uri.getPath().split("/");
+ NameVersion nameVersion = new BasicNameVersion(path[1]);
+ ExecutionModuleDescriptor emd = agent.getExecutionModuleDescriptor(
+ nameVersion.getName(), nameVersion.getVersion());
+
+ StringBuilder flow = new StringBuilder();
+ for (int i = 2; i < path.length; i++)
+ flow.append('/').append(path[i]);
+ String flowPath = flow.toString();
+ ExecutionFlowDescriptor efd = findExecutionFlowDescriptor(emd, flowPath);
+ if (efd == null)
+ throw new SlcException("Flow " + uri + " not found");
+
+ appendModule(emd, buf);
+
+ buf.append(" ").append(efd.getName());
+ if (efd.getDescription() != null
+ && !efd.getDescription().trim().equals(""))
+ buf.append(" : ").append(" ").append(efd.getDescription());
+ buf.append('\n');
+ Map<String, Object> values = DefaultAgent.getQueryMap(uri.getQuery());
+ ExecutionSpec spec = efd.getExecutionSpec();
+ for (String attrKey : spec.getAttributes().keySet()) {
+ ExecutionSpecAttribute esa = spec.getAttributes().get(attrKey);
+ buf.append(" --").append(attrKey);
+ if (values.containsKey(attrKey))
+ buf.append(" ").append(values.get(attrKey));
+ if (esa.getValue() != null)
+ buf.append(" (").append(esa.getValue()).append(')');
+ buf.append('\n');
+ }
+ }
+
+ private void appendModule(ExecutionModuleDescriptor emd, StringBuilder buf) {
+ buf.append("# ").append(emd.getName());
+ if (emd.getDescription() != null
+ && !emd.getDescription().trim().equals(""))
+ buf.append(" : ").append(emd.getDescription());
+ if (emd.getVersion() != null)
+ buf.append(" (v").append(emd.getVersion()).append(")");
+ buf.append('\n');
+ }
+
+ public static List<URI> asURIs(String[] args) {
+ try {
+ List<URI> uris = new ArrayList<URI>();
+ List<String> leftOvers = new ArrayList<String>();
+
+ Boolean hasArgs = false;
+ String currKey = null;
+ StringBuilder currUri = null;
+ Iterator<String> argIt = Arrays.asList(args).iterator();
+ while (argIt.hasNext()) {
+ String arg = argIt.next();
+ if (!arg.startsWith("-")) {
+ if (currKey != null) {// value
+ currUri.append(URLEncoder.encode(arg, UTF8));
+ currKey = null;
+ } else { // module
+ if (currUri != null) {
+ uris.add(new URI(currUri.toString()));
+ }
+ currUri = new StringBuilder("flow:");
+
+ String currModule = arg;
+ currUri.append('/').append(currModule);
+ if (!arg.contains("/")) {
+ // flow path not in arg go to next arg
+ if (!argIt.hasNext())
+ throw new SlcException("No flow found");
+ String currFlow = argIt.next();
+ if (!currFlow.startsWith("/"))
+ currFlow = "/" + currFlow;
+ currUri.append(currFlow);
+ }
+ }
+ } else {
+ if (currUri == null) {// first args
+ leftOvers.add(arg);
+ } else {
+ String key;
+ if (arg.startsWith("--"))
+ key = arg.substring(2);
+ else if (arg.startsWith("-"))
+ key = arg.substring(1);
+ else {
+ throw new SlcException("Cannot intepret key: "
+ + arg);
+ }
+
+ if (!hasArgs) {
+ currUri.append('?');
+ hasArgs = true;
+ } else {
+ currUri.append('&');
+ }
+
+ // deal with boolean keys
+ if (currKey != null) {// value
+ currUri.append(URLEncoder.encode("true", UTF8));
+ currKey = null;
+ }
+
+ currKey = key;
+ currUri.append(URLEncoder.encode(key, UTF8))
+ .append('=');
+ }
+ }
+ }
+ if (currUri != null)
+ uris.add(new URI(currUri.toString()));
+ return uris;
+ } catch (Exception e) {
+ throw new SlcException("Cannot convert " + Arrays.toString(args)
+ + " to flow URI", e);
+ }
+ }
+
+ private ExecutionFlowDescriptor findExecutionFlowDescriptor(
+ ExecutionModuleDescriptor emd, String flowPath) {
+ ExecutionFlowDescriptor flowDescriptor = null;
+ for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) {
+ String name = efd.getName();
+ // normalize name as flow path
+ if (!name.startsWith("/"))
+ name = "/" + name;
+ if (name.endsWith("/"))
+ name = name.substring(0, name.length() - 1);
+ if (name.equals(flowPath)) {
+ flowDescriptor = efd;
+ break;
+ }
+ }
+ return flowDescriptor;
+ }
+
+ public void setAgent(SlcAgent agent) {
+ this.agent = agent;
+ }
+
+ public void setAuthenticationManager(
+ AuthenticationManager authenticationManager) {
+ this.authenticationManager = authenticationManager;
+ }
+
+ public void setTimeout(Long timeout) {
+ this.timeout = timeout;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.validation.MapBindingResult;
+
+/** Default implementation of an execution flow. */
+public class DefaultExecutionFlow implements ExecutionFlow, InitializingBean,
+ BeanNameAware {
+ private final static Log log = LogFactory
+ .getLog(DefaultExecutionFlow.class);
+
+ private final ExecutionSpec executionSpec;
+ private String name = null;
+ private Map<String, Object> parameters = new HashMap<String, Object>();
+ private List<Runnable> executables = new ArrayList<Runnable>();
+
+ private String path;
+
+ private Boolean failOnError = true;
+
+ public DefaultExecutionFlow() {
+ this.executionSpec = new DefaultExecutionSpec();
+ }
+
+ public DefaultExecutionFlow(ExecutionSpec executionSpec) {
+ this.executionSpec = executionSpec;
+ }
+
+ public DefaultExecutionFlow(ExecutionSpec executionSpec,
+ Map<String, Object> parameters) {
+ // be sure to have an execution spec
+ this.executionSpec = (executionSpec == null) ? new DefaultExecutionSpec()
+ : executionSpec;
+
+ // only parameters contained in the executionSpec can be set
+ for (String parameter : parameters.keySet()) {
+ if (!executionSpec.getAttributes().containsKey(parameter)) {
+ throw new SlcException("Parameter " + parameter
+ + " is not defined in the ExecutionSpec");
+ }
+ }
+
+ // set the parameters
+ this.parameters.putAll(parameters);
+
+ // check that all the required parameters are defined
+ MapBindingResult errors = new MapBindingResult(parameters, "execution#"
+ + getName());
+ for (String key : executionSpec.getAttributes().keySet()) {
+ ExecutionSpecAttribute attr = executionSpec.getAttributes()
+ .get(key);
+
+ if (attr.getIsImmutable() && !isSetAsParameter(key)) {
+ errors.rejectValue(key, "Immutable but not set");
+ break;
+ }
+
+ if (attr.getIsConstant() && !isSetAsParameter(key)) {
+ errors.rejectValue(key, "Constant but not set as parameter");
+ break;
+ }
+
+ if (attr.getIsHidden() && !isSetAsParameter(key)) {
+ errors.rejectValue(key, "Hidden but not set as parameter");
+ break;
+ }
+ }
+
+ if (errors.hasErrors())
+ throw new SlcException("Could not prepare execution flow: "
+ + errors.toString());
+
+ }
+
+ public void run() {
+ try {
+ for (Runnable executable : executables) {
+ if (Thread.interrupted()) {
+ log.error("Flow '" + getName() + "' killed before '"
+ + executable + "'");
+ Thread.currentThread().interrupt();
+ return;
+ // throw new ThreadDeath();
+ }
+ this.doExecuteRunnable(executable);
+ }
+ } catch (RuntimeException e) {
+ if (Thread.interrupted()) {
+ log.error("Flow '" + getName()
+ + "' killed while receiving an unrelated exception", e);
+ Thread.currentThread().interrupt();
+ return;
+ // throw new ThreadDeath();
+ }
+ if (failOnError)
+ throw e;
+ else {
+ log.error("Execution flow failed,"
+ + " but process did not fail"
+ + " because failOnError property"
+ + " is set to false: " + e);
+ if (log.isTraceEnabled())
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * List sub-runnables that would be executed if run() method would be
+ * called.
+ */
+ public Iterator<Runnable> runnables() {
+ return executables.iterator();
+ }
+
+ /**
+ * If there is one and only one runnable wrapped return it, throw an
+ * exeception otherwise.
+ */
+ public Runnable getRunnable() {
+ if (executables.size() == 1)
+ return executables.get(0);
+ else
+ throw new SlcException("There are " + executables.size()
+ + " runnables in flow " + getName());
+ }
+
+ public void doExecuteRunnable(Runnable runnable) {
+ runnable.run();
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ if (path == null) {
+ if (name.charAt(0) == '/') {
+ path = name.substring(0, name.lastIndexOf('/'));
+ }
+ }
+
+ if (path != null) {
+ for (Runnable executable : executables) {
+ if (executable instanceof DefaultExecutionFlow) {
+ // so we don't need to have DefaultExecutionFlow
+ // implementing StructureAware
+ // FIXME: probably has side effects
+ DefaultExecutionFlow flow = (DefaultExecutionFlow) executable;
+ String newPath = path + '/' + flow.getName();
+ flow.setPath(newPath);
+ log.warn(newPath + " was forcibly set on " + flow);
+ }
+ }
+ }
+ }
+
+ public void setBeanName(String name) {
+ this.name = name;
+ }
+
+ public void setExecutables(List<Runnable> executables) {
+ this.executables = executables;
+ }
+
+ public void setParameters(Map<String, Object> attributes) {
+ this.parameters = attributes;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public ExecutionSpec getExecutionSpec() {
+ return executionSpec;
+ }
+
+ public Object getParameter(String parameterName) {
+ // Verify that there is a spec attribute
+ ExecutionSpecAttribute specAttr = null;
+ if (executionSpec.getAttributes().containsKey(parameterName)) {
+ specAttr = executionSpec.getAttributes().get(parameterName);
+ } else {
+ throw new SlcException("Key " + parameterName
+ + " is not defined in the specifications of " + toString());
+ }
+
+ if (parameters.containsKey(parameterName)) {
+ Object paramValue = parameters.get(parameterName);
+ return paramValue;
+ } else {
+ if (specAttr.getValue() != null) {
+ return specAttr.getValue();
+ }
+ }
+ throw new SlcException("Key " + parameterName
+ + " is not set as parameter in " + toString());
+ }
+
+ public Boolean isSetAsParameter(String key) {
+ return parameters.containsKey(key)
+ || (executionSpec.getAttributes().containsKey(key) && executionSpec
+ .getAttributes().get(key).getValue() != null);
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuffer("Execution flow ").append(name).toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return ((ExecutionFlow) obj).getName().equals(name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public Boolean getFailOnError() {
+ return failOnError;
+ }
+
+ public void setFailOnError(Boolean failOnError) {
+ this.failOnError = failOnError;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.springframework.aop.scope.ScopedObject;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.util.StringUtils;
+
+/**
+ * Performs conversion in both direction between data exchanged with the agent
+ * and the data in the application context.
+ */
+public class DefaultExecutionFlowDescriptorConverter implements
+ ExecutionFlowDescriptorConverter, ApplicationContextAware {
+ public final static String REF_VALUE_TYPE_BEAN_NAME = "beanName";
+
+ /** Workaround for https://www.spartadn.com/bugzilla/show_bug.cgi?id=206 */
+ private final static String REF_VALUE_INTERNAL = "[internal]";
+
+ private final static Log log = LogFactory
+ .getLog(DefaultExecutionFlowDescriptorConverter.class);
+
+ private ApplicationContext applicationContext;
+
+ @SuppressWarnings("unused")
+ public Map<String, Object> convertValues(
+ ExecutionFlowDescriptor executionFlowDescriptor) {
+ Map<String, Object> values = executionFlowDescriptor.getValues();
+ Map<String, Object> convertedValues = new HashMap<String, Object>();
+ ExecutionSpec executionSpec = executionFlowDescriptor
+ .getExecutionSpec();
+
+ if (executionSpec == null && log.isTraceEnabled())
+ log.warn("Execution spec is null for " + executionFlowDescriptor);
+
+ if (values != null && executionSpec != null) {
+ values: for (String key : values.keySet()) {
+ ExecutionSpecAttribute attribute = executionSpec
+ .getAttributes().get(key);
+
+ if (attribute == null)
+ throw new FlowConfigurationException(
+ "No spec attribute defined for '" + key + "'");
+
+ if (attribute.getIsConstant())
+ continue values;
+
+ Object value = values.get(key);
+ if (value instanceof PrimitiveValue) {
+ PrimitiveValue primitiveValue = (PrimitiveValue) value;
+ // TODO: check class <=> type
+ convertedValues.put(key, primitiveValue.getValue());
+ } else if (value instanceof RefValue) {
+ RefValue refValue = (RefValue) value;
+ String type = refValue.getType();
+ if (REF_VALUE_TYPE_BEAN_NAME.equals(type)) {
+ // FIXME: UI should send all information about spec
+ // - targetClass
+ // - name
+ // String executionSpecName = executionSpec.getName();
+ // ExecutionSpec localSpec = (ExecutionSpec)
+ // applicationContext
+ // .getBean(executionSpecName);
+ // RefSpecAttribute localAttr = (RefSpecAttribute)
+ // localSpec
+ // .getAttributes().get(key);
+ // Class<?> targetClass = localAttr.getTargetClass();
+ //
+ // String primitiveType = PrimitiveUtils
+ // .classAsType(targetClass);
+ String primitiveType = null;
+ if (primitiveType != null) {
+ // not active
+ String ref = refValue.getRef();
+ Object obj = PrimitiveUtils.convert(primitiveType,
+ ref);
+ convertedValues.put(key, obj);
+ } else {
+ String ref = refValue.getRef();
+ if (ref != null && !ref.equals(REF_VALUE_INTERNAL)) {
+ Object obj = null;
+ if (applicationContext.containsBean(ref)) {
+ obj = applicationContext.getBean(ref);
+ } else {
+ // FIXME: hack in order to pass primitive
+ obj = ref;
+ }
+ convertedValues.put(key, obj);
+ } else {
+ log.warn("Cannot interpret " + refValue);
+ }
+ }
+ } else if (PrimitiveUtils.typeAsClass(type) != null) {
+ String ref = refValue.getRef();
+ Object obj = PrimitiveUtils.convert(type, ref);
+ convertedValues.put(key, obj);
+ } else {
+ throw new FlowConfigurationException(
+ "Ref value type not supported: "
+ + refValue.getType());
+ }
+ } else {
+ // default is to take the value as is
+ convertedValues.put(key, value);
+ }
+ }
+ }
+ return convertedValues;
+ }
+
+ public void addFlowsToDescriptor(ExecutionModuleDescriptor md,
+ Map<String, ExecutionFlow> executionFlows) {
+ SortedSet<ExecutionFlowDescriptor> set = new TreeSet<ExecutionFlowDescriptor>(
+ new ExecutionFlowDescriptorComparator());
+ for (String name : executionFlows.keySet()) {
+ ExecutionFlow executionFlow = executionFlows.get(name);
+
+ ExecutionFlowDescriptor efd = getExecutionFlowDescriptor(executionFlow);
+ ExecutionSpec executionSpec = efd.getExecutionSpec();
+
+ // Add execution spec if necessary
+ if (!md.getExecutionSpecs().contains(executionSpec))
+ md.getExecutionSpecs().add(executionSpec);
+
+ // Add execution flow
+ set.add(efd);
+ // md.getExecutionFlows().add(efd);
+ }
+ md.getExecutionFlows().addAll(set);
+ }
+
+ @SuppressWarnings("deprecation")
+ public ExecutionFlowDescriptor getExecutionFlowDescriptor(
+ ExecutionFlow executionFlow) {
+ if (executionFlow.getName() == null)
+ throw new FlowConfigurationException("Flow name is null: "
+ + executionFlow);
+ String name = executionFlow.getName();
+
+ ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
+ if (executionSpec == null)
+ throw new FlowConfigurationException("Execution spec is null: "
+ + executionFlow);
+ if (executionSpec.getName() == null)
+ throw new FlowConfigurationException(
+ "Execution spec name is null: " + executionSpec);
+
+ Map<String, Object> values = new TreeMap<String, Object>();
+ for (String key : executionSpec.getAttributes().keySet()) {
+ ExecutionSpecAttribute attribute = executionSpec.getAttributes()
+ .get(key);
+
+ if (attribute instanceof PrimitiveSpecAttribute) {
+ if (executionFlow.isSetAsParameter(key)) {
+ Object value = executionFlow.getParameter(key);
+ PrimitiveValue primitiveValue = new PrimitiveValue();
+ primitiveValue.setType(((PrimitiveSpecAttribute) attribute)
+ .getType());
+ primitiveValue.setValue(value);
+ values.put(key, primitiveValue);
+ } else {
+ // no need to add a primitive value if it is not set,
+ // all necessary information is in the spec
+ }
+ } else if (attribute instanceof RefSpecAttribute) {
+ if (attribute.getIsConstant()) {
+ values.put(key, new RefValue(REF_VALUE_INTERNAL));
+ } else
+ values.put(
+ key,
+ buildRefValue((RefSpecAttribute) attribute,
+ executionFlow, key));
+ } else {
+ throw new FlowConfigurationException(
+ "Unkown spec attribute type " + attribute.getClass());
+ }
+
+ }
+
+ ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name, null,
+ values, executionSpec);
+ if (executionFlow.getPath() != null)
+ efd.setPath(executionFlow.getPath());
+ else
+ efd.setPath("");
+
+ // Takes description from spring
+ BeanFactory bf = getBeanFactory();
+ if (bf != null) {
+ BeanDefinition bd = getBeanFactory().getBeanDefinition(name);
+ efd.setDescription(bd.getDescription());
+ }
+ return efd;
+ }
+
+ @SuppressWarnings(value = { "unchecked" })
+ protected RefValue buildRefValue(RefSpecAttribute rsa,
+ ExecutionFlow executionFlow, String key) {
+ RefValue refValue = new RefValue();
+ // FIXME: UI should be able to deal with other types
+ refValue.setType(REF_VALUE_TYPE_BEAN_NAME);
+ Class<?> targetClass = rsa.getTargetClass();
+ String primitiveType = PrimitiveUtils.classAsType(targetClass);
+ if (primitiveType != null) {
+ if (executionFlow.isSetAsParameter(key)) {
+ Object value = executionFlow.getParameter(key);
+ refValue.setRef(value.toString());
+ }
+ refValue.setType(primitiveType);
+ return refValue;
+ } else {
+
+ if (executionFlow.isSetAsParameter(key)) {
+ String ref = null;
+ Object value = executionFlow.getParameter(key);
+ if (applicationContext == null) {
+ log.warn("No application context declared, cannot scan ref value.");
+ ref = value.toString();
+ } else {
+
+ // look for a ref to the value
+ Map<String, ?> beans = getBeanFactory()
+ .getBeansOfType(targetClass, false, false);
+ // TODO: also check scoped beans
+ beans: for (String beanName : beans.keySet()) {
+ Object obj = beans.get(beanName);
+ if (value instanceof ScopedObject) {
+ // don't call methods of the target of the scope
+ if (obj instanceof ScopedObject)
+ if (value == obj) {
+ ref = beanName;
+ break beans;
+ }
+ } else {
+ if (obj.equals(value)) {
+ ref = beanName;
+ break beans;
+ }
+ }
+ }
+ }
+ if (ref == null) {
+ if (log.isTraceEnabled())
+ log.trace("Cannot define reference for ref spec attribute "
+ + key
+ + " in "
+ + executionFlow
+ + " ("
+ + rsa
+ + ")."
+ + " If it is an inner bean consider put it frozen.");
+ ref = REF_VALUE_INTERNAL;
+ } else {
+ if (log.isTraceEnabled())
+ log.trace(ref
+ + " is the reference for ref spec attribute "
+ + key + " in " + executionFlow + " (" + rsa
+ + ")");
+ }
+ refValue.setRef(ref);
+ }
+ return refValue;
+ }
+ }
+
+ /** @return can be null */
+ private ConfigurableListableBeanFactory getBeanFactory() {
+ if (applicationContext == null)
+ return null;
+ return ((ConfigurableApplicationContext) applicationContext)
+ .getBeanFactory();
+ }
+
+ /** Must be use within the execution application context */
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+ private static class ExecutionFlowDescriptorComparator implements
+ Comparator<ExecutionFlowDescriptor> {
+ @SuppressWarnings("deprecation")
+ public int compare(ExecutionFlowDescriptor o1,
+ ExecutionFlowDescriptor o2) {
+ // TODO: write unit tests for this
+
+ String name1 = o1.getName();
+ String name2 = o2.getName();
+
+ String path1 = o1.getPath();
+ String path2 = o2.getPath();
+
+ // Check whether name include path
+ int lastIndex1 = name1.lastIndexOf('/');
+ // log.debug(name1+", "+lastIndex1);
+ if (!StringUtils.hasText(path1) && lastIndex1 >= 0) {
+ path1 = name1.substring(0, lastIndex1);
+ name1 = name1.substring(lastIndex1 + 1);
+ }
+
+ int lastIndex2 = name2.lastIndexOf('/');
+ if (!StringUtils.hasText(path2) && lastIndex2 >= 0) {
+ path2 = name2.substring(0, lastIndex2);
+ name2 = name2.substring(lastIndex2 + 1);
+ }
+
+ // Perform the actual comparison
+ if (StringUtils.hasText(path1) && StringUtils.hasText(path2)) {
+ if (path1.equals(path2))
+ return name1.compareTo(name2);
+ else if (path1.startsWith(path2))
+ return -1;
+ else if (path2.startsWith(path1))
+ return 1;
+ else
+ return path1.compareTo(path2);
+ } else if (!StringUtils.hasText(path1)
+ && StringUtils.hasText(path2)) {
+ return 1;
+ } else if (StringUtils.hasText(path1)
+ && !StringUtils.hasText(path2)) {
+ return -1;
+ } else if (!StringUtils.hasText(path1)
+ && !StringUtils.hasText(path2)) {
+ return name1.compareTo(name2);
+ } else {
+ return 0;
+ }
+ }
+
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+
+/** Spring based implementation of execution specifications. */
+public class DefaultExecutionSpec implements ExecutionSpec, BeanNameAware,
+ ApplicationContextAware, InitializingBean, Serializable {
+ private static final long serialVersionUID = 5159882223926926539L;
+ private final static Log log = LogFactory
+ .getLog(DefaultExecutionSpec.class);
+ private transient ApplicationContext applicationContext;
+
+ private String description;
+ private Map<String, ExecutionSpecAttribute> attributes = new HashMap<String, ExecutionSpecAttribute>();
+
+ private String name = INTERNAL_NAME;
+
+ public Map<String, ExecutionSpecAttribute> getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(Map<String, ExecutionSpecAttribute> attributes) {
+ this.attributes = attributes;
+ }
+
+ public void setBeanName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * The Spring bean name (only relevant for specs declared has high-level
+ * beans)
+ */
+ public String getName() {
+ return name;
+ }
+
+ public boolean equals(Object obj) {
+ return ((ExecutionSpec) obj).getName().equals(name);
+ }
+
+ /**
+ * The Spring bean description (only relevant for specs declared has
+ * high-level beans)
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ private ConfigurableListableBeanFactory getBeanFactory() {
+ return ((ConfigurableApplicationContext) applicationContext)
+ .getBeanFactory();
+ }
+
+ public void setApplicationContext(ApplicationContext applicationContext) {
+ this.applicationContext = applicationContext;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ if (description == null) {
+ try {
+ description = getBeanFactory().getBeanDefinition(name)
+ .getDescription();
+ } catch (NoSuchBeanDefinitionException e) {
+ // silent
+ }
+ }
+
+ for (String key : attributes.keySet()) {
+ ExecutionSpecAttribute attr = attributes.get(key);
+ if (attr instanceof RefSpecAttribute) {
+ RefSpecAttribute rsa = (RefSpecAttribute) attr;
+ if (rsa.getChoices() == null) {
+ List<RefValueChoice> choices = buildRefValueChoices(rsa);
+ rsa.setChoices(choices);
+ }
+ if (log.isTraceEnabled())
+ log.debug("Spec attr " + key + " has "
+ + rsa.getChoices().size() + " choices");
+ }
+ }
+ }
+
+ /**
+ * Generates a list of ref value choices based on the bean available in the
+ * application ocntext.
+ */
+ protected List<RefValueChoice> buildRefValueChoices(RefSpecAttribute rsa) {
+ List<RefValueChoice> choices = new ArrayList<RefValueChoice>();
+ if (applicationContext == null) {
+ log.warn("No application context declared,"
+ + " cannot scan ref value choices.");
+ return choices;
+ }
+
+ beanNames: for (String beanName : getBeanFactory().getBeanNamesForType(
+ rsa.getTargetClass(), true, false)) {
+
+ // Since Spring 3, systemProperties is implicitly defined but has no
+ // bean definition
+ if (beanName.equals("systemProperties"))
+ continue beanNames;
+
+ BeanDefinition bd = getBeanFactory().getBeanDefinition(beanName);
+ RefValueChoice choice = new RefValueChoice();
+ choice.setName(beanName);
+ choice.setDescription(bd.getDescription());
+ if (log.isTraceEnabled())
+ log.debug("Found choice " + beanName + " for " + rsa);
+
+ choices.add(choice);
+
+ }
+ return choices;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+import java.util.UUID;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.argeo.slc.execution.ExecutionStack;
+
+/** Canonical implementation of an execution stack. */
+public class DefaultExecutionStack implements ExecutionStack {
+
+ private final static Log log = LogFactory
+ .getLog(DefaultExecutionStack.class);
+
+ private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
+
+ public synchronized void enterFlow(ExecutionFlow executionFlow) {
+ ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
+ stack.push(runtime);
+
+ Map<String, ExecutionSpecAttribute> specAttrs = executionFlow
+ .getExecutionSpec().getAttributes();
+ for (String key : specAttrs.keySet()) {
+ if (executionFlow.isSetAsParameter(key)) {
+ runtime.getLocalVariables().put(key,
+ executionFlow.getParameter(key));
+ }
+ }
+ }
+
+ public synchronized String getCurrentStackLevelUuid() {
+ return stack.peek().getUuid();
+ }
+
+ public synchronized Integer getStackSize() {
+ return stack.size();
+ }
+
+ /**
+ * Looks for a set variable in the stack, starting at the upper flows
+ *
+ * @return the variable or <code>null</code> if not found
+ */
+ public synchronized Object findLocalVariable(String key) {
+ Object obj = null;
+ for (int i = 0; i < stack.size(); i++) {
+ if (stack.get(i).getLocalVariables().containsKey(key)) {
+ obj = stack.get(i).getLocalVariables().get(key);
+ break;
+ }
+ }
+ return obj;
+ }
+
+ public synchronized void leaveFlow(ExecutionFlow executionFlow) {
+ ExecutionFlowRuntime leftEf = stack.pop();
+
+ if (!leftEf.getExecutionFlow().getName()
+ .equals(executionFlow.getName()))
+ throw new SlcException("Asked to leave " + executionFlow
+ + " but last is " + leftEf);
+
+ leftEf.getScopedObjects().clear();
+ leftEf.getLocalVariables().clear();
+ }
+
+ public synchronized void addScopedObject(String name, Object obj) {
+ ExecutionFlowRuntime runtime = stack.peek();
+ // TODO: check that the object is not set yet ?
+ if (log.isDebugEnabled()) {
+ Object existing = findScopedObject(name);
+ if (existing != null)
+ log.warn("Scoped object " + name + " of type " + obj.getClass()
+ + " already registered in " + runtime);
+ }
+ runtime.getScopedObjects().put(name, obj);
+ }
+
+ /** @return </code>null<code> if not found */
+ public synchronized Object findScopedObject(String name) {
+ Object obj = null;
+ for (int i = stack.size() - 1; i >= 0; i--) {
+ if (stack.get(i).getScopedObjects().containsKey(name)) {
+ obj = stack.get(i).getScopedObjects().get(name);
+ break;
+ }
+ }
+ return obj;
+ }
+
+ protected static class ExecutionFlowRuntime {
+ private final ExecutionFlow executionFlow;
+ private final Map<String, Object> scopedObjects = new HashMap<String, Object>();
+ private final Map<String, Object> localVariables = new HashMap<String, Object>();
+ private final String uuid = UUID.randomUUID().toString();
+
+ public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
+ this.executionFlow = executionFlow;
+ }
+
+ public ExecutionFlow getExecutionFlow() {
+ return executionFlow;
+ }
+
+ public Map<String, Object> getScopedObjects() {
+ return scopedObjects;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public Map<String, Object> getLocalVariables() {
+ return localVariables;
+ }
+
+ @Override
+ public String toString() {
+ return "Stack Level #" + uuid;
+ }
+
+ }
+}
--- /dev/null
+package org.argeo.slc.core.execution;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.ExecutionStep;
+import org.argeo.slc.execution.RealizedFlow;
+
+/** Canonical implementation of an {@link ExecutionProcess} as a bean. */
+public class DefaultProcess implements ExecutionProcess {
+ private String uuid = UUID.randomUUID().toString();
+ private String status = ExecutionProcess.NEW;
+
+ private List<ExecutionStep> steps = new ArrayList<ExecutionStep>();
+ private List<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public void addSteps(List<ExecutionStep> steps) {
+ steps.addAll(steps);
+ }
+
+ public List<RealizedFlow> getRealizedFlows() {
+ return realizedFlows;
+ }
+
+ public List<ExecutionStep> getSteps() {
+ return steps;
+ }
+
+ public void setSteps(List<ExecutionStep> steps) {
+ this.steps = steps;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public void setRealizedFlows(List<RealizedFlow> realizedFlows) {
+ this.realizedFlows = realizedFlows;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionStack;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+
+@Aspect
+/** Aspect intercepting calls on execution flows and contexts. */
+public class ExecutionAspect {
+ private final static Log log = LogFactory.getLog(ExecutionAspect.class);
+
+ private ExecutionStack executionStack;
+ private ExecutionContext executionContext;
+
+ @Around("flowExecution()")
+ public void aroundFlow(ProceedingJoinPoint pjp) throws Throwable {
+ // IMPORTANT: Make sure that the execution context is called before the
+ // execution stack
+ executionContext.getUuid();
+
+ ExecutionFlow executionFlow = (ExecutionFlow) pjp.getTarget();
+ executionStack.enterFlow(executionFlow);
+ executionContext.setVariable(ExecutionContext.VAR_FLOW_ID,
+ executionStack.getCurrentStackLevelUuid());
+ executionContext.setVariable(ExecutionContext.VAR_FLOW_NAME,
+ executionFlow.getName());
+
+ logStackEvent("=> ", executionFlow);
+ try {
+ // Actually execute the flow
+ pjp.proceed();
+ } finally {
+ logStackEvent("<= ", executionFlow);
+ executionStack.leaveFlow(executionFlow);
+ }
+ }
+
+ @Around("getVariable()")
+ public Object aroundGetVariable(ProceedingJoinPoint pjp) throws Throwable {
+ Object obj = pjp.proceed();
+ // if the variable was not found, look in the stack starting at the
+ // upper flows
+ if (obj == null) {
+ String key = pjp.getArgs()[0].toString();
+ obj = executionStack.findLocalVariable(key);
+ }
+ return obj;
+ }
+
+ @Pointcut("execution(void org.argeo.slc.execution.ExecutionFlow.run())")
+ public void flowExecution() {
+ }
+
+ @Pointcut("execution(* org.argeo.slc.execution.ExecutionContext.getVariable(..))")
+ public void getVariable() {
+ }
+
+ public void setExecutionStack(ExecutionStack executionStack) {
+ this.executionStack = executionStack;
+ }
+
+ public void setExecutionContext(ExecutionContext executionContext) {
+ this.executionContext = executionContext;
+ }
+
+ protected void logStackEvent(String symbol, ExecutionFlow executionFlow) {
+ Integer stackSize = executionStack.getStackSize();
+ if (log.isTraceEnabled())
+ log.debug(depthSpaces(stackSize) + symbol + executionFlow + " #"
+ + executionStack.getCurrentStackLevelUuid() + ", depth="
+ + stackSize);
+ if (log.isDebugEnabled())
+ log.debug(depthSpaces(stackSize) + symbol + executionFlow);
+ }
+
+ protected void logRunnableExecution(ExecutionFlow executionFlow,
+ Runnable runnable) {
+ Integer stackSize = executionStack.getStackSize();
+ if (log.isDebugEnabled())
+ log.debug(depthSpaces(stackSize + 1)
+ + runnable.getClass().getSimpleName() + " in "
+ + executionFlow);
+ }
+
+ private String depthSpaces(int depth) {
+ StringBuffer buf = new StringBuffer(depth * 2);
+ for (int i = 0; i < depth; i++)
+ buf.append(" ");
+ return buf.toString();
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution;\r
+\r
+import java.beans.PropertyDescriptor;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.execution.ExecutionContext;\r
+import org.argeo.slc.execution.ExecutionFlow;\r
+import org.springframework.beans.BeansException;\r
+import org.springframework.beans.MutablePropertyValues;\r
+import org.springframework.beans.PropertyValue;\r
+import org.springframework.beans.PropertyValues;\r
+import org.springframework.beans.factory.BeanDefinitionStoreException;\r
+import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;\r
+import org.springframework.beans.factory.config.TypedStringValue;\r
+import org.springframework.beans.factory.support.ManagedList;\r
+import org.springframework.beans.factory.support.ManagedMap;\r
+import org.springframework.beans.factory.support.ManagedSet;\r
+import org.springframework.util.ObjectUtils;\r
+import org.springframework.util.StringUtils;\r
+\r
+/**\r
+ * Spring post processor which ensures that execution parameters are properly\r
+ * set. It is used at two levels: first during instantiation for instantiation\r
+ * parameters which allow to implement templates, then at runtime in order to\r
+ * interpret @{} placeholders when object of scope execution are instantiated.\r
+ */\r
+public class ExecutionParameterPostProcessor extends\r
+ InstantiationAwareBeanPostProcessorAdapter {\r
+\r
+ private final static Log log = LogFactory\r
+ .getLog(ExecutionParameterPostProcessor.class);\r
+\r
+ private ExecutionContext executionContext;\r
+ private InstantiationManager instantiationManager;\r
+\r
+ private String placeholderPrefix = "@{";\r
+ private String placeholderSuffix = "}";\r
+ private String nullValue;\r
+\r
+ @Override\r
+ public PropertyValues postProcessPropertyValues(PropertyValues pvs,\r
+ PropertyDescriptor[] pds, Object bean, String beanName)\r
+ throws BeansException {\r
+\r
+ // TODO: resolve at execution only if scope is execution\r
+ // TODO: deal with placeholders in RuntimeBeanReference and\r
+ // RuntimeBeanNameReference\r
+\r
+ MutablePropertyValues newPvs = new MutablePropertyValues();\r
+\r
+ boolean changesOccured = false;\r
+\r
+ for (PropertyValue pv : pvs.getPropertyValues()) {\r
+ Object convertedValue = resolveValue(beanName, bean, pv.getValue());\r
+ newPvs.addPropertyValue(new PropertyValue(pv, convertedValue));\r
+ if (convertedValue != pv.getValue()) {\r
+ changesOccured = true;\r
+ }\r
+ }\r
+\r
+ return changesOccured ? newPvs : pvs;\r
+ }\r
+\r
+ @Override\r
+ public boolean postProcessAfterInstantiation(Object bean, String beanName)\r
+ throws BeansException {\r
+ if (bean instanceof ExecutionFlow)\r
+ instantiationManager.flowInitializationStarted(\r
+ (ExecutionFlow) bean, beanName);\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public Object postProcessAfterInitialization(Object bean, String beanName)\r
+ throws BeansException {\r
+ if (bean instanceof ExecutionFlow)\r
+ instantiationManager.flowInitializationFinished(\r
+ (ExecutionFlow) bean, beanName);\r
+ return bean;\r
+ }\r
+\r
+ protected String resolvePlaceholder(Object bean, String placeholder) {\r
+ if (instantiationManager.isInFlowInitialization())\r
+ return instantiationManager.getInitializingFlowParameter(\r
+ placeholder).toString();\r
+\r
+ else {// execution\r
+ // next call fail if no execution context available\r
+ Object obj = executionContext.getVariable(placeholder);\r
+ if (obj != null) {\r
+ return obj.toString();\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ @SuppressWarnings(value = { "unchecked" })\r
+ public Object resolveValue(String beanName, Object bean, Object value) {\r
+ if (value instanceof TypedStringValue) {\r
+ TypedStringValue tsv = (TypedStringValue) value;\r
+ String originalValue = tsv.getValue();\r
+\r
+ String convertedValue = resolveString(beanName, bean, originalValue);\r
+ if (convertedValue == null)\r
+ return null;\r
+ return convertedValue.equals(originalValue) ? value\r
+ : new TypedStringValue(convertedValue);\r
+ } else if (value instanceof String) {\r
+ String originalValue = value.toString();\r
+ String convertedValue = resolveString(beanName, bean, originalValue);\r
+ if (convertedValue == null)\r
+ return null;\r
+ return convertedValue.equals(originalValue) ? value\r
+ : convertedValue;\r
+ } else if (value instanceof ManagedMap) {\r
+ Map<?, ?> mapVal = (Map<?, ?>) value;\r
+\r
+ Map<Object, Object> newContent = new ManagedMap();\r
+ boolean entriesModified = false;\r
+ for (Iterator<?> it = mapVal.entrySet().iterator(); it.hasNext();) {\r
+ Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next();\r
+ Object key = entry.getKey();\r
+ int keyHash = (key != null ? key.hashCode() : 0);\r
+ Object newKey = resolveValue(beanName, bean, key);\r
+ int newKeyHash = (newKey != null ? newKey.hashCode() : 0);\r
+ Object val = entry.getValue();\r
+ Object newVal = resolveValue(beanName, bean, val);\r
+ newContent.put(newKey, newVal);\r
+ entriesModified = entriesModified\r
+ || (newVal != val || newKey != key || newKeyHash != keyHash);\r
+ }\r
+\r
+ return entriesModified ? newContent : value;\r
+ } else if (value instanceof ManagedList) {\r
+ List<?> listVal = (List<?>) value;\r
+ List<Object> newContent = new ManagedList();\r
+ boolean valueModified = false;\r
+\r
+ for (int i = 0; i < listVal.size(); i++) {\r
+ Object elem = listVal.get(i);\r
+ Object newVal = resolveValue(beanName, bean, elem);\r
+ newContent.add(newVal);\r
+ if (!ObjectUtils.nullSafeEquals(newVal, elem)) {\r
+ valueModified = true;\r
+ }\r
+ }\r
+ return valueModified ? newContent : value;\r
+ } else if (value instanceof ManagedSet) {\r
+ Set<?> setVal = (Set<?>) value;\r
+ Set<Object> newContent = new ManagedSet();\r
+ boolean entriesModified = false;\r
+ for (Iterator<?> it = setVal.iterator(); it.hasNext();) {\r
+ Object elem = it.next();\r
+ int elemHash = (elem != null ? elem.hashCode() : 0);\r
+ Object newVal = resolveValue(beanName, bean, elem);\r
+ int newValHash = (newVal != null ? newVal.hashCode() : 0);\r
+ newContent.add(newVal);\r
+ entriesModified = entriesModified\r
+ || (newVal != elem || newValHash != elemHash);\r
+ }\r
+ return entriesModified ? newContent : value;\r
+ } else {\r
+ // log.debug(beanName + ": " + value.getClass() + " : " + value);\r
+ return value;\r
+ }\r
+\r
+ }\r
+\r
+ private String resolveString(String beanName, Object bean, String strVal) {\r
+ // in case <null/> is passed\r
+ if (strVal == null)\r
+ return null;\r
+\r
+ String value = parseStringValue(bean, strVal, new HashSet<String>());\r
+\r
+ if (value == null)\r
+ throw new SlcException("Could not resolve placeholder '" + strVal\r
+ + "' in bean '" + beanName + "'");\r
+\r
+ return (value.equals(nullValue) ? null : value);\r
+ }\r
+\r
+ public void setPlaceholderPrefix(String placeholderPrefix) {\r
+ this.placeholderPrefix = placeholderPrefix;\r
+ }\r
+\r
+ public void setPlaceholderSuffix(String placeholderSuffix) {\r
+ this.placeholderSuffix = placeholderSuffix;\r
+ }\r
+\r
+ public void setNullValue(String nullValue) {\r
+ this.nullValue = nullValue;\r
+ }\r
+\r
+ public void setInstantiationManager(\r
+ InstantiationManager instantiationManager) {\r
+ this.instantiationManager = instantiationManager;\r
+ }\r
+\r
+ public void setExecutionContext(ExecutionContext executionContext) {\r
+ this.executionContext = executionContext;\r
+ }\r
+\r
+ //\r
+ // Following methods hacked from the internals of\r
+ // PropertyPlaceholderConfigurer\r
+ //\r
+\r
+ protected String parseStringValue(Object bean, String strVal,\r
+ Set<String> visitedPlaceholders)\r
+ throws BeanDefinitionStoreException {\r
+\r
+ // in case <null/> is passed\r
+ if (strVal == null)\r
+ return null;\r
+\r
+ StringBuffer buf = new StringBuffer(strVal);\r
+\r
+ int startIndex = strVal.indexOf(placeholderPrefix);\r
+ while (startIndex != -1) {\r
+ int endIndex = findPlaceholderEndIndex(buf, startIndex);\r
+ if (endIndex != -1) {\r
+ String placeholder = buf.substring(startIndex\r
+ + placeholderPrefix.length(), endIndex);\r
+ if (!visitedPlaceholders.add(placeholder)) {\r
+ throw new BeanDefinitionStoreException(\r
+ "Circular placeholder reference '" + placeholder\r
+ + "' in property definitions");\r
+ }\r
+ // Recursive invocation, parsing placeholders contained in\r
+ // the placeholder key.\r
+ placeholder = parseStringValue(bean, placeholder,\r
+ visitedPlaceholders);\r
+ // Now obtain the value for the fully resolved key...\r
+ String propVal = resolvePlaceholder(bean, placeholder);\r
+ if (propVal != null) {\r
+ // Recursive invocation, parsing placeholders contained\r
+ // in the\r
+ // previously resolved placeholder value.\r
+ propVal = parseStringValue(bean, propVal,\r
+ visitedPlaceholders);\r
+ buf.replace(startIndex,\r
+ endIndex + placeholderSuffix.length(), propVal);\r
+ if (log.isTraceEnabled()) {\r
+ log.trace("Resolved placeholder '" + placeholder + "'");\r
+ }\r
+ startIndex = buf.indexOf(placeholderPrefix, startIndex\r
+ + propVal.length());\r
+ } else {\r
+ throw new BeanDefinitionStoreException(\r
+ "Could not resolve placeholder '" + placeholder\r
+ + "'");\r
+ }\r
+ visitedPlaceholders.remove(placeholder);\r
+ } else {\r
+ startIndex = -1;\r
+ }\r
+ }\r
+\r
+ return buf.toString();\r
+ }\r
+\r
+ private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {\r
+ int index = startIndex + placeholderPrefix.length();\r
+ int withinNestedPlaceholder = 0;\r
+ while (index < buf.length()) {\r
+ if (StringUtils.substringMatch(buf, index, placeholderSuffix)) {\r
+ if (withinNestedPlaceholder > 0) {\r
+ withinNestedPlaceholder--;\r
+ index = index + placeholderSuffix.length();\r
+ } else {\r
+ return index;\r
+ }\r
+ } else if (StringUtils\r
+ .substringMatch(buf, index, placeholderPrefix)) {\r
+ withinNestedPlaceholder++;\r
+ index = index + placeholderPrefix.length();\r
+ } else {\r
+ index++;\r
+ }\r
+ }\r
+ return -1;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+
+import org.springframework.core.io.Resource;
+
+/** Provides write access to resources during execution */
+public interface ExecutionResources {
+ /** The base directory where this execution can write */
+ public File getWritableBaseDir();
+
+ /** Allocates a local file in the writable area and return it as a resource. */
+ public Resource getWritableResource(String relativePath);
+
+ /**
+ * Allocates a local file in the writable area and return it as a fully
+ * qualified OS path.
+ */
+ public String getWritableOsPath(String relativePath);
+
+ /**
+ * Allocates a local file in the writable area and return it as a
+ * {@link File}.
+ */
+ public File getWritableOsFile(String relativePath);
+
+ /**
+ * Returns the resource as a file path. If the resource is not writable it
+ * is copied as a file in the writable area and the path to this local file
+ * is returned.
+ */
+ public String getAsOsPath(Resource resource, Boolean overwrite);
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.core.io.Resource;
+import org.springframework.util.Assert;
+
+/** Workaround when execution placedholders needs to be passed.*/
+public class ExecutionResourcesFactoryBean implements FactoryBean {
+ private ExecutionResources executionResources;
+ private String relativePath;
+
+ public Object getObject() throws Exception {
+ Assert.notNull(executionResources, "executionResources is null");
+ Assert.notNull(relativePath, "relativePath is null");
+ return executionResources.getWritableResource(relativePath);
+ }
+
+ public Class<? extends Object> getObjectType() {
+ return Resource.class;
+ }
+
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public void setExecutionResources(ExecutionResources executionResources) {
+ this.executionResources = executionResources;
+ }
+
+ public void setRelativePath(String relativePath) {
+ this.relativePath = relativePath;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.UnsupportedException;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionStack;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.beans.factory.config.Scope;
+
+/**
+ * When Spring beans are instantiated with this scope, the same instance is
+ * reused across an execution.
+ */
+public class ExecutionScope implements Scope {
+ private final static Log log = LogFactory.getLog(ExecutionScope.class);
+
+ private final ThreadLocal<ExecutionStack> executionStack = new ThreadLocal<ExecutionStack>();
+ public final ThreadLocal<String> executionStackBeanName = new ThreadLocal<String>();
+
+ private final ThreadLocal<ExecutionContext> executionContext = new ThreadLocal<ExecutionContext>();
+ private final ThreadLocal<String> executionContextBeanName = new ThreadLocal<String>();
+
+ public Object get(String name, ObjectFactory objectFactory) {
+ if (log.isTraceEnabled())
+ log.debug("Get execution scoped bean " + name);
+
+ // shortcuts
+ if (executionStackBeanName.get() != null
+ && name.equals(executionStackBeanName.get())) {
+ return executionStack.get();
+ }
+
+ if (executionContextBeanName.get() != null
+ && name.equals(executionContextBeanName.get())) {
+ return executionContext.get();
+ }
+
+ // execution context must be defined first
+ if (executionContext.get() == null) {
+ Object obj = objectFactory.getObject();
+ if (obj instanceof ExecutionContext) {
+ return dealWithSpecialScopedObject(name, executionContext,
+ executionContextBeanName, (ExecutionContext) obj);
+ } else {
+ // TODO: use execution context wrapper
+ throw new SlcException("No execution context has been defined.");
+ }
+ }
+
+ // for other scoped objects, an executions stack must be available
+ if (executionStack.get() == null) {
+ Object obj = objectFactory.getObject();
+ if (obj instanceof ExecutionStack) {
+ return dealWithSpecialScopedObject(name, executionStack,
+ executionStackBeanName, (ExecutionStack) obj);
+ } else {
+ throw new SlcException("No execution stack has been defined.");
+ }
+ }
+
+ // see if the execution stack already knows the object
+ Object obj = executionStack.get().findScopedObject(name);
+ if (obj == null) {
+ obj = objectFactory.getObject();
+ if (obj instanceof ExecutionContext)
+ throw new SlcException(
+ "Only one execution context can be defined per thread");
+ if (obj instanceof ExecutionStack)
+ throw new SlcException(
+ "Only one execution stack can be defined per thread");
+
+ checkForbiddenClasses(obj);
+
+ executionStack.get().addScopedObject(name, obj);
+ }
+ return obj;
+
+ }
+
+ protected <T> T dealWithSpecialScopedObject(String name,
+ ThreadLocal<T> threadLocal,
+ ThreadLocal<String> threadLocalBeanName, T newObj) {
+
+ T obj = threadLocal.get();
+ if (obj == null) {
+ obj = newObj;
+ threadLocal.set(obj);
+ threadLocalBeanName.set(name);
+ if (log.isTraceEnabled()) {
+ log.debug(obj.getClass() + " instantiated. (beanName=" + name
+ + ")");
+ }
+ return obj;
+ } else {
+ throw new SlcException("Only one scoped " + obj.getClass()
+ + " can be defined per thread");
+ }
+
+ }
+
+ protected void checkForbiddenClasses(Object obj) {
+ Class<?> clss = obj.getClass();
+ if (ExecutionFlow.class.isAssignableFrom(clss)
+ || ExecutionSpec.class.isAssignableFrom(clss)) {
+ throw new UnsupportedException("Execution scoped object", clss);
+ }
+ }
+
+ public String getConversationId() {
+ // TODO: is it the most relevant?
+ return executionContext.get().getUuid();
+ }
+
+ public void registerDestructionCallback(String name, Runnable callback) {
+ if (Thread.currentThread() instanceof ExecutionThread) {
+ ExecutionThread executionThread = (ExecutionThread) Thread
+ .currentThread();
+ executionThread.registerDestructionCallback(name, callback);
+ }
+ }
+
+ public Object remove(String name) {
+ if (log.isDebugEnabled())
+ log.debug("Remove object " + name);
+ throw new UnsupportedOperationException();
+ }
+
+ public Object resolveContextualObject(String key) {
+ return executionContext.get().getVariable(key);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionStep;
+import org.argeo.slc.execution.RealizedFlow;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+/** Thread of a single execution */
+public class ExecutionThread extends Thread {
+ public final static String SYSPROP_EXECUTION_AUTO_UPGRADE = "slc.execution.autoupgrade";
+ private final static Log log = LogFactory.getLog(ExecutionThread.class);
+
+ private ExecutionModulesManager executionModulesManager;
+ private final RealizedFlow realizedFlow;
+
+ private List<Runnable> destructionCallbacks = new ArrayList<Runnable>();
+
+ public ExecutionThread(ProcessThreadGroup processThreadGroup,
+ ExecutionModulesManager executionModulesManager,
+ RealizedFlow realizedFlow) {
+ super(processThreadGroup, "Flow "
+ + realizedFlow.getFlowDescriptor().getName());
+ this.realizedFlow = realizedFlow;
+ this.executionModulesManager = executionModulesManager;
+ }
+
+ public void run() {
+ // authenticate thread
+ Authentication authentication = getProcessThreadGroup()
+ .getAuthentication();
+ if (authentication == null)
+ throw new SlcException("Can only execute authenticated threads");
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+
+ // Retrieve execution flow descriptor
+ ExecutionFlowDescriptor executionFlowDescriptor = realizedFlow
+ .getFlowDescriptor();
+ String flowName = executionFlowDescriptor.getName();
+
+ getProcessThreadGroup().dispatchAddStep(
+ new ExecutionStep(realizedFlow.getModuleName(),
+ ExecutionStep.PHASE_START, "Flow " + flowName));
+
+ try {
+ String autoUpgrade = System
+ .getProperty(SYSPROP_EXECUTION_AUTO_UPGRADE);
+ if (autoUpgrade != null && autoUpgrade.equals("true"))
+ executionModulesManager.upgrade(realizedFlow
+ .getModuleNameVersion());
+ executionModulesManager.start(realizedFlow.getModuleNameVersion());
+ //
+ // START FLOW
+ //
+ executionModulesManager.execute(realizedFlow);
+ // END FLOW
+ } catch (FlowConfigurationException e) {
+ String msg = "Configuration problem with flow " + flowName + ":\n"
+ + e.getMessage();
+ log.error(msg);
+ getProcessThreadGroup().dispatchAddStep(
+ new ExecutionStep(realizedFlow.getModuleName(),
+ ExecutionStep.ERROR, msg + " " + e.getMessage()));
+ } catch (Exception e) {
+ // TODO: re-throw exception ?
+ String msg = "Execution of flow " + flowName + " failed.";
+ log.error(msg, e);
+ getProcessThreadGroup().dispatchAddStep(
+ new ExecutionStep(realizedFlow.getModuleName(),
+ ExecutionStep.ERROR, msg + " " + e.getMessage()));
+ } finally {
+ getProcessThreadGroup().dispatchAddStep(
+ new ExecutionStep(realizedFlow.getModuleName(),
+ ExecutionStep.PHASE_END, "Flow " + flowName));
+ processDestructionCallbacks();
+ }
+ }
+
+ private synchronized void processDestructionCallbacks() {
+ for (int i = destructionCallbacks.size() - 1; i >= 0; i--) {
+ try {
+ destructionCallbacks.get(i).run();
+ } catch (Exception e) {
+ log.warn("Could not process destruction callback " + i
+ + " in thread " + getName(), e);
+ }
+ }
+ }
+
+ /**
+ * Gather object destruction callback to be called in reverse order at the
+ * end of the thread
+ */
+ synchronized void registerDestructionCallback(String name, Runnable callback) {
+ destructionCallbacks.add(callback);
+ }
+
+ protected ProcessThreadGroup getProcessThreadGroup() {
+ return (ProcessThreadGroup) getThreadGroup();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionContext;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.Resource;
+import org.springframework.util.Assert;
+
+/** Implements write access to resources based on standard Java {@link File} */
+public class FileExecutionResources implements ExecutionResources {
+ private final static Log log = LogFactory
+ .getLog(FileExecutionResources.class);
+ protected final static String DEFAULT_EXECUTION_RESOURCES_DIRNAME = "executionResources";
+ public final static String DEFAULT_EXECUTION_RESOURCES_TMP_PATH = System
+ .getProperty("java.io.tmpdir")
+ + File.separator
+ + System.getProperty("user.name")
+ + File.separator
+ + "slc"
+ + File.separator + DEFAULT_EXECUTION_RESOURCES_DIRNAME;
+
+ private File baseDir;
+ private ExecutionContext executionContext;
+ private String prefixDatePattern = "yyMMdd_HHmmss_SSS";
+ private SimpleDateFormat sdf = null;
+
+ private Boolean withExecutionSubdirectory = true;
+
+ public FileExecutionResources() {
+ // Default base directory
+ String osgiInstanceArea = System.getProperty("osgi.instance.area");
+ String osgiInstanceAreaDefault = System
+ .getProperty("osgi.instance.area.default");
+
+ if (osgiInstanceArea != null) {
+ // within OSGi with -data specified
+ osgiInstanceArea = removeFilePrefix(osgiInstanceArea);
+ baseDir = new File(osgiInstanceArea + File.separator
+ + DEFAULT_EXECUTION_RESOURCES_DIRNAME);
+ } else if (osgiInstanceAreaDefault != null) {
+ // within OSGi without -data specified
+ osgiInstanceAreaDefault = removeFilePrefix(osgiInstanceAreaDefault);
+ baseDir = new File(osgiInstanceAreaDefault + File.separator
+ + DEFAULT_EXECUTION_RESOURCES_DIRNAME);
+ } else {// outside OSGi
+ baseDir = new File(DEFAULT_EXECUTION_RESOURCES_TMP_PATH);
+ }
+ }
+
+ protected SimpleDateFormat sdf() {
+ // Lazy init in case prefix has been externally set
+ if (sdf == null)
+ sdf = new SimpleDateFormat(prefixDatePattern);
+ return sdf;
+ }
+
+ public Resource getWritableResource(String relativePath) {
+ File file = getFile(relativePath);
+ File parentDir = file.getParentFile();
+
+ if (!parentDir.exists()) {
+ // Creates if necessary
+ if (log.isTraceEnabled())
+ log.trace("Creating parent directory " + parentDir);
+ parentDir.mkdirs();
+ }
+ Resource resource = new FileSystemResource(file);
+
+ if (log.isTraceEnabled())
+ log.trace("Returns writable resource " + resource);
+ return resource;
+ }
+
+ public String getWritableOsPath(String relativePath) {
+ try {
+ return getFile(relativePath).getCanonicalPath();
+ } catch (IOException e) {
+ throw new SlcException("Cannot find canonical path", e);
+ }
+ }
+
+ public File getWritableOsFile(String relativePath) {
+ return getFile(relativePath);
+ }
+
+ public String getAsOsPath(Resource resource, Boolean overwrite) {
+ File file = fileFromResource(resource);
+ if (file != null)
+ try {
+ if (log.isTraceEnabled())
+ log.debug("Directly interpret " + resource + " as OS file "
+ + file);
+ return file.getCanonicalPath();
+ } catch (IOException e1) {
+ // silent
+ }
+
+ if (log.isTraceEnabled())
+ log.trace("Resource " + resource
+ + " is not available on the file system. Retrieving it...");
+
+ InputStream in = null;
+ OutputStream out = null;
+ try {
+ String path = resource.getURL().getPath();
+ file = getFile(path);
+ if (file.exists() && !overwrite)
+ return file.getCanonicalPath();
+
+ file.getParentFile().mkdirs();
+ in = resource.getInputStream();
+ out = new FileOutputStream(file);
+ IOUtils.copy(in, out);
+ if (log.isDebugEnabled())
+ log.debug("Retrieved " + resource + " to OS file " + file);
+ return file.getCanonicalPath();
+ } catch (IOException e) {
+ throw new SlcException("Could not make resource " + resource
+ + " an OS file.", e);
+ } finally {
+ IOUtils.closeQuietly(in);
+ IOUtils.closeQuietly(out);
+ }
+ }
+
+ /**
+ * Extract the underlying file from the resource.
+ *
+ * @return the file or null if no files support this resource.
+ */
+ protected File fileFromResource(Resource resource) {
+ try {
+ return resource.getFile();
+ } catch (IOException e) {
+ return null;
+ }
+
+ }
+
+ protected File getFile(String relativePath) {
+ File writableBaseDir = getWritableBaseDir();
+ return new File(writableBaseDir.getPath() + File.separator
+ + relativePath.replace('/', File.separatorChar));
+ }
+
+ public File getWritableBaseDir() {
+ if (withExecutionSubdirectory) {
+ Date executionContextCreationDate = (Date) executionContext
+ .getVariable(ExecutionContext.VAR_EXECUTION_CONTEXT_CREATION_DATE);
+ Assert.notNull(executionContext, "execution context is null");
+ String path = baseDir.getPath() + File.separator
+ + sdf().format(executionContextCreationDate);
+ // TODO write execution id somewhere? like in a txt file
+ return new File(path);
+ } else {
+ return baseDir;
+ }
+ }
+
+ protected String removeFilePrefix(String url) {
+ if (url.startsWith("file:"))
+ return url.substring("file:".length());
+ else if (url.startsWith("reference:file:"))
+ return url.substring("reference:file:".length());
+ else
+ return url;
+ }
+
+ public void setBaseDir(File baseDir) {
+ this.baseDir = baseDir;
+ }
+
+ public void setExecutionContext(ExecutionContext executionContext) {
+ this.executionContext = executionContext;
+ }
+
+ public void setPrefixDatePattern(String prefixDatePattern) {
+ this.prefixDatePattern = prefixDatePattern;
+ }
+
+ public File getBaseDir() {
+ return baseDir;
+ }
+
+ public ExecutionContext getExecutionContext() {
+ return executionContext;
+ }
+
+ public String getPrefixDatePattern() {
+ return prefixDatePattern;
+ }
+
+ /** Default is true. */
+ public void setWithExecutionSubdirectory(Boolean withExecutionSubdirectory) {
+ this.withExecutionSubdirectory = withExecutionSubdirectory;
+ }
+
+}
--- /dev/null
+package org.argeo.slc.core.execution;
+
+import org.argeo.slc.SlcException;
+
+/** The stack trace of such exceptions does not need to be displayed */
+public class FlowConfigurationException extends SlcException {
+ private static final long serialVersionUID = 8456260596346797321L;
+
+ public FlowConfigurationException(String message) {
+ super(message);
+ }
+}
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution;\r
+\r
+import java.util.Stack;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.execution.ExecutionFlow;\r
+import org.argeo.slc.execution.ExecutionSpecAttribute;\r
+\r
+/** Manage parameters that need to be set during the instantiation of a flow */\r
+public class InstantiationManager {\r
+\r
+ private final static Log log = LogFactory\r
+ .getLog(InstantiationManager.class);\r
+\r
+ private ThreadLocal<Stack<ExecutionFlow>> flowStack = new ThreadLocal<Stack<ExecutionFlow>>();\r
+\r
+ public Object createRef(String name) {\r
+\r
+ if ((flowStack.get() == null) || flowStack.get().empty()) {\r
+ throw new SlcException("No flow is currently initializing."\r
+ + " Declare ParameterRef as inner beans or prototypes.");\r
+ }\r
+\r
+ return getInitializingFlowParameter(name);\r
+ }\r
+\r
+ public void flowInitializationStarted(ExecutionFlow flow, String flowName) {\r
+ // set the flow name if it is DefaultExecutionFlow\r
+ if (flow instanceof DefaultExecutionFlow) {\r
+ ((DefaultExecutionFlow) flow).setBeanName(flowName);\r
+ }\r
+\r
+ if (log.isTraceEnabled())\r
+ log.trace("Start initialization of " + flow.hashCode() + " ("\r
+ + flow + " - " + flow.getClass() + ")");\r
+\r
+ // log.info("# flowInitializationStarted " + flowName);\r
+ // create a stack for this thread if there is none\r
+ if (flowStack.get() == null) {\r
+ flowStack.set(new Stack<ExecutionFlow>());\r
+ }\r
+ flowStack.get().push(flow);\r
+ }\r
+\r
+ public void flowInitializationFinished(ExecutionFlow flow, String flowName) {\r
+ if (log.isTraceEnabled())\r
+ log.trace("Finish initialization of " + flow.hashCode() + " ("\r
+ + flow + " - " + flow.getClass() + ")");\r
+\r
+ if (flowStack.get() != null) {\r
+ ExecutionFlow registeredFlow = flowStack.get().pop();\r
+ if (registeredFlow != null) {\r
+ if (!flow.getName().equals(registeredFlow.getName()))\r
+ throw new SlcException("Current flow is " + flow);\r
+ // log.info("# flowInitializationFinished " + flowName);\r
+ // initializingFlow.set(null);\r
+ }\r
+ } else {\r
+ // happens for flows imported as services\r
+ log.warn("flowInitializationFinished - Flow Stack is null");\r
+ }\r
+ }\r
+\r
+ protected ExecutionFlow findInitializingFlowWithParameter(String key) {\r
+ if ((flowStack.get() == null) || flowStack.get().empty())\r
+ throw new SlcException("No initializing flow available.");\r
+\r
+ // first look in the outer flow (that may override parameters)\r
+ for (int i = 0; i < flowStack.get().size(); i++) {\r
+ if (flowStack.get().elementAt(i).isSetAsParameter(key)) {\r
+ return flowStack.get().elementAt(i);\r
+ }\r
+ }\r
+ throw new SlcException("Key " + key + " is not set as parameter in "\r
+ + flowStack.get().firstElement().toString() + " (stack size="\r
+ + flowStack.get().size() + ")");\r
+\r
+ }\r
+\r
+ public Object getInitializingFlowParameter(String key) {\r
+ return findInitializingFlowWithParameter(key).getParameter(key);\r
+ }\r
+\r
+ public Class<?> getInitializingFlowParameterClass(String key) {\r
+ ExecutionSpecAttribute attr = findInitializingFlowWithParameter(key)\r
+ .getExecutionSpec().getAttributes().get(key);\r
+ if (attr instanceof RefSpecAttribute)\r
+ return ((RefSpecAttribute) attr).getTargetClass();\r
+ else if (attr instanceof PrimitiveSpecAttribute) {\r
+ String type = ((PrimitiveSpecAttribute) attr).getType();\r
+ Class<?> clss = PrimitiveUtils.typeAsClass(type);\r
+ if (clss == null)\r
+ throw new SlcException("Cannot convert type " + type\r
+ + " to class.");\r
+ return clss;\r
+ } else\r
+ return null;\r
+ }\r
+\r
+ public Boolean isInFlowInitialization() {\r
+ return (flowStack.get() != null) && !flowStack.get().empty();\r
+ }\r
+}\r
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionContext;
+import org.springframework.beans.BeanWrapper;
+import org.springframework.beans.BeanWrapperImpl;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+public class MapExecutionContext implements ExecutionContext,
+ ApplicationContextAware {
+ private final Map<String, Object> variables = Collections
+ .synchronizedMap(new HashMap<String, Object>());
+
+ private final String uuid;
+
+ private ApplicationContext applicationContext;
+
+ public MapExecutionContext() {
+ uuid = UUID.randomUUID().toString();
+ variables.put(VAR_EXECUTION_CONTEXT_ID, uuid);
+ variables.put(VAR_EXECUTION_CONTEXT_CREATION_DATE, new Date());
+ }
+
+ public void setVariable(String key, Object value) {
+ // check if we do not refer to a bean
+ int lastInd = key.lastIndexOf('.');
+ if (applicationContext != null && lastInd > 0) {
+ String beanName = key.substring(0, lastInd);
+ String propertyName = key.substring(lastInd + 1);
+ if (applicationContext.containsBean(beanName)) {
+ BeanWrapper beanWrapper = new BeanWrapperImpl(
+ applicationContext.getBean(beanName));
+ if (!beanWrapper.isWritableProperty(propertyName))
+ throw new SlcException("No writable property "
+ + propertyName + " in bean " + beanName);
+ beanWrapper.setPropertyValue(propertyName, value);
+ }
+ }
+
+ variables.put(key, value);
+ }
+
+ public Object getVariable(String key) {
+ // check if we do not refer to a bean
+ int lastInd = key.lastIndexOf('.');
+ if (applicationContext != null && lastInd > 0) {
+ String beanName = key.substring(0, lastInd);
+ String propertyName = key.substring(lastInd + 1);
+ if (applicationContext.containsBean(beanName)) {
+ BeanWrapper beanWrapper = new BeanWrapperImpl(
+ applicationContext.getBean(beanName));
+ if (!beanWrapper.isReadableProperty(propertyName))
+ throw new SlcException("No readable property "
+ + propertyName + " in bean " + beanName);
+ Object obj = beanWrapper.getPropertyValue(propertyName);
+ return obj;
+ }
+ }
+
+ Object value = variables.get(key);
+ // try system property in last resort
+ if (value == null)
+ value = System.getProperty(key);
+ return value;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ExecutionContext)
+ return uuid.equals(((ExecutionContext) obj).getUuid());
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "#" + uuid;
+ }
+
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.core.io.Resource;
+import org.springframework.util.Assert;
+
+/** Retrieve an OS File from the given resource. */
+public class OsFileFactoryBean implements FactoryBean {
+ private ExecutionResources executionResources;
+ private Resource resource;
+ private Boolean overwrite = false;
+
+ /** Return an existing file on the file system. */
+ public Object getObject() throws Exception {
+ Assert.notNull(executionResources, "executionResources is null");
+ Assert.notNull(resource, "resource is null");
+ return executionResources.getAsOsPath(resource, overwrite);
+ }
+
+ /** Return {@link Object} because CGLIB is unable to proxy {@link File}.*/
+ public Class<? extends Object> getObjectType() {
+ return CharSequence.class;
+ }
+
+ public boolean isSingleton() {
+ return false;
+ }
+
+ /** The execution resources object. */
+ public void setExecutionResources(ExecutionResources executionResources) {
+ this.executionResources = executionResources;
+ }
+
+ /** The resource to access. */
+ public void setResource(Resource resource) {
+ this.resource = resource;
+ }
+
+ /**
+ * Whether to overwrite the resource if it already exists. Default is
+ * <code>false</code>.
+ */
+ public void setOverwrite(Boolean overwrite) {
+ this.overwrite = overwrite;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.FactoryBean;
+
+public class ParameterRef implements FactoryBean {
+ private final static Log log = LogFactory.getLog(ParameterRef.class);
+
+ private InstantiationManager instantiationManager;
+ private String name;
+
+ /** Cached object. */
+ private Object object;
+
+ public ParameterRef() {
+ }
+
+ public ParameterRef(String name) {
+ this.name = name;
+ }
+
+ public Object getObject() throws Exception {
+ if (log.isTraceEnabled())
+ log.debug("Parameter ref called for " + name);
+
+ if (object == null)
+ object = instantiationManager.getInitializingFlowParameter(name);
+ return object;
+ }
+
+ public Class<?> getObjectType() {
+ if (object == null)
+ return instantiationManager.getInitializingFlowParameterClass(name);
+ else
+ return object.getClass();
+ }
+
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public void setInstantiationManager(
+ InstantiationManager instantiationManager) {
+ this.instantiationManager = instantiationManager;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+/** Abstraction of access to primitive values */
+public interface PrimitiveAccessor {
+ public final static String TYPE_STRING = "string";
+ /**
+ * As of Argeo 1, passwords are NOT stored encrypted, just hidden in the UI,
+ * but stored in plain text in JCR. Use keyring instead.
+ */
+ public final static String TYPE_PASSWORD = "password";
+ public final static String TYPE_INTEGER = "integer";
+ public final static String TYPE_LONG = "long";
+ public final static String TYPE_FLOAT = "float";
+ public final static String TYPE_DOUBLE = "double";
+ public final static String TYPE_BOOLEAN = "boolean";
+
+ public String getType();
+
+ public Object getValue();
+
+ public void setValue(Object value);
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import org.argeo.slc.SlcException;
+
+/**
+ * A spec attribute wrapping a primitive value.
+ *
+ * @see PrimitiveAccessor
+ */
+public class PrimitiveSpecAttribute extends AbstractSpecAttribute implements
+ PrimitiveAccessor {
+ private static final long serialVersionUID = -566676381839825483L;
+ private String type = "string";
+ private Object value = null;
+
+ public PrimitiveSpecAttribute() {
+ }
+
+ public PrimitiveSpecAttribute(String type, Object value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ // check whether type is recognized.
+ if (PrimitiveUtils.typeAsClass(type) == null)
+ throw new SlcException("Unrecognized type " + type);
+ this.type = type;
+
+ }
+
+ @Override
+ public String toString() {
+ return "Primitive spec attribute [" + type + "]"
+ + (value != null ? "=" + value : "");
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+/** Converts to and from primitive types. */
+public class PrimitiveUtils {
+ /**
+ * @deprecated Use {@link PrimitiveAccessor#TYPE_STRING} instead
+ */
+ public final static String TYPE_STRING = PrimitiveAccessor.TYPE_STRING;
+ /**
+ * @deprecated Use {@link PrimitiveAccessor#TYPE_INTEGER} instead
+ */
+ public final static String TYPE_INTEGER = PrimitiveAccessor.TYPE_INTEGER;
+ /**
+ * @deprecated Use {@link PrimitiveAccessor#TYPE_LONG} instead
+ */
+ public final static String TYPE_LONG = PrimitiveAccessor.TYPE_LONG;
+ /**
+ * @deprecated Use {@link PrimitiveAccessor#TYPE_FLOAT} instead
+ */
+ public final static String TYPE_FLOAT = PrimitiveAccessor.TYPE_FLOAT;
+ /**
+ * @deprecated Use {@link PrimitiveAccessor#TYPE_DOUBLE} instead
+ */
+ public final static String TYPE_DOUBLE = PrimitiveAccessor.TYPE_DOUBLE;
+ /**
+ * @deprecated Use {@link PrimitiveAccessor#TYPE_BOOLEAN} instead
+ */
+ public final static String TYPE_BOOLEAN = PrimitiveAccessor.TYPE_BOOLEAN;
+
+ private PrimitiveUtils() {
+
+ }
+
+ /** @return the class or null if the provided type is not a primitive */
+ public static Class<?> typeAsClass(String type) {
+ if (PrimitiveAccessor.TYPE_STRING.equals(type))
+ return String.class;
+ else if (PrimitiveAccessor.TYPE_PASSWORD.equals(type))
+ return char[].class;
+ else if (PrimitiveAccessor.TYPE_INTEGER.equals(type))
+ return Integer.class;
+ else if (PrimitiveAccessor.TYPE_LONG.equals(type))
+ return Long.class;
+ else if (PrimitiveAccessor.TYPE_FLOAT.equals(type))
+ return Float.class;
+ else if (PrimitiveAccessor.TYPE_DOUBLE.equals(type))
+ return Double.class;
+ else if (PrimitiveAccessor.TYPE_BOOLEAN.equals(type))
+ return Boolean.class;
+ else
+ return null;
+ }
+
+ /** @return the type or null if the provided class is not a primitive */
+ public static String classAsType(Class<?> clss) {
+ if (String.class.isAssignableFrom(clss))
+ return PrimitiveAccessor.TYPE_STRING;
+ else if (char[].class.isAssignableFrom(clss))
+ return PrimitiveAccessor.TYPE_PASSWORD;
+ else if (Integer.class.isAssignableFrom(clss))
+ return PrimitiveAccessor.TYPE_INTEGER;
+ else if (Long.class.isAssignableFrom(clss))
+ return PrimitiveAccessor.TYPE_LONG;
+ else if (Float.class.isAssignableFrom(clss))
+ return PrimitiveAccessor.TYPE_FLOAT;
+ else if (Double.class.isAssignableFrom(clss))
+ return PrimitiveAccessor.TYPE_DOUBLE;
+ else if (Boolean.class.isAssignableFrom(clss))
+ return PrimitiveAccessor.TYPE_BOOLEAN;
+ else
+ return null;
+ }
+
+ /** Parse string as an object. Passwords are returned as String.*/
+ public static Object convert(String type, String str) {
+ if (PrimitiveAccessor.TYPE_STRING.equals(type)) {
+ return str;
+ } else if (PrimitiveAccessor.TYPE_PASSWORD.equals(type)) {
+ return str;
+ } else if (PrimitiveAccessor.TYPE_INTEGER.equals(type)) {
+ return (Integer.parseInt(str));
+ } else if (PrimitiveAccessor.TYPE_LONG.equals(type)) {
+ return (Long.parseLong(str));
+ } else if (PrimitiveAccessor.TYPE_FLOAT.equals(type)) {
+ return (Float.parseFloat(str));
+ } else if (PrimitiveAccessor.TYPE_DOUBLE.equals(type)) {
+ return (Double.parseDouble(str));
+ } else if (PrimitiveAccessor.TYPE_BOOLEAN.equals(type)) {
+ return (Boolean.parseBoolean(str));
+ } else {
+ return str;
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+/** Primitive value to be used by an execution. */
+public class PrimitiveValue extends AbstractExecutionValue implements
+ PrimitiveAccessor {
+ private static final long serialVersionUID = 533414290998374166L;
+
+ private String type;
+
+ private Object value;
+
+ public PrimitiveValue() {
+ }
+
+ public PrimitiveValue(String type, Object value) {
+ super();
+ this.type = type;
+ this.value = value;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.ExecutionStep;
+import org.argeo.slc.execution.RealizedFlow;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+/**
+ * Main thread coordinating an {@link ExecutionProcess}, launching parallel or
+ * sequential {@link ExecutionThread}s.
+ */
+public class ProcessThread extends Thread {
+ private final static Log log = LogFactory.getLog(ProcessThread.class);
+
+ private final ExecutionModulesManager executionModulesManager;
+ private final ExecutionProcess process;
+ private final ProcessThreadGroup processThreadGroup;
+
+ private Set<ExecutionThread> executionThreads = Collections
+ .synchronizedSet(new HashSet<ExecutionThread>());
+
+ // private Boolean hadAnError = false;
+ private Boolean killed = false;
+
+ public ProcessThread(ThreadGroup processesThreadGroup,
+ ExecutionModulesManager executionModulesManager,
+ ExecutionProcess process) {
+ super(processesThreadGroup, "SLC Process #" + process.getUuid());
+ this.executionModulesManager = executionModulesManager;
+ this.process = process;
+ processThreadGroup = new ProcessThreadGroup(process);
+ }
+
+ public final void run() {
+ // authenticate thread
+ Authentication authentication = getProcessThreadGroup()
+ .getAuthentication();
+ if (authentication == null)
+ throw new SlcException("Can only execute authenticated threads");
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+
+ log.info("\n##\n## SLC Process #" + process.getUuid()
+ + " STARTED\n##\n");
+
+ // Start logging
+ new LoggingThread().start();
+
+ process.setStatus(ExecutionProcess.RUNNING);
+ try {
+ process();
+ } catch (InterruptedException e) {
+ die();
+ return;
+ } catch (Exception e) {
+ String msg = "Process " + getProcess().getUuid()
+ + " failed unexpectedly.";
+ log.error(msg, e);
+ getProcessThreadGroup().dispatchAddStep(
+ new ExecutionStep("Process", ExecutionStep.ERROR, msg + " "
+ + e.getMessage()));
+ }
+
+ // waits for all execution threads to complete (in case they were
+ // started asynchronously)
+ for (ExecutionThread executionThread : executionThreads) {
+ if (executionThread.isAlive()) {
+ try {
+ executionThread.join();
+ } catch (InterruptedException e) {
+ die();
+ return;
+ }
+ }
+ }
+
+ computeFinalStatus();
+ }
+
+ /** Make sure this is called BEFORE all the threads are interrupted. */
+ private void computeFinalStatus() {
+ // String oldStatus = process.getStatus();
+ // TODO: error management at flow level?
+ if (killed)
+ process.setStatus(ExecutionProcess.KILLED);
+ else if (processThreadGroup.hadAnError())
+ process.setStatus(ExecutionProcess.ERROR);
+ else
+ process.setStatus(ExecutionProcess.COMPLETED);
+ // executionModulesManager.dispatchUpdateStatus(process, oldStatus,
+ // process.getStatus());
+ log.info("\n## SLC Process #" + process.getUuid() + " "
+ + process.getStatus() + "\n");
+ }
+
+ /** Called when being killed */
+ private synchronized void die() {
+ killed = true;
+ computeFinalStatus();
+ for (ExecutionThread executionThread : executionThreads) {
+ try {
+ executionThread.interrupt();
+ } catch (Exception e) {
+ log.error("Cannot interrupt " + executionThread);
+ }
+ }
+ processThreadGroup.interrupt();
+ }
+
+ /**
+ * Implementation specific execution. To be overridden in order to deal with
+ * custom process types. Default expects an {@link SlcExecution}.
+ */
+ protected void process() throws InterruptedException {
+ List<RealizedFlow> flowsToProcess = new ArrayList<RealizedFlow>();
+ flowsToProcess.addAll(process.getRealizedFlows());
+ while (flowsToProcess.size() > 0) {
+ RealizedFlow realizedFlow = flowsToProcess.remove(0);
+ execute(realizedFlow, true);
+ }
+ }
+
+ /** @return the (distinct) thread used for this execution */
+ protected final void execute(RealizedFlow realizedFlow, Boolean synchronous)
+ throws InterruptedException {
+ if (killed)
+ return;
+
+ ExecutionThread thread = new ExecutionThread(processThreadGroup,
+ executionModulesManager, realizedFlow);
+ executionThreads.add(thread);
+ thread.start();
+
+ if (synchronous)
+ thread.join();
+
+ return;
+ }
+
+ // public void notifyError() {
+ // hadAnError = true;
+ // }
+ //
+ // public synchronized void flowCompleted() {
+ // // notifyAll();
+ // }
+
+ public ExecutionProcess getProcess() {
+ return process;
+ }
+
+ public ProcessThreadGroup getProcessThreadGroup() {
+ return processThreadGroup;
+ }
+
+ public ExecutionModulesManager getExecutionModulesManager() {
+ return executionModulesManager;
+ }
+
+ private class LoggingThread extends Thread {
+
+ public LoggingThread() {
+ super("SLC Process Logger #" + process.getUuid());
+ }
+
+ public void run() {
+ boolean run = true;
+ while (run) {
+ List<ExecutionStep> newSteps = new ArrayList<ExecutionStep>();
+ processThreadGroup.getSteps().drainTo(newSteps);
+ if (newSteps.size() > 0) {
+ // System.out.println(steps.size() + " steps");
+ process.addSteps(newSteps);
+ }
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ break;
+ }
+
+ if (!ProcessThread.this.isAlive()
+ && processThreadGroup.getSteps().size() == 0)
+ run = false;
+ }
+ }
+
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.ExecutionStep;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+/** The thread group attached to a given {@link SlcExecution}. */
+public class ProcessThreadGroup extends ThreadGroup {
+ // private final ExecutionModulesManager executionModulesManager;
+ // private final ProcessThread processThread;
+ private final Authentication authentication;
+ private final static Integer STEPS_BUFFER_CAPACITY = 5000;
+
+ private BlockingQueue<ExecutionStep> steps = new ArrayBlockingQueue<ExecutionStep>(
+ STEPS_BUFFER_CAPACITY);
+
+ private Boolean hadAnError = false;
+
+ public ProcessThreadGroup(ExecutionProcess executionProcess) {
+ super("SLC Process #" + executionProcess.getUuid() + " thread group");
+ // this.executionModulesManager = executionModulesManager;
+ // this.processThread = processThread;
+ this.authentication = SecurityContextHolder.getContext()
+ .getAuthentication();
+ }
+
+ public Authentication getAuthentication() {
+ return authentication;
+ }
+
+ public void dispatchAddStep(ExecutionStep step) {
+ // ExecutionProcess slcProcess = processThread.getProcess();
+ // List<ExecutionStep> steps = new ArrayList<ExecutionStep>();
+ // steps.add(step);
+ // TODO clarify why we don't dispatch steps, must be a reason
+ // dispatchAddSteps(steps);
+ // slcProcess.addSteps(steps);
+ if (step.getType().equals(ExecutionStep.ERROR))
+ hadAnError = true;
+ this.steps.add(step);
+ }
+
+ // public void dispatchAddSteps(List<ExecutionStep> steps) {
+ // ExecutionProcess slcProcess = processThread.getProcess();
+ // executionModulesManager.dispatchAddSteps(slcProcess, steps);
+ // }
+
+ public BlockingQueue<ExecutionStep> getSteps() {
+ return steps;
+ }
+
+ public Boolean hadAnError() {
+ return hadAnError;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.util.List;
+
+/** A spec attribute whose value is a reference to a full fledged object. */
+public class RefSpecAttribute extends AbstractSpecAttribute implements
+ Cloneable {
+ private static final long serialVersionUID = -3427797452955753574L;
+ private transient Class<?> targetClass = String.class;
+ /** Read only. */
+ private String targetClassName;
+ private transient Object value = null;
+
+ /** List to be chosen from */
+ private List<RefValueChoice> choices = null;
+
+ public Object getValue() {
+ return value;
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
+ /** Default is {@link String} */
+ public Class<?> getTargetClass() {
+ return targetClass;
+ }
+
+ public void setTargetClass(Class<?> targetClass) {
+ this.targetClass = targetClass;
+ this.targetClassName = targetClass.getName();
+ }
+
+ public String getTargetClassName() {
+ return targetClassName;
+ }
+
+ /** @return can be null */
+ public List<RefValueChoice> getChoices() {
+ return choices;
+ }
+
+ public void setChoices(List<RefValueChoice> choices) {
+ this.choices = choices;
+ }
+
+ @Override
+ protected Object clone() throws CloneNotSupportedException {
+ RefSpecAttribute rsa = new RefSpecAttribute();
+ rsa.setTargetClass(targetClass);
+ rsa.setChoices(choices);
+ return rsa;
+ }
+
+ @Override
+ public String toString() {
+ return "Ref spec attribute [" + targetClass + "]"
+ + (value != null ? "=" + value : "");
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+/** Reference value to be used by an execution */
+public class RefValue extends AbstractExecutionValue {
+ private static final long serialVersionUID = -8951231456757181687L;
+ private String ref;
+ private String type;
+
+ public RefValue() {
+ }
+
+ public RefValue(String ref) {
+ super();
+ this.ref = ref;
+ }
+
+ public String getRef() {
+ return ref;
+ }
+
+ public void setRef(String ref) {
+ this.ref = ref;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ @Override
+ public String toString() {
+ return "Ref Value [" + type + "=" + ref + "]";
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.Serializable;
+
+/** A choice of ref value to be shown to the end user. */
+public class RefValueChoice implements Serializable {
+ private static final long serialVersionUID = -1133645722307507774L;
+ private String name;
+ private String description;
+
+ public RefValueChoice() {
+ }
+
+ public RefValueChoice(String name, String description) {
+ this.name = name;
+ this.description = description;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.core.io.Resource;
+
+/** Experimental and suboptimal */
+public class SedFilteredResource implements FactoryBean, InitializingBean {
+ private Resource source;
+
+ private List<String> filters = new ArrayList<String>();
+ private Map<Pattern, String> patterns = new HashMap<Pattern, String>();
+
+ private String charset = "UTF-8";
+ private Charset cs;
+ private CharsetDecoder decoder;
+
+ // private CharsetEncoder encoder;
+
+ public Object getObject() throws Exception {
+ if (filters.size() == 0)
+ return source;
+
+ // int capacity = 100 * 1024;// 100 KB
+ ByteBuffer bb;
+ if (source instanceof ByteArrayResource) {
+ bb = ByteBuffer.wrap(((ByteArrayResource) source).getByteArray());
+ } else {
+ FileInputStream fis = null;
+ try {
+ File file = source.getFile();
+ fis = new FileInputStream(file);
+ FileChannel fc = fis.getChannel();
+
+ // Get the file's size and then map it into memory
+ int sz = (int) fc.size();
+ bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
+ } catch (IOException e) {
+ // ReadableByteChannel channel = Channels.newChannel(source
+ // .getInputStream());
+ // bb = ByteBuffer.allocateDirect(capacity);
+ // int read = 0;
+ // do {
+ // read = channel.read(bb);
+ // } while (read > 0);
+ // FIXME : use nio to parse the stream as it goes
+ bb = ByteBuffer.wrap(IOUtils.toByteArray(source
+ .getInputStream()));
+ } finally {
+ IOUtils.closeQuietly(fis);
+ }
+ }
+ CharBuffer cb = decoder.decode(bb);
+ for (Pattern pattern : patterns.keySet()) {
+ Matcher matcher = pattern.matcher(cb);
+ String output = matcher.replaceAll(patterns.get(pattern));
+ cb = CharBuffer.wrap(output);
+ }
+ // ByteBuffer bbout = encoder.encode(cb);
+ // ByteArrayOutputStream out = new ByteArrayOutputStream(capacity);
+ // WritableByteChannel wchannel = Channels.newChannel(out);
+ // wchannel.write(bbout);
+ ByteArrayResource res = new ByteArrayResource(cb.toString().getBytes());
+ return res;
+ }
+
+ public Class<?> getObjectType() {
+ return Resource.class;
+ }
+
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ cs = Charset.forName(charset);
+ decoder = cs.newDecoder();
+ // encoder = cs.newEncoder();
+
+ for (String sedStr : filters) {
+ sedStr = sedStr.trim();
+ if (sedStr.length() < 4)
+ throw new SlcException(sedStr + " not properly formatted.");
+ if (sedStr.charAt(0) != 's')
+ throw new SlcException(sedStr + " not properly formatted.");
+ Character sep = sedStr.charAt(1);
+ List<String> tokens = new ArrayList<String>(4);
+ StringTokenizer st = new StringTokenizer(sedStr, sep.toString());
+ while (st.hasMoreTokens())
+ tokens.add(st.nextToken());
+ if (tokens.size() != 3 && tokens.size() != 4)
+ throw new SlcException(sedStr + " not properly formatted.");
+ patterns.put(Pattern.compile(tokens.get(1)), tokens.get(2));
+ }
+ }
+
+ public void setSource(Resource source) {
+ this.source = source;
+ }
+
+ public void setFilters(List<String> filters) {
+ this.filters = filters;
+ }
+
+ public void setCharset(String charset) {
+ this.charset = charset;
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2007-2012 Argeo GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+ <bean id="slcDefault.executionResources" parent="slcTemplate.fileResources"
+ scope="execution" lazy-init="true">
+ <aop:scoped-proxy proxy-target-class="false" />
+ <property name="executionContext" ref="executionContext" />
+ </bean>
+
+ <bean id="slcDefault.writableResource" parent="slcTemplate.writableResource"
+ abstract="true">
+ <property name="executionResources" ref="slcDefault.executionResources" />
+ </bean>
+
+ <bean id="slcDefault.osFile" parent="slcTemplate.osFile" abstract="true">
+ <property name="executionResources" ref="slcDefault.executionResources" />
+ </bean>
+</beans>
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.doc;
+
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+
+public class ConsoleContextDescriber implements ContextDescriber {
+ public void describeContext(BeanDefinitionRegistry registry) {
+ String[] beanNames = registry.getBeanDefinitionNames();
+ for (String beanName : beanNames) {
+ log("\n## BEAN: " + beanName);
+ describeBean(registry.getBeanDefinition(beanName));
+ }
+ }
+
+ public void describeBean(BeanDefinition beanDefinition) {
+ log("BeanDefinition class: "+beanDefinition.getClass());
+ log("# ATTRIBUTES");
+ for(String attr:beanDefinition.attributeNames()){
+ log(attr+"="+beanDefinition.getAttribute(attr));
+ }
+ log("# PROPERTIES");
+ MutablePropertyValues pValues = beanDefinition.getPropertyValues();
+ for (PropertyValue pv : pValues.getPropertyValues()) {
+ log(pv.getName() + "= (" + pv.getValue().getClass() + ") "
+ + pv.getValue());
+ }
+ }
+
+ protected void log(Object obj){
+ System.out.println(obj);
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.doc;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+
+public interface ContextDescriber {
+ public void describeContext(BeanDefinitionRegistry registry);
+ public void describeBean(BeanDefinition bd);
+}
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.Map;\r
+\r
+import org.argeo.slc.SlcException;\r
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
+\r
+/**\r
+ * Composite <code>RunnableFactory</code>, redirecting the Runnable \r
+ * creation to on of the configured <code>RunnableFactory</code> depending\r
+ * on an entry of the data of the <code>RunnableDataNode</code>.\r
+ */\r
+public class CompositeRunnableFactory implements RunnableFactory {\r
+\r
+ /**\r
+ * Key used to access factory ID in the data of the <code>RunnableDataNode</code>\r
+ */\r
+ private String factoryKey;\r
+\r
+ /**\r
+ * Maps a factory ID to an ExecutionFlowFactory\r
+ */\r
+ private Map<String, RunnableFactory> factories;\r
+\r
+ public void createAndRegisterRunnable(RunnableDataNode node,\r
+ BeanDefinitionRegistry beanDefinitionRegistry) {\r
+ findFactory(node).createAndRegisterRunnable(node, beanDefinitionRegistry);\r
+ } \r
+ \r
+ /**\r
+ * Finds the <code>RunnableFactory</code> to use for a <code>RunnableDataNode</code>\r
+ * @param node\r
+ * @return the <code>RunnableFactory</code> to use for the <code>RunnableDataNode</code>\r
+ */\r
+ private RunnableFactory findFactory(RunnableDataNode node) {\r
+ // get the factory ID from the data of the RunnableDescriptor\r
+ Map<String, Object> data = node.getData();\r
+ if (!data.containsKey(factoryKey)) {\r
+ throw new SlcException("No data value for key '" + factoryKey + "'");\r
+ }\r
+ String factoryId = data.get(factoryKey).toString();\r
+ \r
+ // see if we have a factory for the factory ID\r
+ if ((factories != null) && factories.containsKey(factoryId)) {\r
+ return factories.get(factoryId);\r
+ }\r
+ // if not, look for a bean of name equals to the factory ID\r
+ else {\r
+ throw new SlcException("Not implemented");\r
+ } \r
+ }\r
+ \r
+ public void setFactoryKey(String factoryKey) {\r
+ this.factoryKey = factoryKey;\r
+ }\r
+\r
+ public void setFactories(Map<String, RunnableFactory> factories) {\r
+ this.factories = factories;\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+/**\r
+ * Default implementation of <code>RunnableDataNode</code>\r
+ *\r
+ */\r
+public class DefaultRunnableDataNode implements RunnableDataNode {\r
+\r
+ private List<RunnableDataNode> children = new ArrayList<RunnableDataNode>();\r
+ \r
+ private RunnableDataNode parent;\r
+ \r
+ /**\r
+ * Data of the RunnableDataNode. Does not contain\r
+ * parent data.\r
+ */\r
+ private Map<String, Object> properData = new HashMap<String, Object>();\r
+ \r
+ private String path;\r
+ \r
+ private String beanName;\r
+\r
+ public boolean isLeaf() {\r
+ return children.size() == 0;\r
+ }\r
+ \r
+ public List<RunnableDataNode> getChildren() {\r
+ return children;\r
+ }\r
+\r
+ public void addChild(RunnableDataNode child) {\r
+ child.setParent(this);\r
+ children.add(child);\r
+ }\r
+ \r
+ public Map<String, Object> getData() {\r
+ Map<String, Object> data = new HashMap<String, Object>();\r
+ if(parent != null) {\r
+ Map<String, Object> parentData = parent.getData();\r
+ if(parentData != null) {\r
+ data.putAll(parentData);\r
+ }\r
+ }\r
+ // entries defined in parentData can be overridden\r
+ // in properData\r
+ if(properData != null) {\r
+ data.putAll(properData);\r
+ }\r
+ return data;\r
+ }\r
+\r
+ public Map<String, Object> getProperData() {\r
+ return properData;\r
+ }\r
+\r
+ public void setProperData(Map<String, Object> properData) {\r
+ this.properData = properData;\r
+ }\r
+\r
+ public String getPath() {\r
+ return path;\r
+ }\r
+\r
+ public void setPath(String path) {\r
+ this.path = path;\r
+ }\r
+\r
+ public String getBeanName() {\r
+ return beanName;\r
+ }\r
+\r
+ public void setBeanName(String beanName) {\r
+ this.beanName = beanName;\r
+ }\r
+\r
+ public void setParent(RunnableDataNode parent) {\r
+ this.parent = parent;\r
+ }\r
+\r
+ public RunnableDataNode getParent() {\r
+ return parent;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.SlcException;\r
+import org.springframework.aop.scope.ScopedProxyUtils;\r
+import org.springframework.beans.BeansException;\r
+import org.springframework.beans.MutablePropertyValues;\r
+import org.springframework.beans.factory.config.BeanDefinitionHolder;\r
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;\r
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;\r
+import org.springframework.beans.factory.config.RuntimeBeanReference;\r
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
+import org.springframework.beans.factory.support.GenericBeanDefinition;\r
+import org.springframework.core.Ordered;\r
+\r
+/**\r
+ * Generates <code>ExecutionFlows</code> and <code>Runnables</code> as\r
+ * beans in the Spring Application Context.\r
+ * Called by the Application Context as a <code>BeanFactoryPostProcessor</code>.\r
+ * Two kinds of beans are generated:\r
+ * <code>RunnableCallFlow</code>, calling a list of <code>Runnables</code> from the\r
+ * Application Context after configuring the <code>ExecutionContext</code>, \r
+ * and outputs of a <code>RunnableFactory</code>.\r
+ */\r
+public class ExecutionFlowGenerator implements BeanFactoryPostProcessor,\r
+ Ordered {\r
+ \r
+ private final Log log = LogFactory.getLog(getClass());\r
+\r
+ /**\r
+ * Source providing a list of <code>RunnableCallFlowDescriptor</code> \r
+ * used to create <code>RunnableCallFlow</code> and a list of \r
+ * <code>RunnableDataNode</code> used to create any kind of flow via a factory\r
+ */\r
+ protected ExecutionFlowGeneratorSource source;\r
+ \r
+ /**\r
+ * Factory used to create Runnables in the Application context from\r
+ * the <code>RunnableDataNode</code> provided from the source.\r
+ */\r
+ protected RunnableFactory runnableFactory;\r
+ \r
+ /**\r
+ * Bean name of the <code>ExecutionContext</code>.\r
+ * Used to provide the created <code>RunnableCallFlow</code> beans \r
+ * with a <code>RuntimeBeanReference</code> to\r
+ * the <code>ExecutionContext</code>\r
+ */\r
+ private String executionContextBeanName = "executionContext";\r
+ \r
+ /**\r
+ * Bean name of the context values Map.\r
+ * A bean of class HashMap is created with this name, and a \r
+ * <code>RuntimeBeanReference</code> is provided to the created\r
+ * <code>RunnableCallFlow</code> beans.\r
+ */\r
+ private String contextValuesBeanName = "executionFlowGenerator.contextValues";\r
+ \r
+ /**\r
+ * Prefix added to the bean names defined in each \r
+ * <code>RunnableCallFlowDescriptor</code>\r
+ */\r
+ private String flowBeanNamesPrefix = "";\r
+ \r
+ private int order = Ordered.HIGHEST_PRECEDENCE;\r
+ \r
+ public void postProcessBeanFactory(\r
+ ConfigurableListableBeanFactory beanFactory) throws BeansException {\r
+\r
+ // assert that the beanFactory is a BeanDefinitionRegistry\r
+ if (!(beanFactory instanceof BeanDefinitionRegistry)) {\r
+ throw new SlcException("Can only work on "\r
+ + BeanDefinitionRegistry.class);\r
+ } \r
+ \r
+ // add bean for the Context Values Map\r
+ createAndRegisterContextValuesBean((BeanDefinitionRegistry) beanFactory);\r
+ \r
+ // add beans for each RunnableDataNode\r
+ for(RunnableDataNode node : source.getRunnableDataNodes()) {\r
+ runnableFactory.createAndRegisterRunnable(node, (BeanDefinitionRegistry) beanFactory);\r
+ }\r
+ \r
+ // add beans for each RunnableCallFlowDescriptor of the source to the application context\r
+ for (RunnableCallFlowDescriptor descriptor : source\r
+ .getRunnableCallFlowDescriptors()) {\r
+ createAndRegisterFlowFor(descriptor, (BeanDefinitionRegistry) beanFactory);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Creates a <code>RunnableCallFlow</code> bean\r
+ * for a <code>RunnableCallFlowDescriptor</code> and registers \r
+ * it in the <code>BeanDefinitionRegistry</code>\r
+ * @param flowDescriptor\r
+ * @param registry\r
+ */\r
+ private void createAndRegisterFlowFor(RunnableCallFlowDescriptor flowDescriptor, BeanDefinitionRegistry registry) {\r
+ // create the flow bean\r
+ GenericBeanDefinition flowBean = new GenericBeanDefinition();\r
+ flowBean.setBeanClass(RunnableCallFlow.class);\r
+ \r
+ String beanName = flowBeanNamesPrefix + flowDescriptor.getBeanName();\r
+ \r
+ MutablePropertyValues mpv = new MutablePropertyValues(); \r
+ mpv.addPropertyValue("runnableCalls", flowDescriptor.getRunnableCalls());\r
+ mpv.addPropertyValue("sharedContextValuesMap", new RuntimeBeanReference(contextValuesBeanName));\r
+ \r
+ mpv.addPropertyValue("name", beanName);\r
+ mpv.addPropertyValue("path", flowDescriptor.getPath());\r
+\r
+ mpv.addPropertyValue("executionContext", new RuntimeBeanReference(executionContextBeanName));\r
+ \r
+ flowBean.setPropertyValues(mpv);\r
+ \r
+ // register it\r
+ if(log.isDebugEnabled()) {\r
+ log.debug("Registering bean definition for RunnableCallFlow " + beanName);\r
+ }\r
+ registry.registerBeanDefinition(beanName, flowBean);\r
+ }\r
+ \r
+ /**\r
+ * Creates the Context Values bean and register it in the\r
+ * <code>BeanDefinitionRegistry</code>\r
+ * @param registry\r
+ */\r
+ private void createAndRegisterContextValuesBean(BeanDefinitionRegistry registry) {\r
+ GenericBeanDefinition contextValuesBean = new GenericBeanDefinition();\r
+ contextValuesBean.setBeanClass(HashMap.class);\r
+ \r
+ BeanDefinitionHolder bdh = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(contextValuesBean, contextValuesBeanName), registry, true); \r
+ registry.registerBeanDefinition(contextValuesBeanName, bdh.getBeanDefinition()); \r
+ }\r
+ \r
+ public int getOrder() {\r
+ return order;\r
+ }\r
+\r
+ public void setOrder(int order) {\r
+ this.order = order;\r
+ }\r
+\r
+ public void setSource(ExecutionFlowGeneratorSource source) {\r
+ this.source = source;\r
+ }\r
+\r
+ public void setRunnableFactory(RunnableFactory runnableFactory) {\r
+ this.runnableFactory = runnableFactory;\r
+ }\r
+\r
+ public void setExecutionContextBeanName(String executionContextBeanName) {\r
+ this.executionContextBeanName = executionContextBeanName;\r
+ }\r
+\r
+ public void setContextValuesBeanName(String contextValuesBeanName) {\r
+ this.contextValuesBeanName = contextValuesBeanName;\r
+ }\r
+\r
+ public void setFlowBeanNamesPrefix(String flowBeanNamesPrefix) {\r
+ this.flowBeanNamesPrefix = flowBeanNamesPrefix;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Provides 2 types of information required by an <code>ExecutionFlowGenerator</code>: \r
+ * a list of <code>RunnableCallFlowDescriptor</code> used to create <code>RunnableCallFlow</code>\r
+ * and a list of <code>RunnableDataNode</code> used to create any kind of flow via a factory.\r
+ */\r
+public interface ExecutionFlowGeneratorSource {\r
+ \r
+ /**\r
+ * @return a list of <code>RunnableCallFlowDescriptor</code> used \r
+ * by a <code>ExecutionFlowGenerator</code> to create <code>RunnableCallFlow</code>\r
+ */\r
+ public List<RunnableCallFlowDescriptor> getRunnableCallFlowDescriptors();\r
+ \r
+ /**\r
+ * @return a list of <code>RunnableDataNode</code> used \r
+ * by a <code>ExecutionFlowGenerator</code> to create any kind of flow via a factory\r
+ */\r
+ public List<RunnableDataNode> getRunnableDataNodes();\r
+ \r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.Map;\r
+\r
+/**\r
+ * Storage class for information required to call a flow \r
+ * of the Spring execution context: \r
+ * bean name of the flow,\r
+ * variables to add to the Execution Context before the call \r
+ * and variables (context values) to add to a Map \r
+ * potentially referenced by the called flow \r
+ */\r
+public class RunnableCall {\r
+ \r
+ /**\r
+ * Bean name of the flow to call\r
+ */\r
+ private String beanName;\r
+ \r
+ /**\r
+ * Variables to add to the execution context before the call\r
+ */\r
+ private Map<String, Object> executionVariables;\r
+ \r
+ /**\r
+ * Variables to add to the Map potentially referenced by\r
+ * the called flow\r
+ */\r
+ private Map<String, Object> contextValues;\r
+\r
+ public String getBeanName() {\r
+ return beanName;\r
+ }\r
+\r
+ public void setBeanName(String beanName) {\r
+ this.beanName = beanName;\r
+ }\r
+\r
+ public Map<String, Object> getExecutionVariables() {\r
+ return executionVariables;\r
+ }\r
+\r
+ public void setExecutionVariables(Map<String, Object> executionVariables) {\r
+ this.executionVariables = executionVariables;\r
+ }\r
+\r
+ public Map<String, Object> getContextValues() {\r
+ return contextValues;\r
+ }\r
+\r
+ public void setContextValues(Map<String, Object> contextValues) {\r
+ this.contextValues = contextValues;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.core.execution.DefaultExecutionSpec;\r
+import org.argeo.slc.execution.ExecutionContext;\r
+import org.argeo.slc.execution.ExecutionFlow;\r
+import org.argeo.slc.execution.ExecutionSpec;\r
+import org.springframework.context.ApplicationContext;\r
+import org.springframework.context.ApplicationContextAware;\r
+\r
+/**\r
+ * Execution Flow calling a list of <code>Runnable</code> (identified by their\r
+ * bean name in the Spring Application Context) after configuring the Execution\r
+ * context and a Map potentially shared by the called <code>Runnable</code>\r
+ * \r
+ */\r
+public class RunnableCallFlow implements ExecutionFlow, ApplicationContextAware {\r
+\r
+ private final static Log log = LogFactory.getLog(RunnableCallFlow.class);\r
+\r
+ /**\r
+ * Key in the execution context for the index of the call (e.g. 0 for the\r
+ * first runnable called, ...)\r
+ */\r
+ public final static String VAR_CALL_INDEX = "slcVar.runnableCallFlow.callIndex";\r
+\r
+ /**\r
+ * Name of the flow. Also bean name\r
+ */\r
+ private String name;\r
+\r
+ /**\r
+ * Path of the flow\r
+ */\r
+ private String path;\r
+\r
+ /**\r
+ * Whether an exception in a <code>Runnable</code> shall stop the execution\r
+ * of the flow\r
+ */\r
+ private Boolean failOnError = true;\r
+\r
+ /**\r
+ * List of <code>Runnable</code> to call, with bean name, execution\r
+ * variables and context values\r
+ */\r
+ private List<RunnableCall> runnableCalls;\r
+\r
+ /**\r
+ * Map potentially referenced by called flows. Updated with the context\r
+ * values of a Runnable before calling it.\r
+ */\r
+ private Map<String, Object> sharedContextValuesMap;\r
+\r
+ /**\r
+ * ExecutionSpec of the flow. Does not contain any attribute.\r
+ */\r
+ private ExecutionSpec executionSpec = new DefaultExecutionSpec();\r
+\r
+ /**\r
+ * Reference to the ExecutionContext\r
+ */\r
+ private ExecutionContext executionContext;\r
+\r
+ /**\r
+ * Reference to the Spring <code>ApplicationContext</code>. Set via\r
+ * <code>setApplicationContext</code>, the class implementing\r
+ * <code>ApplicationContextAware</code>\r
+ */\r
+ private ApplicationContext applicationContext;\r
+\r
+ /**\r
+ * Runs a <code>Runnable</code> after configuring the Execution Context and\r
+ * <code>sharedContextValuesMap</code>\r
+ * \r
+ * @param runnable\r
+ * the <code>Runnable</code> to call\r
+ * @param executionVariables\r
+ * the variables to add to the <code>ExecutionContext</code>\r
+ * @param contextValues\r
+ * the variables to add to <code>sharedContextValuesMap</code>\r
+ * @param callIndex\r
+ * index of the call (0 for the first called\r
+ * <code>Runnable</code>) set as variable of the\r
+ * <code>ExecutionContext</code>\r
+ */\r
+ private void run(Runnable runnable, Map<String, Object> executionVariables,\r
+ Map<String, Object> contextValues, int callIndex) {\r
+ // add all variables to the Execution Context\r
+ for (Map.Entry<String, Object> entry : executionVariables.entrySet()) {\r
+ executionContext.setVariable(entry.getKey(), entry.getValue());\r
+ }\r
+\r
+ // add call Index Variable\r
+ executionContext.setVariable(VAR_CALL_INDEX, callIndex);\r
+\r
+ // clear sharedContextValues and add all values of contextValues\r
+ if (sharedContextValuesMap != null) {\r
+ sharedContextValuesMap.clear();\r
+ sharedContextValuesMap.putAll(contextValues);\r
+ }\r
+\r
+ // then run the runnable\r
+ doExecuteRunnable(runnable);\r
+ }\r
+\r
+ public void doExecuteRunnable(Runnable runnable) {\r
+ runnable.run();\r
+ }\r
+\r
+ /**\r
+ * Executes the flow. For each <code>RunnableCall</code>, the corresponding\r
+ * flow is retrieved from the Spring Application Context, the\r
+ * <code>ExecutionContext</code> and <code>sharedContextValuesMap</code> are\r
+ * configured and the <code>Runnable</code> is called.\r
+ */\r
+ public void run() {\r
+ if (applicationContext == null) {\r
+ throw new SlcException("No ApplicationContext defined");\r
+ }\r
+\r
+ try {\r
+ for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
+ RunnableCall runnableCall = runnableCalls.get(callIndex);\r
+ Object bean = applicationContext.getBean(\r
+ runnableCall.getBeanName(), Runnable.class);\r
+ if (log.isDebugEnabled())\r
+ log.debug("Running flow '" + runnableCall.getBeanName()\r
+ + "'");\r
+ run((Runnable) bean, runnableCall.getExecutionVariables(),\r
+ runnableCall.getContextValues(), callIndex);\r
+ }\r
+ } catch (RuntimeException e) {\r
+ if (failOnError)\r
+ throw e;\r
+ else {\r
+ log.error("Execution flow failed,"\r
+ + " but process did not fail"\r
+ + " because failOnError property"\r
+ + " is set to false: " + e);\r
+ if (log.isTraceEnabled())\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
+ public Iterator<Runnable> runnables() {\r
+ List<Runnable> runnables = new ArrayList<Runnable>();\r
+ for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
+ RunnableCall runnableCall = runnableCalls.get(callIndex);\r
+ Object bean = applicationContext.getBean(\r
+ runnableCall.getBeanName(), Runnable.class);\r
+ runnables.add((Runnable) bean);\r
+ }\r
+ return runnables.iterator();\r
+ }\r
+\r
+ public Runnable getRunnable() {\r
+ if (runnableCalls.size() == 1)\r
+ return runnables().next();\r
+ else\r
+ throw new SlcException("There are " + runnableCalls.size()\r
+ + " runnables in flow " + getName());\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return new StringBuffer("RunnableCallFlow ").append(name).toString();\r
+ }\r
+\r
+ public ExecutionSpec getExecutionSpec() {\r
+ return executionSpec;\r
+ }\r
+\r
+ public String getName() {\r
+ return name;\r
+ }\r
+\r
+ public Object getParameter(String key) {\r
+ throw new SlcException("RunnableCallFlow have no parameters");\r
+ }\r
+\r
+ public String getPath() {\r
+ return path;\r
+ }\r
+\r
+ public Boolean isSetAsParameter(String key) {\r
+ // The ExecutionSpec having no attribute,\r
+ // always return false\r
+ return false;\r
+ }\r
+\r
+ public void setName(String name) {\r
+ this.name = name;\r
+ }\r
+\r
+ public void setPath(String path) {\r
+ this.path = path;\r
+ }\r
+\r
+ public void setExecutionContext(ExecutionContext executionContext) {\r
+ this.executionContext = executionContext;\r
+ }\r
+\r
+ public void setRunnableCalls(List<RunnableCall> runnableCalls) {\r
+ this.runnableCalls = runnableCalls;\r
+ }\r
+\r
+ public void setApplicationContext(ApplicationContext applicationContext) {\r
+ this.applicationContext = applicationContext;\r
+ }\r
+\r
+ public void setSharedContextValuesMap(Map<String, Object> contextValues) {\r
+ this.sharedContextValuesMap = contextValues;\r
+ }\r
+\r
+ public void setFailOnError(Boolean failOnError) {\r
+ this.failOnError = failOnError;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+/**\r
+ * Storage Class for information required to\r
+ * instantiate a <code>RunnableCallFlow</code>:\r
+ * bean name of the flow, \r
+ * path of the flow \r
+ * and list of <code>RunnableCall</code>. \r
+ *\r
+ */\r
+public class RunnableCallFlowDescriptor {\r
+ \r
+ /**\r
+ * Bean name of the flow to instantiate\r
+ */\r
+ private String beanName;\r
+ \r
+ /**\r
+ * Path of the flow to instantiate\r
+ */\r
+ private String path;\r
+ \r
+ /**\r
+ * List of <code>RunnableCall</code> \r
+ */\r
+ private List<RunnableCall> runnableCalls = new ArrayList<RunnableCall>();\r
+\r
+ public String getBeanName() {\r
+ return beanName;\r
+ }\r
+\r
+ public void setBeanName(String beanName) {\r
+ this.beanName = beanName;\r
+ }\r
+\r
+ public String getPath() {\r
+ return path;\r
+ }\r
+\r
+ public void setPath(String path) {\r
+ this.path = path;\r
+ }\r
+\r
+ public List<RunnableCall> getRunnableCalls() {\r
+ return runnableCalls;\r
+ }\r
+\r
+ public void setRunnableCalls(List<RunnableCall> runnableCalls) {\r
+ this.runnableCalls = runnableCalls;\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+/**\r
+ * Stores information relative to a Runnable.\r
+ * Allows to structure the information as a tree, each node\r
+ * storing data as a Map.\r
+ */\r
+public interface RunnableDataNode {\r
+\r
+ /**\r
+ * @return a Map containing the data associated with this node.\r
+ * Data associated with parent nodes are expected\r
+ * to be contained in the returned Map\r
+ */\r
+ public Map<String, Object> getData(); \r
+\r
+ /**\r
+ * @return the name of the bean to create.\r
+ * Can be null if no bean shall be created for the \r
+ * <code>RunnableDataNode</code> (e.g. is is a sub-node)\r
+ */\r
+ public String getBeanName();\r
+ \r
+ /**\r
+ * @return the path of the flow bean to create.\r
+ * Can be null if the bean to created is not an\r
+ * <code>ExecutionFlow</code> or if no bean shall be created for the \r
+ * <code>RunnableDataNode</code> (e.g. is is a sub-node)\r
+ */\r
+ public String getPath();\r
+ \r
+ /**\r
+ * @return whether the <code>RunnableDataNode</code> has\r
+ * children or not.\r
+ * Expected to be equivalent to <code>getChildren().empty()</code>\r
+ */\r
+ public boolean isLeaf();\r
+\r
+ /**\r
+ * @return the list of <code>RunnableDataNode</code> children.\r
+ * Can be empty. Shall not be null.\r
+ */\r
+ public List<RunnableDataNode> getChildren();\r
+ \r
+ /**\r
+ * @return the <code>RunnableDataNode</code> parent.\r
+ * Can be null if no parent is defined (top node).\r
+ */\r
+ public RunnableDataNode getParent();\r
+ \r
+ /**\r
+ * Sets the <code>RunnableDataNode</code> parent\r
+ * @param parent\r
+ */\r
+ public void setParent(RunnableDataNode parent); \r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.generator;\r
+\r
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
+\r
+/**\r
+ * Interprets a <code>RunnableDataNode</code> by creating corresponding\r
+ * beans and registering them in a <code>BeanDefinitionRegistry</code>\r
+ *\r
+ */\r
+public interface RunnableFactory {\r
+\r
+ public void createAndRegisterRunnable(RunnableDataNode node,\r
+ BeanDefinitionRegistry beanDefinitionRegistry);\r
+}\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2007-2012 Argeo GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under
+ the Apache License, Version 2.0 (the "License"); you may not use this file
+ except in compliance with the License. You may obtain a copy of the License
+ at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
+ law or agreed to in writing, software distributed under the License is distributed
+ on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ express or implied. See the License for the specific language governing permissions
+ and limitations under the License. -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+ <description>Bare minimal runtime configuration. In general you will
+ want to use simple.xml instead.</description>
+
+ <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
+ <property name="scopes">
+ <map>
+ <entry key="execution">
+ <bean class="org.argeo.slc.core.execution.ExecutionScope" />
+ </entry>
+ </map>
+ </property>
+ </bean>
+
+
+ <bean id="executionStack" class="org.argeo.slc.core.execution.DefaultExecutionStack"
+ scope="execution">
+ <aop:scoped-proxy proxy-target-class="false" />
+ </bean>
+
+ <bean id="instantiationManager" class="org.argeo.slc.core.execution.InstantiationManager" />
+
+ <bean class="org.argeo.slc.core.execution.ExecutionParameterPostProcessor">
+ <property name="executionContext" ref="executionContext" />
+ <property name="instantiationManager" ref="instantiationManager" />
+ </bean>
+
+ <bean class="org.argeo.slc.core.execution.ExecutionAspect">
+ <property name="executionStack" ref="executionStack" />
+ <property name="executionContext" ref="executionContext" />
+ </bean>
+
+ <aop:aspectj-autoproxy />
+
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2007-2012 Argeo GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under
+ the Apache License, Version 2.0 (the "License"); you may not use this file
+ except in compliance with the License. You may obtain a copy of the License
+ at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
+ law or agreed to in writing, software distributed under the License is distributed
+ on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ express or implied. See the License for the specific language governing permissions
+ and limitations under the License. -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
+ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+ <description>Default Capabilities</description>
+
+ <import resource="runtime.xml" />
+
+ <bean id="executionContext" class="org.argeo.slc.core.execution.MapExecutionContext"
+ scope="execution">
+ <aop:scoped-proxy proxy-target-class="false" />
+ </bean>
+
+ <bean id="executionFlowDescriptorConverter"
+ class="org.argeo.slc.core.execution.DefaultExecutionFlowDescriptorConverter"></bean>
+
+ <bean
+ class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
+ <property name="ignoreUnresolvablePlaceholders" value="true" />
+ </bean>
+
+ <bean id="parameterRef" class="org.argeo.slc.core.execution.ParameterRef"
+ abstract="true">
+ <property name="instantiationManager" ref="instantiationManager" />
+ </bean>
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2007-2012 Argeo GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+ <bean id="specAttr.primitive" class="org.argeo.slc.core.execution.PrimitiveSpecAttribute"
+ abstract="true" />
+ <bean id="specAttr.resource" class="org.argeo.slc.core.execution.ResourceSpecAttribute"
+ abstract="true" />
+ <bean id="specAttr.ref" class="org.argeo.slc.core.execution.RefSpecAttribute"
+ abstract="true" />
+
+ <bean id="slcTemplate.simpleFlow" class="org.argeo.slc.core.execution.DefaultExecutionFlow"
+ abstract="true" />
+ <bean id="slcTemplate.simpleSpec" class="org.argeo.slc.core.execution.DefaultExecutionSpec"
+ abstract="true" />
+
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2007-2012 Argeo GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under
+ the Apache License, Version 2.0 (the "License"); you may not use this file
+ except in compliance with the License. You may obtain a copy of the License
+ at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
+ law or agreed to in writing, software distributed under the License is distributed
+ on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ express or implied. See the License for the specific language governing permissions
+ and limitations under the License. -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
+ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+ <description>
+ Simple runtime enriched with defaults and templates used
+ to simplify XML files. These templates have been deprecated by the
+ custom XML namespace and will be removed in SLC 2.x. Use the XML
+ namespace instead.
+ </description>
+
+ <import resource="simple.xml" />
+
+ <import resource="specs.xml" />
+ <import resource="templates.xml" />
+ <import resource="defaults.xml" />
+ <import resource="utils.xml" />
+ <import resource="tasks/core.xml" />
+
+</beans>
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import org.argeo.slc.test.TestResult;
+
+public class CloseTestResult implements Runnable {
+ private TestResult testResult;
+
+ public void run() {
+ testResult.close();
+ }
+
+ public void setTestResult(TestResult testResult) {
+ this.testResult = testResult;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.core.io.Resource;
+
+public class Echo implements Runnable {
+ private final static Log defaultLog = LogFactory.getLog(Echo.class);
+ private Resource writeTo = null;
+
+ private Log log;
+ private Object message;
+
+ public void run() {
+ log().info(message);
+
+ if (writeTo != null) {
+ try {
+ File file = writeTo.getFile();
+ if (log().isDebugEnabled())
+ log().debug("Write to " + file);
+ if (message != null)
+ FileUtils.writeStringToFile(file, message.toString());
+ } catch (IOException e) {
+ throw new SlcException("Could not write to " + writeTo, e);
+ }
+ }
+ }
+
+ private Log log() {
+ return log != null ? log : defaultLog;
+ }
+
+ public void setMessage(Object message) {
+ this.message = message;
+ }
+
+ public void setWriteTo(Resource writeTo) {
+ this.writeTo = writeTo;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import org.argeo.slc.SlcException;
+
+/** Conditional execution */
+public class If implements Runnable {
+ private Boolean is;
+ private Boolean not;
+ private Runnable then;
+ private Runnable els;
+
+ public void run() {
+ if (is == null && not == null)
+ throw new SlcException("No condition set");
+ if (is != null && not != null)
+ throw new SlcException("Both is and not cannot be set");
+
+ boolean bool = (is != null ? is : !not);
+ if (bool) {
+ if (then != null)
+ then.run();
+ } else {
+ if (els != null)
+ els.run();
+ }
+
+ }
+
+ public void setIs(Boolean bool) {
+ this.is = bool;
+ }
+
+ public void setThen(Runnable then) {
+ this.then = then;
+ }
+
+ public void setEls(Runnable els) {
+ this.els = els;
+ }
+
+ public Boolean getNot() {
+ return not;
+ }
+
+ public void setNot(Boolean not) {
+ this.not = not;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.io.Resource;
+
+/** A Java Virtual Machine process. */
+public class JvmProcess extends SystemCall implements InitializingBean {
+ private Properties systemProperties = new Properties();
+ private List<Resource> classpath = new ArrayList<Resource>();
+ private List<Resource> pBootClasspath = new ArrayList<Resource>();
+ private Resource jvm = null;
+ private String mainClass;
+ private String mainJar;
+ private List<String> jvmArgs = new ArrayList<String>();
+ private List<String> args = new ArrayList<String>();
+
+ private String systemPropertiesFileProperty = null;
+ private String systemPropertiesFileDir = null;
+ private String systemPropertiesFileName = null;
+
+ public void afterPropertiesSet() throws Exception {
+ List<Object> command = new ArrayList<Object>();
+ if (jvm != null)
+ command.add(asFile(jvm).getPath());
+ else
+ command.add("java");
+
+ if (pBootClasspath.size() > 0) {
+ StringBuffer buf = new StringBuffer("-Xbootclasspath/p:");
+ Boolean first = true;
+ for (Resource res : pBootClasspath) {
+ if (first)
+ first = false;
+ else
+ buf.append(File.pathSeparatorChar);
+
+ buf.append(asFile(res));
+ }
+ command.add(buf.toString());
+ }
+
+ for (String jvmArg : jvmArgs) {
+ command.add(jvmArg);
+ }
+
+ if (classpath.size() > 0) {
+ command.add("-cp");
+ StringBuffer buf = new StringBuffer("");
+ for (Resource res : classpath) {
+ if (buf.length() != 0)
+ buf.append(File.pathSeparatorChar);
+ buf.append(asFile(res));
+ }
+ command.add(buf.toString());
+ }
+
+ if (systemPropertiesFileProperty == null) {
+ // pass system properties as argument
+ for (Map.Entry<Object, Object> entry : systemProperties.entrySet()) {
+ command.add("-D" + entry.getKey() + "=" + entry.getValue());
+ }
+ } else {
+ // write system properties in a file to work around OS limitations
+ // with command line (e.g. Win XP)
+ String dir = systemPropertiesFileDir;
+ if (dir == null)
+ dir = getExecDirToUse();
+ String fileName = systemPropertiesFileName;
+ if (fileName == null)
+ fileName = systemPropertiesFileProperty + ".properties";
+
+ // Write file
+ FileOutputStream fos = null;
+ File file = new File(dir + File.separator + fileName);
+ try {
+
+ if (!file.getParentFile().exists())
+ file.getParentFile().mkdirs();
+ fos = new FileOutputStream(file);
+ systemProperties.store(fos, "Automatically generated by "
+ + getClass());
+ command.add("-D" + systemPropertiesFileProperty + "="
+ + file.getCanonicalPath());
+ } catch (IOException e) {
+ throw new SlcException("Cannot write to system properties to "
+ + file, e);
+ } finally {
+ IOUtils.closeQuietly(fos);
+ }
+ }
+
+ // Program
+ if (mainClass != null) {
+ command.add(mainClass);
+ } else if (mainJar != null) {
+ command.add("-jar");
+ command.add(mainJar);
+ } else {
+ throw new SlcException("No main class or jar defined");
+ }
+
+ for (String arg : args) {
+ command.add(arg);
+ }
+
+ setCommand(command);
+ }
+
+ protected File asFile(Resource res) {
+ try {
+ return res.getFile();
+ } catch (FileNotFoundException e) {
+ return copyToTempFile(res);
+ } catch (IOException e) {
+ throw new SlcException("Cannot convert resource to file", e);
+ }
+
+ }
+
+ protected File copyToTempFile(Resource res) {
+ File tempFile;
+ FileOutputStream fos;
+ try {
+ tempFile = File.createTempFile("slcJvmProcess-", res.getFilename());
+ tempFile.deleteOnExit();
+ fos = new FileOutputStream(tempFile);
+ IOUtils.copy(res.getInputStream(), fos);
+ } catch (IOException e) {
+ throw new SlcException("Cannot copy " + res + " to temp file.", e);
+ }
+ IOUtils.closeQuietly(fos);
+ return tempFile;
+ }
+
+ /** Append the argument (for chaining) */
+ @Override
+ public SystemCall arg(String arg) {
+ args.add(arg);
+ return this;
+ }
+
+ /** Append the argument (for chaining) */
+ @Override
+ public SystemCall arg(String arg, String value) {
+ args.add(arg);
+ args.add(value);
+ return this;
+ }
+
+ public Properties getSystemProperties() {
+ return systemProperties;
+ }
+
+ public void setSystemProperties(Properties systemProperties) {
+ this.systemProperties = systemProperties;
+ }
+
+ public List<Resource> getClasspath() {
+ return classpath;
+ }
+
+ public void setClasspath(List<Resource> classpath) {
+ this.classpath = classpath;
+ }
+
+ public List<Resource> getPBootClasspath() {
+ return pBootClasspath;
+ }
+
+ public void setPBootClasspath(List<Resource> bootClasspath) {
+ pBootClasspath = bootClasspath;
+ }
+
+ public Resource getJvm() {
+ return jvm;
+ }
+
+ public void setJvm(Resource jvm) {
+ this.jvm = jvm;
+ }
+
+ public String getMainClass() {
+ return mainClass;
+ }
+
+ public void setMainClass(String mainClass) {
+ this.mainClass = mainClass;
+ }
+
+ public String getMainJar() {
+ return mainJar;
+ }
+
+ public void setMainJar(String mainJar) {
+ this.mainJar = mainJar;
+ }
+
+ public List<String> getJvmArgs() {
+ return jvmArgs;
+ }
+
+ public void setJvmArgs(List<String> jvmArgs) {
+ this.jvmArgs = jvmArgs;
+ }
+
+ public List<String> getArgs() {
+ return args;
+ }
+
+ public void setArgs(List<String> args) {
+ this.args = args;
+ }
+
+ public void setSystemPropertiesFileProperty(
+ String systemPropertiesFilePropertyName) {
+ this.systemPropertiesFileProperty = systemPropertiesFilePropertyName;
+ }
+
+ public void setSystemPropertiesFileDir(String systemPropertiesFileDir) {
+ this.systemPropertiesFileDir = systemPropertiesFileDir;
+ }
+
+ public void setSystemPropertiesFileName(String systemPropertiesFileName) {
+ this.systemPropertiesFileName = systemPropertiesFileName;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.FactoryBean;
+
+/** Merge the provided lists in one single list, in the order provided. */
+public class MergedLists implements FactoryBean {
+ private List<List<Object>> lists = new ArrayList<List<Object>>();
+
+ public void setLists(List<List<Object>> lists) {
+ this.lists = lists;
+ }
+
+ public Object getObject() throws Exception {
+ List<Object> merged = new ArrayList<Object>();
+ for (List<Object> lst : lists) {
+ merged.addAll(lst);
+ }
+ return merged;
+ }
+
+ public Class<?> getObjectType() {
+ return List.class;
+ }
+
+ public boolean isSingleton() {
+ return false;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.util.Assert;
+import org.springframework.util.ReflectionUtils;
+
+public class MethodCall implements Runnable {
+ private Object target;
+ private String method;
+ private List<Object> args = new ArrayList<Object>();
+
+ public void run() {
+ Assert.notNull(target, "target");
+ Assert.notNull(method, "method");
+ Method methodRef = ReflectionUtils
+ .findMethod(target.getClass(), method);
+ if (args.size() == 0)
+ ReflectionUtils.invokeMethod(methodRef, target);
+ else
+ ReflectionUtils.invokeMethod(methodRef, methodRef, args.toArray());
+ }
+
+ public void setTarget(Object target) {
+ this.target = target;
+ }
+
+ public void setMethod(String method) {
+ this.method = method;
+ }
+
+ public void setArgs(List<Object> args) {
+ this.args = args;
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.tasks;\r
+\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.core.test.context.SimpleContextAware;\r
+import org.argeo.slc.test.context.ContextAware;\r
+\r
+/**\r
+ * Overrides Values and Expected values of a target \r
+ * <code>SimpleContextAware</code> with the corresponding\r
+ * values and expected values of a source <code>ContextAware</code>\r
+ *\r
+ */\r
+public class OverrideContextAware implements Runnable {\r
+\r
+ private ContextAware source;\r
+\r
+ private SimpleContextAware target;\r
+ \r
+ /**\r
+ * Whether an exception shall be thrown if a value\r
+ * or expected value of the source is not defined\r
+ * in the target\r
+ */\r
+ private Boolean failIfUndefinedInSource = true;\r
+ \r
+ public void run() {\r
+ // override values\r
+ if(source.getValues() != null)\r
+ for(String key : source.getValues().keySet()) {\r
+ if(failIfUndefinedInSource && !target.getValues().containsKey(key)) {\r
+ throw new SlcException("No entry in target values for key '" + key + "'");\r
+ }\r
+ target.getValues().put(key, source.getValues().get(key));\r
+ }\r
+ \r
+ // override expected values\r
+ if(source.getExpectedValues() != null)\r
+ for(String key : source.getExpectedValues().keySet()) {\r
+ if(failIfUndefinedInSource && !target.getExpectedValues().containsKey(key)) {\r
+ throw new SlcException("No entry in target expected values for key '" + key + "'");\r
+ }\r
+ target.getExpectedValues().put(key, source.getExpectedValues().get(key));\r
+ } \r
+ } \r
+ \r
+ public void setSource(ContextAware source) {\r
+ this.source = source;\r
+ }\r
+\r
+ public void setTarget(SimpleContextAware target) {\r
+ this.target = target;\r
+ }\r
+\r
+ public void setFailIfUndefinedInSource(Boolean failIfUndefinedInSource) {\r
+ this.failIfUndefinedInSource = failIfUndefinedInSource;\r
+ } \r
+}\r
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteException;
+import org.apache.commons.exec.ExecuteResultHandler;
+import org.apache.commons.exec.ExecuteStreamHandler;
+import org.apache.commons.exec.ExecuteWatchdog;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.LogOutputStream;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.apache.commons.exec.ShutdownHookProcessDestroyer;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.UnsupportedException;
+import org.argeo.slc.core.execution.ExecutionResources;
+import org.argeo.slc.core.test.SimpleResultPart;
+import org.argeo.slc.test.TestResult;
+import org.argeo.slc.test.TestStatus;
+import org.springframework.core.io.Resource;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+/** Execute an OS specific system call. */
+public class SystemCall implements Runnable {
+ public final static String LOG_STDOUT = "System.out";
+
+ private final Log log = LogFactory.getLog(getClass());
+
+ private String execDir;
+
+ private String cmd = null;
+ private List<Object> command = null;
+
+ private Executor executor = new DefaultExecutor();
+ private Boolean synchronous = true;
+
+ private String stdErrLogLevel = "ERROR";
+ private String stdOutLogLevel = "INFO";
+
+ private Resource stdOutFile = null;
+ private Resource stdErrFile = null;
+
+ private Resource stdInFile = null;
+ /**
+ * If no {@link #stdInFile} provided, writing to this stream will write to
+ * the stdin of the process.
+ */
+ private OutputStream stdInSink = null;
+
+ private Boolean redirectStdOut = false;
+
+ private List<SystemCallOutputListener> outputListeners = Collections
+ .synchronizedList(new ArrayList<SystemCallOutputListener>());
+
+ private Map<String, List<Object>> osCommands = new HashMap<String, List<Object>>();
+ private Map<String, String> osCmds = new HashMap<String, String>();
+ private Map<String, String> environmentVariables = new HashMap<String, String>();
+
+ private Boolean logCommand = false;
+ private Boolean redirectStreams = true;
+ private Boolean exceptionOnFailed = true;
+ private Boolean mergeEnvironmentVariables = true;
+
+ private Authentication authentication;
+
+ private String osConsole = null;
+ private String generateScript = null;
+
+ /** 24 hours */
+ private Long watchdogTimeout = 24 * 60 * 60 * 1000l;
+
+ private TestResult testResult;
+
+ private ExecutionResources executionResources;
+
+ /** Sudo the command, as root if empty or as user if not. */
+ private String sudo = null;
+ // TODO make it more secure and robust, test only once
+ private final String sudoPrompt = UUID.randomUUID().toString();
+ private String askPassProgram = "/usr/libexec/openssh/ssh-askpass";
+ private boolean firstLine = true;
+ private CallbackHandler callbackHandler;
+ /** Chroot to the this path (must not be empty) */
+ private String chroot = null;
+
+ // Current
+ /** Current watchdog, null if process is completed */
+ ExecuteWatchdog currentWatchdog = null;
+
+ /** Empty constructor */
+ public SystemCall() {
+
+ }
+
+ /**
+ * Constructor based on the provided command list.
+ *
+ * @param command
+ * the command list
+ */
+ public SystemCall(List<Object> command) {
+ this.command = command;
+ }
+
+ /**
+ * Constructor based on the provided command.
+ *
+ * @param cmd
+ * the command. If the provided string contains no space a
+ * command list is initialized with the argument as first
+ * component (useful for chained construction)
+ */
+ public SystemCall(String cmd) {
+ if (cmd.indexOf(' ') < 0) {
+ command = new ArrayList<Object>();
+ command.add(cmd);
+ } else {
+ this.cmd = cmd;
+ }
+ }
+
+ /** Executes the system call. */
+ public void run() {
+ authentication = SecurityContextHolder.getContext().getAuthentication();
+
+ // Manage streams
+ Writer stdOutWriter = null;
+ OutputStream stdOutputStream = null;
+ Writer stdErrWriter = null;
+ InputStream stdInStream = null;
+ if (stdOutFile != null)
+ if (redirectStdOut)
+ stdOutputStream = createOutputStream(stdOutFile);
+ else
+ stdOutWriter = createWriter(stdOutFile, true);
+
+ if (stdErrFile != null) {
+ stdErrWriter = createWriter(stdErrFile, true);
+ } else {
+ if (stdOutFile != null && !redirectStdOut)
+ stdErrWriter = createWriter(stdOutFile, true);
+ }
+
+ try {
+ if (stdInFile != null)
+ stdInStream = stdInFile.getInputStream();
+ else {
+ stdInStream = new PipedInputStream();
+ stdInSink = new PipedOutputStream(
+ (PipedInputStream) stdInStream);
+ }
+ } catch (IOException e2) {
+ throw new SlcException("Cannot open a stream for " + stdInFile, e2);
+ }
+
+ if (log.isTraceEnabled()) {
+ log.debug("os.name=" + System.getProperty("os.name"));
+ log.debug("os.arch=" + System.getProperty("os.arch"));
+ log.debug("os.version=" + System.getProperty("os.version"));
+ }
+
+ // Execution directory
+ File dir = new File(getExecDirToUse());
+ // if (!dir.exists())
+ // dir.mkdirs();
+
+ // Watchdog to check for lost processes
+ Executor executorToUse;
+ if (executor != null)
+ executorToUse = executor;
+ else
+ executorToUse = new DefaultExecutor();
+ executorToUse.setWatchdog(createWatchdog());
+
+ if (redirectStreams) {
+ // Redirect standard streams
+ executorToUse.setStreamHandler(createExecuteStreamHandler(
+ stdOutWriter, stdOutputStream, stdErrWriter, stdInStream));
+ } else {
+ // Dummy stream handler (otherwise pump is used)
+ executorToUse.setStreamHandler(new DummyexecuteStreamHandler());
+ }
+
+ executorToUse.setProcessDestroyer(new ShutdownHookProcessDestroyer());
+ executorToUse.setWorkingDirectory(dir);
+
+ // Command line to use
+ final CommandLine commandLine = createCommandLine();
+ if (logCommand)
+ log.info("Execute command:\n" + commandLine
+ + "\n in working directory: \n" + dir + "\n");
+
+ // Env variables
+ Map<String, String> environmentVariablesToUse = null;
+ environmentVariablesToUse = new HashMap<String, String>();
+ if (mergeEnvironmentVariables)
+ environmentVariablesToUse.putAll(System.getenv());
+ if (environmentVariables.size() > 0)
+ environmentVariablesToUse.putAll(environmentVariables);
+
+ // Execute
+ ExecuteResultHandler executeResultHandler = createExecuteResultHandler(commandLine);
+
+ //
+ // THE EXECUTION PROPER
+ //
+ try {
+ if (synchronous)
+ try {
+ int exitValue = executorToUse.execute(commandLine,
+ environmentVariablesToUse);
+ executeResultHandler.onProcessComplete(exitValue);
+ } catch (ExecuteException e1) {
+ if (e1.getExitValue() == Executor.INVALID_EXITVALUE) {
+ Thread.currentThread().interrupt();
+ return;
+ }
+ // Sleep 1s in order to make sure error logs are flushed
+ Thread.sleep(1000);
+ executeResultHandler.onProcessFailed(e1);
+ }
+ else
+ executorToUse.execute(commandLine, environmentVariablesToUse,
+ executeResultHandler);
+ } catch (SlcException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new SlcException("Could not execute command " + commandLine,
+ e);
+ } finally {
+ IOUtils.closeQuietly(stdOutWriter);
+ IOUtils.closeQuietly(stdErrWriter);
+ IOUtils.closeQuietly(stdInStream);
+ IOUtils.closeQuietly(stdInSink);
+ }
+
+ }
+
+ public synchronized String function() {
+ final StringBuffer buf = new StringBuffer("");
+ SystemCallOutputListener tempOutputListener = new SystemCallOutputListener() {
+ private Long lineCount = 0l;
+
+ public void newLine(SystemCall systemCall, String line,
+ Boolean isError) {
+ if (!isError) {
+ if (lineCount != 0l)
+ buf.append('\n');
+ buf.append(line);
+ lineCount++;
+ }
+ }
+ };
+ addOutputListener(tempOutputListener);
+ run();
+ removeOutputListener(tempOutputListener);
+ return buf.toString();
+ }
+
+ public String asCommand() {
+ return createCommandLine().toString();
+ }
+
+ @Override
+ public String toString() {
+ return asCommand();
+ }
+
+ /**
+ * Build a command line based on the properties. Can be overridden by
+ * specific command wrappers.
+ */
+ protected CommandLine createCommandLine() {
+ // Check if an OS specific command overrides
+ String osName = System.getProperty("os.name");
+ List<Object> commandToUse = null;
+ if (osCommands.containsKey(osName))
+ commandToUse = osCommands.get(osName);
+ else
+ commandToUse = command;
+ String cmdToUse = null;
+ if (osCmds.containsKey(osName))
+ cmdToUse = osCmds.get(osName);
+ else
+ cmdToUse = cmd;
+
+ CommandLine commandLine = null;
+
+ // Which command definition to use
+ if (commandToUse == null && cmdToUse == null)
+ throw new SlcException("Please specify a command.");
+ else if (commandToUse != null && cmdToUse != null)
+ throw new SlcException(
+ "Specify the command either as a line or as a list.");
+ else if (cmdToUse != null) {
+ if (chroot != null && !chroot.trim().equals(""))
+ cmdToUse = "chroot \"" + chroot + "\" " + cmdToUse;
+ if (sudo != null) {
+ environmentVariables.put("SUDO_ASKPASS", askPassProgram);
+ if (!sudo.trim().equals(""))
+ cmdToUse = "sudo -p " + sudoPrompt + " -u " + sudo + " "
+ + cmdToUse;
+ else
+ cmdToUse = "sudo -p " + sudoPrompt + " " + cmdToUse;
+ }
+
+ // GENERATE COMMAND LINE
+ commandLine = CommandLine.parse(cmdToUse);
+ } else if (commandToUse != null) {
+ if (commandToUse.size() == 0)
+ throw new SlcException("Command line is empty.");
+
+ if (chroot != null && sudo != null) {
+ commandToUse.add(0, "chroot");
+ commandToUse.add(1, chroot);
+ }
+
+ if (sudo != null) {
+ environmentVariables.put("SUDO_ASKPASS", askPassProgram);
+ commandToUse.add(0, "sudo");
+ commandToUse.add(1, "-p");
+ commandToUse.add(2, sudoPrompt);
+ if (!sudo.trim().equals("")) {
+ commandToUse.add(3, "-u");
+ commandToUse.add(4, sudo);
+ }
+ }
+
+ // GENERATE COMMAND LINE
+ commandLine = new CommandLine(commandToUse.get(0).toString());
+
+ for (int i = 1; i < commandToUse.size(); i++) {
+ if (log.isTraceEnabled())
+ log.debug(commandToUse.get(i));
+ commandLine.addArgument(commandToUse.get(i).toString());
+ }
+ } else {
+ // all cases covered previously
+ throw new UnsupportedException();
+ }
+
+ if (generateScript != null) {
+ File scriptFile = new File(getExecDirToUse() + File.separator
+ + generateScript);
+ try {
+ FileUtils.writeStringToFile(scriptFile,
+ (osConsole != null ? osConsole + " " : "")
+ + commandLine.toString());
+ } catch (IOException e) {
+ throw new SlcException("Could not generate script "
+ + scriptFile, e);
+ }
+ commandLine = new CommandLine(scriptFile);
+ } else {
+ if (osConsole != null)
+ commandLine = CommandLine.parse(osConsole + " "
+ + commandLine.toString());
+ }
+
+ return commandLine;
+ }
+
+ /**
+ * Creates a {@link PumpStreamHandler} which redirects streams to the custom
+ * logging mechanism.
+ */
+ protected ExecuteStreamHandler createExecuteStreamHandler(
+ final Writer stdOutWriter, final OutputStream stdOutputStream,
+ final Writer stdErrWriter, final InputStream stdInStream) {
+
+ // Log writers
+ OutputStream stdout = stdOutputStream != null ? stdOutputStream
+ : new LogOutputStream() {
+ protected void processLine(String line, int level) {
+ // if (firstLine) {
+ // if (sudo != null && callbackHandler != null
+ // && line.startsWith(sudoPrompt)) {
+ // try {
+ // PasswordCallback pc = new PasswordCallback(
+ // "sudo password", false);
+ // Callback[] cbs = { pc };
+ // callbackHandler.handle(cbs);
+ // char[] pwd = pc.getPassword();
+ // char[] arr = Arrays.copyOf(pwd,
+ // pwd.length + 1);
+ // arr[arr.length - 1] = '\n';
+ // IOUtils.write(arr, stdInSink);
+ // stdInSink.flush();
+ // } catch (Exception e) {
+ // throw new SlcException(
+ // "Cannot retrieve sudo password", e);
+ // }
+ // }
+ // firstLine = false;
+ // }
+
+ if (line != null && !line.trim().equals(""))
+ logStdOut(line);
+
+ if (stdOutWriter != null)
+ appendLineToFile(stdOutWriter, line);
+ }
+ };
+
+ OutputStream stderr = new LogOutputStream() {
+ protected void processLine(String line, int level) {
+ if (line != null && !line.trim().equals(""))
+ logStdErr(line);
+ if (stdErrWriter != null)
+ appendLineToFile(stdErrWriter, line);
+ }
+ };
+
+ PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(stdout,
+ stderr, stdInStream) {
+
+ @Override
+ public void stop() throws IOException {
+ // prevents the method to block when joining stdin
+ if (stdInSink != null)
+ IOUtils.closeQuietly(stdInSink);
+
+ super.stop();
+ }
+ };
+ return pumpStreamHandler;
+ }
+
+ /** Creates the default {@link ExecuteResultHandler}. */
+ protected ExecuteResultHandler createExecuteResultHandler(
+ final CommandLine commandLine) {
+ return new ExecuteResultHandler() {
+
+ public void onProcessComplete(int exitValue) {
+ String msg = "System call '" + commandLine
+ + "' properly completed.";
+ if (log.isTraceEnabled())
+ log.trace(msg);
+ if (testResult != null) {
+ forwardPath(testResult);
+ testResult.addResultPart(new SimpleResultPart(
+ TestStatus.PASSED, msg));
+ }
+ releaseWatchdog();
+ }
+
+ public void onProcessFailed(ExecuteException e) {
+
+ String msg = "System call '" + commandLine + "' failed.";
+ if (testResult != null) {
+ forwardPath(testResult);
+ testResult.addResultPart(new SimpleResultPart(
+ TestStatus.ERROR, msg, e));
+ } else {
+ if (exceptionOnFailed)
+ throw new SlcException(msg, e);
+ else
+ log.error(msg, e);
+ }
+ releaseWatchdog();
+ }
+ };
+ }
+
+ @Deprecated
+ protected void forwardPath(TestResult testResult) {
+ // TODO: allocate a TreeSPath
+ }
+
+ /**
+ * Shortcut method getting the execDir to use
+ */
+ protected String getExecDirToUse() {
+ try {
+ if (execDir != null) {
+ return execDir;
+ }
+ return System.getProperty("user.dir");
+ } catch (Exception e) {
+ throw new SlcException("Cannot find exec dir", e);
+ }
+ }
+
+ protected void logStdOut(String line) {
+ for (SystemCallOutputListener outputListener : outputListeners)
+ outputListener.newLine(this, line, false);
+ log(stdOutLogLevel, line);
+ }
+
+ protected void logStdErr(String line) {
+ for (SystemCallOutputListener outputListener : outputListeners)
+ outputListener.newLine(this, line, true);
+ log(stdErrLogLevel, line);
+ }
+
+ /** Log from the underlying streams. */
+ protected void log(String logLevel, String line) {
+ // TODO optimize
+ if (SecurityContextHolder.getContext().getAuthentication() == null) {
+ SecurityContextHolder.getContext()
+ .setAuthentication(authentication);
+ }
+
+ if ("ERROR".equals(logLevel))
+ log.error(line);
+ else if ("WARN".equals(logLevel))
+ log.warn(line);
+ else if ("INFO".equals(logLevel))
+ log.info(line);
+ else if ("DEBUG".equals(logLevel))
+ log.debug(line);
+ else if ("TRACE".equals(logLevel))
+ log.trace(line);
+ else if (LOG_STDOUT.equals(logLevel))
+ System.out.println(line);
+ else if ("System.err".equals(logLevel))
+ System.err.println(line);
+ else
+ throw new SlcException("Unknown log level " + logLevel);
+ }
+
+ /** Append line to a log file. */
+ protected void appendLineToFile(Writer writer, String line) {
+ try {
+ writer.append(line).append('\n');
+ } catch (IOException e) {
+ log.error("Cannot write to log file", e);
+ }
+ }
+
+ /** Creates the writer for the output/err files. */
+ protected Writer createWriter(Resource target, Boolean append) {
+ FileWriter writer = null;
+ try {
+
+ final File file;
+ if (executionResources != null)
+ file = new File(executionResources.getAsOsPath(target, true));
+ else
+ file = target.getFile();
+ writer = new FileWriter(file, append);
+ } catch (IOException e) {
+ log.error("Cannot get file for " + target, e);
+ IOUtils.closeQuietly(writer);
+ }
+ return writer;
+ }
+
+ /** Creates an outputstream for the output/err files. */
+ protected OutputStream createOutputStream(Resource target) {
+ FileOutputStream out = null;
+ try {
+
+ final File file;
+ if (executionResources != null)
+ file = new File(executionResources.getAsOsPath(target, true));
+ else
+ file = target.getFile();
+ out = new FileOutputStream(file, false);
+ } catch (IOException e) {
+ log.error("Cannot get file for " + target, e);
+ IOUtils.closeQuietly(out);
+ }
+ return out;
+ }
+
+ /** Append the argument (for chaining) */
+ public SystemCall arg(String arg) {
+ if (command == null)
+ command = new ArrayList<Object>();
+ command.add(arg);
+ return this;
+ }
+
+ /** Append the argument (for chaining) */
+ public SystemCall arg(String arg, String value) {
+ if (command == null)
+ command = new ArrayList<Object>();
+ command.add(arg);
+ command.add(value);
+ return this;
+ }
+
+ // CONTROL
+ public synchronized Boolean isRunning() {
+ return currentWatchdog != null;
+ }
+
+ private synchronized ExecuteWatchdog createWatchdog() {
+// if (currentWatchdog != null)
+// throw new SlcException("A process is already being monitored");
+ currentWatchdog = new ExecuteWatchdog(watchdogTimeout);
+ return currentWatchdog;
+ }
+
+ private synchronized void releaseWatchdog() {
+ currentWatchdog = null;
+ }
+
+ public synchronized void kill() {
+ if (currentWatchdog != null)
+ currentWatchdog.destroyProcess();
+ }
+
+ /** */
+ public void setCmd(String command) {
+ this.cmd = command;
+ }
+
+ public void setCommand(List<Object> command) {
+ this.command = command;
+ }
+
+ public void setExecDir(String execdir) {
+ this.execDir = execdir;
+ }
+
+ public void setStdErrLogLevel(String stdErrLogLevel) {
+ this.stdErrLogLevel = stdErrLogLevel;
+ }
+
+ public void setStdOutLogLevel(String stdOutLogLevel) {
+ this.stdOutLogLevel = stdOutLogLevel;
+ }
+
+ public void setSynchronous(Boolean synchronous) {
+ this.synchronous = synchronous;
+ }
+
+ public void setOsCommands(Map<String, List<Object>> osCommands) {
+ this.osCommands = osCommands;
+ }
+
+ public void setOsCmds(Map<String, String> osCmds) {
+ this.osCmds = osCmds;
+ }
+
+ public void setEnvironmentVariables(Map<String, String> environmentVariables) {
+ this.environmentVariables = environmentVariables;
+ }
+
+ public Map<String, String> getEnvironmentVariables() {
+ return environmentVariables;
+ }
+
+ public void setWatchdogTimeout(Long watchdogTimeout) {
+ this.watchdogTimeout = watchdogTimeout;
+ }
+
+ public void setStdOutFile(Resource stdOutFile) {
+ this.stdOutFile = stdOutFile;
+ }
+
+ public void setStdErrFile(Resource stdErrFile) {
+ this.stdErrFile = stdErrFile;
+ }
+
+ public void setStdInFile(Resource stdInFile) {
+ this.stdInFile = stdInFile;
+ }
+
+ public void setTestResult(TestResult testResult) {
+ this.testResult = testResult;
+ }
+
+ public void setLogCommand(Boolean logCommand) {
+ this.logCommand = logCommand;
+ }
+
+ public void setRedirectStreams(Boolean redirectStreams) {
+ this.redirectStreams = redirectStreams;
+ }
+
+ public void setExceptionOnFailed(Boolean exceptionOnFailed) {
+ this.exceptionOnFailed = exceptionOnFailed;
+ }
+
+ public void setMergeEnvironmentVariables(Boolean mergeEnvironmentVariables) {
+ this.mergeEnvironmentVariables = mergeEnvironmentVariables;
+ }
+
+ public void setOsConsole(String osConsole) {
+ this.osConsole = osConsole;
+ }
+
+ public void setGenerateScript(String generateScript) {
+ this.generateScript = generateScript;
+ }
+
+ public void setExecutionResources(ExecutionResources executionResources) {
+ this.executionResources = executionResources;
+ }
+
+ public void setRedirectStdOut(Boolean redirectStdOut) {
+ this.redirectStdOut = redirectStdOut;
+ }
+
+ public void addOutputListener(SystemCallOutputListener outputListener) {
+ outputListeners.add(outputListener);
+ }
+
+ public void removeOutputListener(SystemCallOutputListener outputListener) {
+ outputListeners.remove(outputListener);
+ }
+
+ public void setOutputListeners(
+ List<SystemCallOutputListener> outputListeners) {
+ this.outputListeners = outputListeners;
+ }
+
+ public void setExecutor(Executor executor) {
+ this.executor = executor;
+ }
+
+ public void setSudo(String sudo) {
+ this.sudo = sudo;
+ }
+
+ public void setCallbackHandler(CallbackHandler callbackHandler) {
+ this.callbackHandler = callbackHandler;
+ }
+
+ public void setChroot(String chroot) {
+ this.chroot = chroot;
+ }
+
+ private class DummyexecuteStreamHandler implements ExecuteStreamHandler {
+
+ public void setProcessErrorStream(InputStream is) throws IOException {
+ }
+
+ public void setProcessInputStream(OutputStream os) throws IOException {
+ }
+
+ public void setProcessOutputStream(InputStream is) throws IOException {
+ }
+
+ public void start() throws IOException {
+ }
+
+ public void stop() {
+ }
+
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+public interface SystemCallOutputListener {
+ public void newLine(SystemCall systemCall, String line, Boolean isError);
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.tasks;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.attachment.Attachment;
+import org.argeo.slc.core.attachment.AttachmentUploader;
+import org.argeo.slc.core.attachment.AttachmentsEnabled;
+import org.springframework.core.io.Resource;
+
+public class UploadAttachments implements Runnable {
+ private AttachmentUploader attachmentUploader;
+ private Attachment attachment = null;
+ private Resource resource = null;
+ private Map<Attachment, Resource> attachments = new HashMap<Attachment, Resource>();
+ private List<AttachmentsEnabled> attachTo = new ArrayList<AttachmentsEnabled>();
+ private Boolean newUuidPerExecution = true;
+
+ public void run() {
+ if (attachment != null) {
+ if (resource == null)
+ throw new SlcException("A resource must be specified.");
+ uploadAndAdd(attachment, resource);
+ }
+
+ for (Attachment attachmentT : attachments.keySet()) {
+ Resource resourceT = attachments.get(attachmentT);
+ uploadAndAdd(attachmentT, resourceT);
+ }
+
+ }
+
+ protected void uploadAndAdd(Attachment attachment, Resource resource) {
+ if (newUuidPerExecution)
+ attachment.setUuid(UUID.randomUUID().toString());
+ attachmentUploader.upload(attachment, resource);
+ for (AttachmentsEnabled attachmentsEnabled : attachTo) {
+ attachmentsEnabled.addAttachment(attachment);
+ }
+ }
+
+ public void setAttachmentUploader(AttachmentUploader attachmentUploader) {
+ this.attachmentUploader = attachmentUploader;
+ }
+
+ public void setAttachments(Map<Attachment, Resource> attachments) {
+ this.attachments = attachments;
+ }
+
+ public void setAttachTo(List<AttachmentsEnabled> attachTo) {
+ this.attachTo = attachTo;
+ }
+
+ public void setAttachment(Attachment attachment) {
+ this.attachment = attachment;
+ }
+
+ public void setResource(Resource resource) {
+ this.resource = resource;
+ }
+
+ public void setNewUuidPerExecution(Boolean newUuidPerExecution) {
+ this.newUuidPerExecution = newUuidPerExecution;
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2007-2012 Argeo GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+ <bean id="task.echo" class="org.argeo.slc.core.execution.tasks.Echo"
+ abstract="true" />
+ <bean id="task.systemCall" class="org.argeo.slc.core.execution.tasks.SystemCall"
+ abstract="true" />
+ <bean id="task.closeTestResult" class="org.argeo.slc.core.execution.tasks.CloseTestResult"
+ abstract="true" />
+ <bean id="task.slcManager" class="org.argeo.slc.core.execution.tasks.SlcManager"
+ abstract="true" />
+ <bean id="task.overrideContextAware" class="org.argeo.slc.core.execution.tasks.OverrideContextAware"
+ abstract="true" />
+ <bean id="task.uploadAttachments" class="org.argeo.slc.core.execution.tasks.UploadAttachments"
+ abstract="true" />
+
+ <bean id="taskArg.attachment" class="org.argeo.slc.core.attachment.SimpleAttachment"
+ abstract="true" />
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2007-2012 Argeo GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+ <bean id="slcTemplate.fileResources" class="org.argeo.slc.core.execution.FileExecutionResources"
+ abstract="true" />
+
+ <bean id="slcTemplate.resourcesFactoryBean" parent="slcTemplate.writableResource"
+ abstract="true" />
+
+ <bean id="slcTemplate.writableResource"
+ class="org.argeo.slc.core.execution.ExecutionResourcesFactoryBean"
+ abstract="true" />
+
+ <bean id="slcTemplate.osFile" class="org.argeo.slc.core.execution.OsFileFactoryBean"
+ abstract="true" />
+
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2007-2012 Argeo GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+ <bean id="mergedLists" class="org.argeo.slc.core.execution.tasks.MergedLists"
+ abstract="true">
+ </bean>
+</beans>
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.DefaultExecutionFlow;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+
+/** Publishes a {@link Runnable} as an {@link ExecutionFlow} */
+public class AsFlowDecorator implements BeanDefinitionDecorator {
+ private Log log = LogFactory.getLog(AsFlowDecorator.class);
+
+ @SuppressWarnings("unchecked")
+ public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder bean,
+ ParserContext ctx) {
+ String attrValue = ((Attr) node).getValue();
+ if (attrValue.charAt(attrValue.length() - 1) == '/')
+ throw new SlcException(attrValue + " cannot end with a path");
+ final String flowBeanName = attrValue;
+
+ if (log.isTraceEnabled())
+ log.trace("flowBeanName=" + flowBeanName);
+
+ if (ctx.getRegistry().containsBeanDefinition(flowBeanName))
+ throw new SlcException("A bean named " + flowBeanName
+ + " is already defined.");
+ BeanDefinitionBuilder flow = BeanDefinitionBuilder
+ .rootBeanDefinition(DefaultExecutionFlow.class);
+ ManagedList executables = new ManagedList(1);
+
+ String beanName = bean.getBeanName();
+ if (beanName == null)
+ executables.add(bean.getBeanDefinition());
+ else
+ executables.add(new RuntimeBeanReference(beanName));
+
+ // if (path != null)
+ // flow.addPropertyValue("path", path);
+ flow.addPropertyValue("executables", executables);
+
+ if (beanName != null)
+ ctx.getRegistry().registerBeanDefinition(flowBeanName,
+ flow.getBeanDefinition());
+ return bean;
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.execution.xml;\r
+\r
+import org.springframework.aop.scope.ScopedProxyUtils;\r
+import org.springframework.beans.factory.config.BeanDefinitionHolder;\r
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;\r
+import org.springframework.beans.factory.xml.BeanDefinitionDecorator;\r
+import org.springframework.beans.factory.xml.ParserContext;\r
+import org.w3c.dom.Element;\r
+import org.w3c.dom.Node;\r
+\r
+/**\r
+ * Inspired by org.springframework.aop.config.ScopedProxyBeanDefinitionDecorator\r
+ */\r
+public class ExecutionScopeDecorator implements BeanDefinitionDecorator { \r
+ private static final String PROXY_TARGET_CLASS = "proxy-target-class"; \r
+ \r
+ public BeanDefinitionHolder decorate(Node node,\r
+ BeanDefinitionHolder definition, ParserContext parserContext) {\r
+ \r
+ definition.getBeanDefinition().setScope("execution");\r
+ \r
+ // Default: CGLib not used\r
+ boolean proxyTargetClass = false;\r
+ if (node instanceof Element) {\r
+ Element ele = (Element) node;\r
+ if (ele.hasAttribute(PROXY_TARGET_CLASS)) {\r
+ proxyTargetClass = Boolean.valueOf(ele.getAttribute(PROXY_TARGET_CLASS)).booleanValue();\r
+ }\r
+ }\r
+ \r
+ // Register the original bean definition as it will be referenced by the scoped proxy and is relevant for tooling (validation, navigation).\r
+ String targetBeanName = ScopedProxyUtils.getTargetBeanName(definition.getBeanName());\r
+ parserContext.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(definition.getBeanDefinition(), targetBeanName));\r
+ \r
+ return ScopedProxyUtils.createScopedProxy(definition, parserContext.getRegistry(), proxyTargetClass); \r
+ }\r
+}\r
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.DefaultExecutionFlow;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.support.ManagedMap;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+import org.springframework.util.xml.DomUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/** Interprets the <flow:flow> tag */
+public class FlowBeanDefinitionParser extends
+ AbstractSingleBeanDefinitionParser {
+ private Log log = LogFactory.getLog(FlowBeanDefinitionParser.class);
+
+ /** Whether the user has already be warned on path attribute usage. */
+ private Boolean warnedAboutPathAttribute = false;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void doParse(Element element, ParserContext parserContext,
+ BeanDefinitionBuilder builder) {
+ String path = element.getAttribute("path");
+ if (StringUtils.hasText(path)) {
+ builder.addPropertyValue("path", path);
+
+ // warns user only once
+ if (!warnedAboutPathAttribute)
+ log.warn("The path=\"\" attribute is deprecated"
+ + " and will be removed in a later release."
+ + " Use <flow:flow name=\"/my/path/flowName\">.");
+ warnedAboutPathAttribute = true;
+ }
+
+ String spec = element.getAttribute("spec");
+ if (StringUtils.hasText(spec))
+ builder.getBeanDefinition().getConstructorArgumentValues()
+ .addGenericArgumentValue(new RuntimeBeanReference(spec));
+
+ String abstrac = element.getAttribute("abstract");
+ if (StringUtils.hasText(abstrac))
+ builder.setAbstract(Boolean.parseBoolean(abstrac));
+
+ String parent = element.getAttribute("parent");
+ if (StringUtils.hasText(parent))
+ builder.setParentName(parent);
+
+ builder.getBeanDefinition().setDescription(
+ DomUtils.getChildElementValueByTagName(element, "description"));
+
+ List<Element> argsElems = new ArrayList<Element>();
+ List<Element> execElems = new ArrayList<Element>();
+ List<Element> specElems = new ArrayList<Element>();
+ NodeList nodeList = element.getChildNodes();
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node node = nodeList.item(i);
+ if (node instanceof Element) {
+ if (DomUtils.nodeNameEquals(node, "arg"))
+ argsElems.add((Element) node);
+ else if (DomUtils.nodeNameEquals(node, "spec"))
+ specElems.add((Element) node);
+ else if (!DomUtils.nodeNameEquals(node, "description"))
+ execElems.add((Element) node);
+ }
+ }
+
+ // Arguments
+ if (argsElems.size() != 0) {
+ ManagedMap args = new ManagedMap(argsElems.size());
+ for (Element argElem : argsElems) {
+ Object value = NamespaceUtils.parseValue(argElem,
+ parserContext, builder.getBeanDefinition(), null);
+ if (value != null)
+ args.put(argElem.getAttribute("name"), value);
+ else
+ throw new SlcException("No value defined.");
+ }
+ builder.getBeanDefinition().getConstructorArgumentValues()
+ .addGenericArgumentValue(args);
+ }
+
+ // Execution specs
+ if (StringUtils.hasText(spec) && specElems.size() != 0)
+ throw new SlcException("A flow cannot have multiple specs");
+ if (specElems.size() == 1) {
+ Object specObj = NamespaceUtils.parseBeanOrReference(
+ specElems.get(0), parserContext,
+ builder.getBeanDefinition());
+ builder.getBeanDefinition().getConstructorArgumentValues()
+ .addGenericArgumentValue(specObj);
+ } else if (specElems.size() > 1)
+ throw new SlcException("A flow cannot have multiple specs");
+
+ // Executables
+ if (execElems.size() != 0) {
+ ManagedList executables = new ManagedList(execElems.size());
+ for (Element child : execElems) {
+ // child validity check is performed in xsd
+ executables.add(NamespaceUtils.parseBeanOrReference(child,
+ parserContext, builder.getBeanDefinition()));
+ }
+ if (executables.size() > 0)
+ builder.addPropertyValue("executables", executables);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Class<? extends ExecutionFlow> getBeanClass(Element element) {
+ String clss = element.getAttribute("class");
+ if (StringUtils.hasText(clss))
+ // TODO: check that it actually works
+ try {
+ return (Class<? extends ExecutionFlow>) getClass()
+ .getClassLoader().loadClass(clss);
+ } catch (ClassNotFoundException e) {
+ try {
+ return (Class<? extends ExecutionFlow>) Thread
+ .currentThread().getContextClassLoader()
+ .loadClass(clss);
+ } catch (ClassNotFoundException e1) {
+ throw new SlcException("Cannot load class " + clss, e);
+ }
+ }
+ else
+ return DefaultExecutionFlow.class;
+ }
+
+ // parse nested bean definition
+ // private Object parseBeanReference(Element element,
+ // ParserContext parserContext, BeanDefinitionBuilder builder) {
+ // return parserContext.getDelegate().parsePropertySubElement(element,
+ // builder.getBeanDefinition());
+ // }
+
+ @Override
+ protected String resolveId(Element element,
+ AbstractBeanDefinition definition, ParserContext parserContext)
+ throws BeanDefinitionStoreException {
+ String name = element.getAttribute("name");
+ if (StringUtils.hasText(name)) {
+ return name;
+ } else {
+ return super.resolveId(element, definition, parserContext);
+ }
+ }
+
+ protected boolean shouldGenerateIdAsFallback() {
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+
+public class FlowNamespaceHandler extends NamespaceHandlerSupport {
+
+ public void init() {
+ registerBeanDefinitionParser("flow", new FlowBeanDefinitionParser());
+ registerBeanDefinitionParser("spec", new SpecBeanDefinitionParser());
+ registerBeanDefinitionDecoratorForAttribute("as-flow",
+ new AsFlowDecorator());
+ registerBeanDefinitionParser("param", new ParamDecorator());
+
+ // The objective was to replace
+ // - attribute scope="execution"
+ // - and element "aop:scoped-proxy"
+ // by a single attribute, using an attribute decorator
+ // this does not work correctly with other attribute decorators (e.g.
+ // p namespace) since this decorator needs to be called after all
+ // properties have been set on target bean.
+ // It works properly with element decorators (called after all attribute
+ // decorators
+ registerBeanDefinitionDecorator("variable", new ExecutionScopeDecorator());
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.xml.DomUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Utilities to simplify common tasks when interpreting a custom namespace and
+ * converting it into bean definitions.
+ */
+public class NamespaceUtils {
+ // private final static Log log = LogFactory.getLog(NamespaceUtils.class);
+
+ /**
+ * Returns the value defined either: directly by the the 'value' attribute,
+ * as reference by the 'ref' attribute or as a nested bean.
+ */
+ public static Object parseValue(Element element,
+ ParserContext parserContext,
+ BeanDefinition containingBeanDefintion, String valueTagName) {
+ Object value = null;
+ if (element.hasAttribute("value")) {
+ value = element.getAttribute("value");
+ }
+
+ if (element.hasAttribute("ref")) {
+ if (value != null)
+ throw new SlcException("Multiple value definition for "
+ + element);
+ value = new RuntimeBeanReference(element.getAttribute("ref"));
+ }
+
+ Element uniqueSubElem = null;
+ if (valueTagName != null) {
+ Element valueElem = DomUtils.getChildElementByTagName(element,
+ valueTagName);
+ if (valueElem != null) {
+ uniqueSubElem = findUniqueSubElement(valueElem);
+ if (uniqueSubElem == null)
+ throw new SlcException("No subelement found under "
+ + valueElem);
+ }
+ } else {// no intermediary tag
+ uniqueSubElem = findUniqueSubElement(element);
+ }
+
+ if (uniqueSubElem != null) {
+ if (value != null)
+ throw new SlcException("Multiple value definition for "
+ + element);
+ value = parseBeanOrReference(uniqueSubElem, parserContext,
+ containingBeanDefintion);
+ }
+ return value;
+ }
+
+ public static Element findUniqueSubElement(Element element) {
+ NodeList childNodes = element.getChildNodes();
+
+ Element uniqueSubElem = null;
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ Node node = childNodes.item(i);
+ if (node != null && node instanceof Element) {
+ if (uniqueSubElem == null)
+ uniqueSubElem = (Element) node;
+ else
+ throw new SlcException(
+ "There are more than one sub element under "
+ + element);
+ }
+ }
+ return uniqueSubElem;
+ }
+
+ public static Object parseBeanOrReference(Element element,
+ ParserContext parserContext, BeanDefinition beanDefinition) {
+ // return parserContext.getDelegate().parsePropertySubElement(element,
+ // beanDefinition);
+
+ BeanDefinitionParserDelegate deleg = parserContext.getDelegate();
+ // if ("bean".equals(element.getNodeName()))
+ // return deleg.parseBeanDefinitionElement(element, beanDefinition);
+ // else
+ return deleg.parsePropertySubElement(element, beanDefinition);
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import org.argeo.slc.core.execution.ParameterRef;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+
+public class ParamDecorator extends AbstractSingleBeanDefinitionParser {
+
+ // public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder
+ // bean,
+ // ParserContext ctx) {
+ // String paramName = ((Element) node).getAttribute("name");
+ // String propertyName = ((Element) node.getParentNode())
+ // .getAttribute("name");
+ // BeanDefinitionBuilder parameterRef = BeanDefinitionBuilder
+ // .genericBeanDefinition(ParameterRef.class);
+ // parameterRef.addPropertyReference("instantiationManager",
+ // "instantiationManager");
+ // parameterRef.addConstructorArgValue(paramName);
+ // bean.getBeanDefinition().getPropertyValues().addPropertyValue(
+ // propertyName, parameterRef.getBeanDefinition());
+ // return bean;
+ // }
+
+ @Override
+ protected void doParse(Element element, ParserContext parserContext,
+ BeanDefinitionBuilder builder) {
+ String paramName = element.getAttribute("name");
+
+ String instantationManagerRef = element
+ .getAttribute("instantiationManager");
+ if (!StringUtils.hasText(instantationManagerRef))
+ instantationManagerRef = "instantiationManager";
+ builder.addPropertyReference("instantiationManager",
+ instantationManagerRef);
+ builder.addConstructorArgValue(paramName);
+ }
+
+ @Override
+ protected Class<ParameterRef> getBeanClass(Element element) {
+ return ParameterRef.class;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.execution.xml;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.core.execution.DefaultExecutionSpec;
+import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
+import org.argeo.slc.core.execution.RefSpecAttribute;
+import org.argeo.slc.core.execution.RefValueChoice;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.support.ManagedMap;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+import org.springframework.util.xml.DomUtils;
+import org.w3c.dom.Element;
+
+/** Interprets the <flow:spec> tag */
+public class SpecBeanDefinitionParser extends
+ AbstractSingleBeanDefinitionParser {
+ private Log log = LogFactory.getLog(SpecBeanDefinitionParser.class);
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void doParse(Element element, ParserContext parserContext,
+ BeanDefinitionBuilder builder) {
+ builder.getBeanDefinition().setDescription(
+ DomUtils.getChildElementValueByTagName(element, "description"));
+
+ ManagedMap attributes = new ManagedMap();
+
+ // Primitives
+ for (Element child : (List<Element>) DomUtils
+ .getChildElementsByTagName(element, "primitive")) {
+ BeanDefinitionBuilder childBuilder = BeanDefinitionBuilder
+ .genericBeanDefinition(PrimitiveSpecAttribute.class);
+ addCommonProperties(child, parserContext, childBuilder);
+
+ String type = child.getAttribute("type");
+ if (StringUtils.hasText(type))
+ childBuilder.addPropertyValue("type", type);
+
+ putInAttributes(attributes, child,
+ childBuilder.getBeanDefinition(), "primitive");
+ }
+
+ // Refs
+ for (Element refAttrElem : (List<Element>) DomUtils
+ .getChildElementsByTagName(element, "ref")) {
+ BeanDefinitionBuilder refAttrBuilder = BeanDefinitionBuilder
+ .genericBeanDefinition(RefSpecAttribute.class);
+ addCommonProperties(refAttrElem, parserContext, refAttrBuilder);
+
+ String targetClassName = refAttrElem.getAttribute("targetClass");
+ if (StringUtils.hasText(targetClassName))
+ refAttrBuilder.addPropertyValue("targetClass", targetClassName);
+
+ // Choices
+ Element choicesElem = DomUtils.getChildElementByTagName(
+ refAttrElem, "choices");
+ if (choicesElem != null) {
+ List<Element> choices = DomUtils.getChildElementsByTagName(
+ choicesElem, "choice");
+ ManagedList choiceBeans = new ManagedList(choices.size());
+ for (Element choiceElem : choices) {
+ BeanDefinitionBuilder choiceBuilder = BeanDefinitionBuilder
+ .genericBeanDefinition(RefValueChoice.class);
+ choiceBuilder.addPropertyValue("name",
+ choiceElem.getAttribute("name"));
+ String desc = choiceElem.getAttribute("description");
+ if (StringUtils.hasText(desc))
+ choiceBuilder.addPropertyValue("description", desc);
+
+ choiceBeans.add(choiceBuilder.getBeanDefinition());
+ }
+ refAttrBuilder.addPropertyValue("choices", choiceBeans);
+ }
+
+ putInAttributes(attributes, refAttrElem,
+ refAttrBuilder.getBeanDefinition(), "ref");
+ }
+
+ builder.addPropertyValue("attributes", attributes);
+ }
+
+ protected void addCommonProperties(Element element,
+ ParserContext parserContext, BeanDefinitionBuilder specAttr) {
+ addBooleanProperty("isImmutable", specAttr, element);
+ addBooleanProperty("isConstant", specAttr, element);
+ addBooleanProperty("isHidden", specAttr, element);
+ addBooleanProperty("isParameter", specAttr, element);
+ addBooleanProperty("isFrozen", specAttr, element);
+
+ Object value = NamespaceUtils.parseValue(element, parserContext,
+ specAttr.getBeanDefinition(), "value");
+ if (value != null)
+ specAttr.addPropertyValue("value", value);
+
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void putInAttributes(ManagedMap attributes, Element child,
+ BeanDefinition beanDefinition, String nature) {
+ String name = child.getAttribute("name");
+ attributes.put(name, beanDefinition);
+ if (log.isTraceEnabled())
+ log.debug("Added " + nature + " attribute " + name);
+
+ }
+
+ private void addBooleanProperty(String name,
+ BeanDefinitionBuilder specAttr, Element element) {
+ String bool = element.getAttribute(name);
+ if (StringUtils.hasText(bool))
+ specAttr.addPropertyValue(name, Boolean.parseBoolean(bool));
+
+ }
+
+ @Override
+ protected Class<DefaultExecutionSpec> getBeanClass(Element element) {
+ return DefaultExecutionSpec.class;
+ }
+
+ protected boolean shouldGenerateIdAsFallback() {
+ return false;
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns:beans="http://www.springframework.org/schema/beans"
+ targetNamespace="http://www.argeo.org/schema/slc-flow"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+ <xsd:import namespace="http://www.springframework.org/schema/beans"
+ schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" />
+
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ SLC Flow Schema, version 0.12
+ Authors: Mathieu Baudier
+
+ This simplifies the definition of SLC flows and their integration with
+ regular Spring beans.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:element name="flow">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Adds an SLC execution flow, using the default implementation.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="beans:identifiedType">
+ <xsd:sequence>
+ <xsd:element ref="beans:description" minOccurs="0" />
+ <xsd:sequence>
+ <xsd:element name="arg" minOccurs="0" maxOccurs="unbounded"
+ type="flow:argType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Parameter for an execution flow which will override at instantiation the
+ value of the parameter already defined as default value or in a parent bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:sequence>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element ref="beans:bean" />
+ <xsd:element ref="beans:ref" />
+ <xsd:element ref="flow:flow" />
+ </xsd:choice>
+ <!--
+ <xsd:any namespace="##other" processContents="strict"
+ minOccurs="0" maxOccurs="unbounded" />
+ -->
+ </xsd:sequence>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Name of the flow (alternative to ID).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="class" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Another implementation of execution flow.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="path" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The hierarchical path under which to register this flow.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="spec" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference to the related specification bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="parent" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The parent bean definition (in Spring sense).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="abstract" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether this flow is abstract (in Spring sense).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="spec">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ SLC flow specifications, defining the parameters and variables
+ which can be used in related flows, along with their default values and
+ various constraints.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="beans:identifiedType">
+ <xsd:sequence>
+ <xsd:element ref="beans:description" minOccurs="0" />
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="primitive" type="flow:primitiveSpecAttributeType"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A primitive specification attribute, that is, a plain standard value
+ and not a reference to an object.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="ref" type="flow:refSpecAttributeType"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference specification attribute, that is, a reference to another object.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="specAttributeType">
+ <xsd:choice>
+ <xsd:element name="value" minOccurs="0" maxOccurs="1">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The default value of the attribute as an inner bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:choice minOccurs="1" maxOccurs="1">
+ <xsd:element ref="beans:bean" />
+ <xsd:element ref="beans:ref" />
+ <xsd:element ref="beans:list" />
+ <xsd:element ref="beans:set" />
+ <xsd:element ref="beans:map" />
+ <xsd:element ref="beans:props" />
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ <xsd:attribute name="name" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the attribute, under which in can then be referenced.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="value" use="optional" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The default value of the attribute.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="ref" use="optional" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The default value of the attribute as a reference to another bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isParameter" use="optional" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is a parameter, that is, it has to be set at
+ instantiation but can be modified afterwards for objects of scope execution.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isFrozen" use="optional" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is frozen, that is, it cannot be modified at runtime.
+ A frozen attribute has to be a parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isHidden" use="optional" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is hidden, that is, it should not be displayed in UIs.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="primitiveSpecAttributeType">
+ <xsd:complexContent>
+ <xsd:extension base="flow:specAttributeType">
+ <xsd:attribute name="type" default="string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The type of the primitive specification attribute.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="string" />
+ <xsd:enumeration value="integer" />
+ <xsd:enumeration value="long" />
+ <xsd:enumeration value="float" />
+ <xsd:enumeration value="double" />
+ <xsd:enumeration value="boolean" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="refSpecAttributeType">
+ <xsd:complexContent>
+ <xsd:extension base="flow:specAttributeType">
+ <xsd:choice>
+ <xsd:element name="choices" minOccurs="0" maxOccurs="1">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Possible values to chose from, if ommitted, all the beans in the
+ application context which implement the provided targetClass will
+ be considered.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element name="choice" minOccurs="0" maxOccurs="unbounded"
+ type="flow:refChoiceType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A choice for a reference specification attribute.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ <xsd:attribute name="targetClass" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The class that has to be implemented by the underlying object.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="refChoiceType">
+ <xsd:attribute name="name" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the related bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="description" use="optional" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A human readable description of this choice.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="argType">
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element ref="beans:bean" />
+ <xsd:element ref="beans:ref" />
+ <xsd:element ref="flow:param" />
+ <xsd:element ref="beans:list" />
+ <xsd:element ref="beans:set" />
+ <xsd:element ref="beans:map" />
+ <xsd:element ref="beans:props" />
+ </xsd:choice>
+ <xsd:attribute name="name" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the related parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="value" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The plain value of the related parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="ref" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The value of the related parameter as a reference to a bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:attribute name="as-flow" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ If decorating an executable bean, it will generate an implicit SLC
+ execution flow with the provided value as name.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <!--
+ <xsd:attribute name="var" type="xsd:boolean"> <xsd:annotation>
+ <xsd:documentation><![CDATA[ If true, the decorated bean is set to
+ scope execution and proxied. ]]></xsd:documentation> </xsd:annotation>
+ </xsd:attribute>
+ -->
+
+ <xsd:element name="variable">
+ <xsd:complexType>
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Marks a bean definition as being variable, i.e. a scoped proxy of scope execution
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="proxy-target-class" type="xsd:boolean"
+ default="true">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Are class-based (CGLIB) proxies to be created?
+ This is the default;
+ in order to switch to standard Java
+ interface-based proxies, turn this flag to
+ "false".
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="param">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ If within a property tag of a bean, it will set the value of this property
+ with a reference to a parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:attribute name="name" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the related parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="instantiationManager" type="xsd:string"
+ use="optional" default="instantiationManager">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference to the instantiation manager to use instead of the default one
+ (expert usage).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+</xsd:schema>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns:beans="http://www.springframework.org/schema/beans"
+ targetNamespace="http://www.argeo.org/schema/slc-flow"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+ <xsd:import namespace="http://www.springframework.org/schema/beans"
+ schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" />
+
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ SLC Flow Schema, version 1.2
+ Authors: Mathieu Baudier
+
+ This simplifies the definition of SLC flows and their integration with
+ regular Spring beans.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:element name="flow">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Adds an SLC execution flow, using the default implementation.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="beans:identifiedType">
+ <xsd:sequence>
+ <xsd:element ref="beans:description" minOccurs="0" />
+ <xsd:sequence>
+ <xsd:element name="arg" minOccurs="0" maxOccurs="unbounded"
+ type="flow:argType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Parameter for an execution flow which will override at instantiation the
+ value of the parameter already defined as default value or in a parent bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:sequence>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element ref="beans:bean" />
+ <xsd:element ref="beans:ref" />
+ <xsd:element ref="flow:flow" />
+ <xsd:element ref="flow:spec" />
+ </xsd:choice>
+ <!-- <xsd:any namespace="##other" processContents="strict" minOccurs="0"
+ maxOccurs="unbounded" /> -->
+ </xsd:sequence>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Name of the flow (alternative to ID).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="class" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Another implementation of execution flow.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="path" type="xsd:string">
+ <!-- DEPRECATED: not used anymore -->
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The hierarchical path under which to register this flow.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="spec" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference to the related specification bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="parent" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The parent bean definition (in Spring sense).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="abstract" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether this flow is abstract (in Spring sense).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="spec">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ SLC flow specifications, defining the parameters and variables
+ which can be used in related flows, along with their default values and
+ various constraints.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="beans:identifiedType">
+ <xsd:sequence>
+ <xsd:element ref="beans:description" minOccurs="0" />
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="primitive" type="flow:primitiveSpecAttributeType"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A primitive specification attribute, that is, a plain standard value
+ and not a reference to an object.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="ref" type="flow:refSpecAttributeType"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference specification attribute, that is, a reference to another object.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="specAttributeType">
+ <xsd:choice>
+ <xsd:element name="value" minOccurs="0" maxOccurs="1">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The default value of the attribute as an inner bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:choice minOccurs="1" maxOccurs="1">
+ <xsd:element ref="beans:bean" />
+ <xsd:element ref="beans:ref" />
+ <xsd:element ref="beans:list" />
+ <xsd:element ref="beans:set" />
+ <xsd:element ref="beans:map" />
+ <xsd:element ref="beans:props" />
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ <xsd:attribute name="name" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the attribute, under which in can then be referenced.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="value" use="optional" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The default value of the attribute.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="ref" use="optional" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The default value of the attribute as a reference to another bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isImmutable" use="optional" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is a parameter, that is, it has to be set at
+ instantiation but can be modified afterwards for objects of scope execution.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isParameter" use="optional" type="xsd:boolean"
+ default="false">
+ <!-- DEPRECATED: old name of isImmutable -->
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is a parameter, that is, it has to be set at
+ instantiation but can be modified afterwards for objects of scope execution.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isConstant" use="optional" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is frozen, that is, it cannot be modified at runtime.
+ A frozen attribute has to be a parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isFrozen" use="optional" type="xsd:boolean"
+ default="false">
+ <!-- DEPRECATED: old name of isConstant -->
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is frozen, that is, it cannot be modified at runtime.
+ A frozen attribute has to be a parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isHidden" use="optional" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is hidden, that is, it should not be displayed in UIs.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="primitiveSpecAttributeType">
+ <xsd:complexContent>
+ <xsd:extension base="flow:specAttributeType">
+ <xsd:attribute name="type" default="string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The type of the primitive specification attribute.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="string" />
+ <xsd:enumeration value="password" />
+ <xsd:enumeration value="integer" />
+ <xsd:enumeration value="long" />
+ <xsd:enumeration value="float" />
+ <xsd:enumeration value="double" />
+ <xsd:enumeration value="boolean" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="refSpecAttributeType">
+ <xsd:complexContent>
+ <xsd:extension base="flow:specAttributeType">
+ <xsd:choice>
+ <xsd:element name="choices" minOccurs="0" maxOccurs="1">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Possible values to chose from, if ommitted, all the beans in the
+ application context which implement the provided targetClass will
+ be considered.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element name="choice" minOccurs="0" maxOccurs="unbounded"
+ type="flow:refChoiceType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A choice for a reference specification attribute.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ <xsd:attribute name="targetClass" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The class that has to be implemented by the underlying object.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="refChoiceType">
+ <xsd:attribute name="name" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the related bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="description" use="optional" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A human readable description of this choice.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="argType">
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element ref="beans:bean" />
+ <xsd:element ref="beans:ref" />
+ <xsd:element ref="flow:param" />
+ <xsd:element ref="beans:list" />
+ <xsd:element ref="beans:set" />
+ <xsd:element ref="beans:map" />
+ <xsd:element ref="beans:props" />
+ </xsd:choice>
+ <xsd:attribute name="name" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the related parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="value" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The plain value of the related parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="ref" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The value of the related parameter as a reference to a bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:attribute name="as-flow" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ If decorating an executable bean, it will generate an implicit SLC
+ execution flow with the provided value as name.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <!-- <xsd:attribute name="var" type="xsd:boolean"> <xsd:annotation> <xsd:documentation><![CDATA[
+ If true, the decorated bean is set to scope execution and proxied. ]]></xsd:documentation>
+ </xsd:annotation> </xsd:attribute> -->
+
+ <xsd:element name="variable">
+ <xsd:complexType>
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Marks a bean definition as being variable, i.e. a scoped proxy of scope execution
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="proxy-target-class" type="xsd:boolean"
+ default="true">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Are class-based (CGLIB) proxies to be created?
+ This is the default;
+ in order to switch to standard Java
+ interface-based proxies, turn this flag to
+ "false".
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="param">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ If within a property tag of a bean, it will set the value of this property
+ with a reference to a parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:attribute name="name" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the related parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="instantiationManager" type="xsd:string"
+ use="optional" default="instantiationManager">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference to the instantiation manager to use instead of the default one
+ (expert usage).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+</xsd:schema>
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.test.TestData;\r
+\r
+public class BasicTestData implements TestData {\r
+ private Object expected;\r
+ private Object reached;\r
+\r
+ public Object getExpected() {\r
+ return expected;\r
+ }\r
+\r
+ public void setExpected(Object expected) {\r
+ this.expected = expected;\r
+ }\r
+\r
+ public Object getReached() {\r
+ return reached;\r
+ }\r
+\r
+ public void setReached(Object reached) {\r
+ this.reached = reached;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.core.test.context.ContextUtils;\r
+import org.argeo.slc.test.IncompatibleTestDataException;\r
+import org.argeo.slc.test.TestData;\r
+import org.argeo.slc.test.TestDefinition;\r
+import org.argeo.slc.test.TestResult;\r
+import org.argeo.slc.test.TestRun;\r
+import org.argeo.slc.test.TestStatus;\r
+import org.argeo.slc.test.context.ContextAware;\r
+\r
+/** Understands basic test data and context aware test data. */\r
+public class BasicTestDefinition implements TestDefinition {\r
+\r
+ public void execute(TestRun testRun) {\r
+ if (testRun.<TestData> getTestData() instanceof BasicTestData) {\r
+ BasicTestData testData = testRun.getTestData();\r
+ TestResult result = testRun.getTestResult();\r
+\r
+ if (result == null)\r
+ throw new SlcException("No test result defined.");\r
+\r
+ try {\r
+ if (testData.getExpected().equals(testData.getReached())) {\r
+ result.addResultPart(new SimpleResultPart(\r
+ TestStatus.PASSED, "Reached and expected equals"));\r
+ } else {\r
+ result.addResultPart(new SimpleResultPart(\r
+ TestStatus.FAILED, "Expected "\r
+ + testData.getExpected() + " but reached "\r
+ + testData.getReached()));\r
+ }\r
+ } catch (Exception e) {\r
+ result.addResultPart(new SimpleResultPart(TestStatus.ERROR,\r
+ "Could not compare", e));\r
+ }\r
+ } else if (testRun.<TestData> getTestData() instanceof ContextAware) {\r
+ TestData testData = testRun.getTestData();\r
+ ContextUtils.compareReachedExpected((ContextAware) testData,\r
+ testRun.getTestResult());\r
+ } else {\r
+ throw new IncompatibleTestDataException(testRun);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import java.io.Serializable;\r
+\r
+import org.argeo.slc.test.TestResultPart;\r
+import org.argeo.slc.test.TestRun;\r
+import org.argeo.slc.test.TestRunAware;\r
+import org.argeo.slc.test.TestStatus;\r
+\r
+/**\r
+ * <p>\r
+ * Basic implementation of a result part, implementing the standard three status\r
+ * approach for test results.\r
+ * </p>\r
+ * \r
+ * @see TestStatus\r
+ */\r
+public class SimpleResultPart implements TestResultPart, TestStatus,\r
+ TestRunAware, Serializable {\r
+ private static final long serialVersionUID = 6669675957685071901L;\r
+\r
+ private Long tid;\r
+\r
+ private String testRunUuid;\r
+\r
+ /** The status. Default to ERROR since it should always be explicitely set. */\r
+ private Integer status = ERROR;\r
+ private String message;\r
+ private String exceptionMessage;\r
+\r
+ public SimpleResultPart() {\r
+ }\r
+\r
+ public SimpleResultPart(Integer status, String message) {\r
+ this(status, message, null);\r
+ }\r
+\r
+ public SimpleResultPart(Integer status, String message, Exception exception) {\r
+ this.status = status;\r
+ this.message = message;\r
+ setException(exception);\r
+ }\r
+\r
+ public String getMessage() {\r
+ return message;\r
+ }\r
+\r
+ public void setMessage(String message) {\r
+ this.message = message;\r
+ }\r
+\r
+ public void setStatus(Integer status) {\r
+ this.status = status;\r
+ }\r
+\r
+ public Integer getStatus() {\r
+ return status;\r
+ }\r
+\r
+ public String getExceptionMessage() {\r
+ return exceptionMessage;\r
+ }\r
+\r
+ public void setException(Exception exception) {\r
+ if (exception == null)\r
+ return;\r
+\r
+ StringBuffer buf = new StringBuffer("");\r
+ buf.append(exception.toString());\r
+ buf.append('\n');\r
+ for (StackTraceElement elem : exception.getStackTrace()) {\r
+ buf.append('\t').append(elem.toString()).append('\n');\r
+ }\r
+\r
+ if (exception.getCause() != null)\r
+ addRootCause(buf, exception.getCause());\r
+\r
+ this.exceptionMessage = buf.toString();\r
+ }\r
+\r
+ protected void addRootCause(StringBuffer buf, Throwable cause) {\r
+ if (cause == null)\r
+ return;\r
+\r
+ buf.append("Caused by: " + cause.getMessage());\r
+ for (StackTraceElement elem : cause.getStackTrace()) {\r
+ buf.append('\t').append(elem.toString()).append('\n');\r
+ }\r
+\r
+ if (cause.getCause() != null) {\r
+ addRootCause(buf, cause.getCause());\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ StringBuffer buf = new StringBuffer("");\r
+ buf.append(SlcTestUtils.statusToString(status));\r
+ if (status == PASSED || status == FAILED) {\r
+ buf.append(' ');\r
+ } else if (status == ERROR) {\r
+ buf.append(" ");\r
+ }\r
+ buf.append(message);\r
+ return buf.toString();\r
+ }\r
+\r
+ /** @deprecated */\r
+ Long getTid() {\r
+ return tid;\r
+ }\r
+\r
+ /** @deprecated */\r
+ void setTid(Long tid) {\r
+ this.tid = tid;\r
+ }\r
+\r
+ public String getTestRunUuid() {\r
+ return testRunUuid;\r
+ }\r
+\r
+ /** For ORM */\r
+ public void setTestRunUuid(String testRunUuid) {\r
+ this.testRunUuid = testRunUuid;\r
+ }\r
+\r
+ public void notifyTestRun(TestRun testRun) {\r
+ testRunUuid = testRun.getUuid();\r
+ }\r
+\r
+ public void setExceptionMessage(String exceptionMessage) {\r
+ this.exceptionMessage = exceptionMessage;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+import java.util.UUID;\r
+import java.util.Vector;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.test.TestResult;\r
+import org.argeo.slc.test.TestResultPart;\r
+import org.argeo.slc.test.TestRun;\r
+\r
+/**\r
+ * Basic implementation of a test result containing only a list of result parts.\r
+ */\r
+public class SimpleTestResult implements TestResult {\r
+ private static Log log = LogFactory.getLog(SimpleTestResult.class);\r
+\r
+ private String uuid;\r
+ private String currentTestRunUuid;\r
+\r
+ private Boolean throwError = true;\r
+\r
+ private Date closeDate;\r
+ private List<TestResultPart> parts = new Vector<TestResultPart>();\r
+\r
+ private Map<String, String> attributes = new TreeMap<String, String>();\r
+\r
+ public void addResultPart(TestResultPart part) {\r
+ if (throwError && part.getStatus() == ERROR) {\r
+ throw new SlcException(\r
+ "There was an error in the underlying test: "\r
+ + part.getExceptionMessage());\r
+ }\r
+ parts.add(part);\r
+ if (log.isDebugEnabled())\r
+ log.debug(part);\r
+ }\r
+\r
+ public void close() {\r
+ parts.clear();\r
+ closeDate = new Date();\r
+ }\r
+\r
+ public List<TestResultPart> getParts() {\r
+ return parts;\r
+ }\r
+\r
+ public Date getCloseDate() {\r
+ return closeDate;\r
+ }\r
+\r
+ public void setThrowError(Boolean throwError) {\r
+ this.throwError = throwError;\r
+ }\r
+\r
+ public void notifyTestRun(TestRun testRun) {\r
+ currentTestRunUuid = testRun.getUuid();\r
+ }\r
+\r
+ public String getUuid() {\r
+ if (uuid == null) {\r
+ uuid = UUID.randomUUID().toString();\r
+ }\r
+ return uuid;\r
+ }\r
+\r
+ public void setUuid(String uuid) {\r
+ this.uuid = uuid;\r
+ }\r
+\r
+ public String getCurrentTestRunUuid() {\r
+ return currentTestRunUuid;\r
+ }\r
+\r
+ public Map<String, String> getAttributes() {\r
+ return attributes;\r
+ }\r
+\r
+ public void setAttributes(Map<String, String> attributes) {\r
+ this.attributes = attributes;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import java.util.UUID;\r
+\r
+import org.argeo.slc.deploy.DeployedSystem;\r
+import org.argeo.slc.test.ExecutableTestRun;\r
+import org.argeo.slc.test.TestData;\r
+import org.argeo.slc.test.TestDefinition;\r
+import org.argeo.slc.test.TestResult;\r
+import org.argeo.slc.test.WritableTestRun;\r
+\r
+/**\r
+ * A basic bean implementation of a <code>WritableTestRun</code>, holding\r
+ * references to the various parts of a test run.\r
+ */\r
+public class SimpleTestRun implements WritableTestRun, ExecutableTestRun {\r
+ private String uuid;\r
+\r
+ // private String slcExecutionUuid;\r
+ // private String slcExecutionStepUuid;\r
+\r
+ private DeployedSystem deployedSystem;\r
+ private TestData testData;\r
+ private TestDefinition testDefinition;\r
+ private TestResult testResult;\r
+\r
+ /** Executes the underlying test definition. */\r
+ public void run() {\r
+ uuid = UUID.randomUUID().toString();\r
+ if (testResult != null)\r
+ testResult.notifyTestRun(this);\r
+\r
+ testDefinition.execute(this);\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public <T extends DeployedSystem> T getDeployedSystem() {\r
+ return (T) deployedSystem;\r
+ }\r
+\r
+ public void setDeployedSystem(DeployedSystem deployedSystem) {\r
+ this.deployedSystem = deployedSystem;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public <T extends TestData> T getTestData() {\r
+ return (T) testData;\r
+ }\r
+\r
+ public void setTestData(TestData testData) {\r
+ this.testData = testData;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public <T extends TestDefinition> T getTestDefinition() {\r
+ return (T) testDefinition;\r
+ }\r
+\r
+ public void setTestDefinition(TestDefinition testDefinition) {\r
+ this.testDefinition = testDefinition;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public <T extends TestResult> T getTestResult() {\r
+ return (T) testResult;\r
+ }\r
+\r
+ public void setTestResult(TestResult testResult) {\r
+ this.testResult = testResult;\r
+ }\r
+\r
+ public String getUuid() {\r
+ return uuid;\r
+ }\r
+\r
+ public void setUuid(String uuid) {\r
+ this.uuid = uuid;\r
+ }\r
+\r
+ // public String getSlcExecutionUuid() {\r
+ // return slcExecutionUuid;\r
+ // }\r
+ //\r
+ // public void setSlcExecutionUuid(String slcExecutionUuid) {\r
+ // this.slcExecutionUuid = slcExecutionUuid;\r
+ // }\r
+ //\r
+ // public String getSlcExecutionStepUuid() {\r
+ // return slcExecutionStepUuid;\r
+ // }\r
+ //\r
+ // public void setSlcExecutionStepUuid(String slcExecutionStepUuid) {\r
+ // this.slcExecutionStepUuid = slcExecutionStepUuid;\r
+ // }\r
+}\r
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.core.test;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.test.TestStatus;
+
+public abstract class SlcTestUtils {
+ public static String statusToString(Integer status) {
+ if (status.equals(TestStatus.PASSED)) {
+ return TestStatus.STATUSSTR_PASSED;
+ } else if (status.equals(TestStatus.FAILED)) {
+ return TestStatus.STATUSSTR_FAILED;
+ } else if (status.equals(TestStatus.ERROR)) {
+ return TestStatus.STATUSSTR_ERROR;
+ } else {
+ throw new SlcException("Unrecognized status " + status);
+ }
+ }
+
+ public static Integer stringToStatus(String statusStr) {
+ if (statusStr.equals(TestStatus.STATUSSTR_PASSED)) {
+ return TestStatus.PASSED;
+ } else if (statusStr.equals(TestStatus.STATUSSTR_FAILED)) {
+ return TestStatus.FAILED;
+ } else if (statusStr.equals(TestStatus.STATUSSTR_ERROR)) {
+ return TestStatus.ERROR;
+ } else {
+ throw new SlcException("Unrecognized status string " + statusStr);
+ }
+ }
+
+ private SlcTestUtils() {
+
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.UnsupportedException;\r
+import org.argeo.slc.test.TestData;\r
+import org.argeo.slc.test.TestDataProvider;\r
+\r
+/** Utilities for dealing with test datas. */\r
+public class TestDataUtils {\r
+ /** Extracts the test data from the given provider. */\r
+ public static <T extends TestData> T getFromProvider(Object obj,\r
+ Class<T> clss, String key) {\r
+ if (obj instanceof TestDataProvider) {\r
+ TestDataProvider testDataProvider = (TestDataProvider) obj;\r
+ return testDataProvider.getTestData(clss, key);\r
+ } else {\r
+ throw new UnsupportedException("test data provider", obj);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Extracts the test data from the given provider using <code>null</code>\r
+ * as key.\r
+ */\r
+ public static <T extends TestData> T getFromProvider(Object obj,\r
+ Class<T> clss) {\r
+ return getFromProvider(obj, clss, null);\r
+ }\r
+\r
+ /**\r
+ * Returns it self after making the proper checks. Used for test data being\r
+ * their own data providers.\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ public static <T extends TestData> T getItSelf(Class<T> clss,\r
+ TestData testDataObject) {\r
+ if (clss.isAssignableFrom(testDataObject.getClass())) {\r
+ return (T) testDataObject;\r
+ } else {\r
+ throw new UnsupportedException("test data", testDataObject);\r
+ }\r
+\r
+ }\r
+\r
+ /** Makes sure this is an utility class. */\r
+ private TestDataUtils() {\r
+\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.core.test.SimpleResultPart;\r
+import org.argeo.slc.test.TestResult;\r
+import org.argeo.slc.test.TestStatus;\r
+import org.argeo.slc.test.context.ContextAware;\r
+import org.argeo.slc.test.context.ParentContextAware;\r
+\r
+/** Utilities for comparing and synchronising contexts. */\r
+public class ContextUtils {\r
+ private final static Log log = LogFactory.getLog(ContextUtils.class);\r
+\r
+ public static void compareReachedExpected(ContextAware contextAware,\r
+ TestResult testResult) {\r
+ for (String key : contextAware.getExpectedValues().keySet()) {\r
+\r
+ // Compare expected values with reached ones\r
+ Object expectedValue = contextAware.getExpectedValues().get(key);\r
+\r
+ if (expectedValue.toString().equals(\r
+ contextAware.getContextSkipFlag())) {\r
+ if (log.isDebugEnabled())\r
+ log.debug("Skipped check for key '" + key + "'");\r
+ continue;\r
+ }\r
+\r
+ if (contextAware.getValues().containsKey(key)) {\r
+ Object reachedValue = contextAware.getValues().get(key);\r
+\r
+ if (expectedValue.equals(contextAware.getContextAnyFlag())) {\r
+ testResult.addResultPart(new SimpleResultPart(\r
+ TestStatus.PASSED, "Expected any value for key '"\r
+ + key + "'"));\r
+ } else if (expectedValue.equals(reachedValue)) {\r
+ testResult.addResultPart(new SimpleResultPart(\r
+ TestStatus.PASSED, "Values matched for key '" + key\r
+ + "'"));\r
+ } else {\r
+ testResult.addResultPart(new SimpleResultPart(\r
+ TestStatus.FAILED, "Mismatch for key '" + key\r
+ + "': expected '" + expectedValue\r
+ + "' but reached '" + reachedValue + "'"));\r
+ }\r
+ } else {\r
+ testResult.addResultPart(new SimpleResultPart(\r
+ TestStatus.FAILED, "No value reached for key '" + key\r
+ + "'"));\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Makes sure that all children and sub-children of parent share the same\r
+ * maps for values and expected values.\r
+ */\r
+ public static void synchronize(ParentContextAware parent) {\r
+ Map<String, Object> expectedValuesCommon = new TreeMap<String, Object>(\r
+ parent.getExpectedValues());\r
+ synchronize(parent, expectedValuesCommon);\r
+ if (log.isDebugEnabled())\r
+ log.debug("Synchronized context " + parent);\r
+\r
+ }\r
+\r
+ private static void synchronize(ParentContextAware parent,\r
+ Map<String, Object> expectedValuesCommon) {\r
+ for (ContextAware child : parent.getChildContexts()) {\r
+ // Values\r
+ putNotContained(parent.getValues(), child.getValues());\r
+ child.setValues(parent.getValues());\r
+\r
+ // Expected Values\r
+ // Expected values reference is not overridden: each child has its\r
+ // own expected values map.\r
+ overrideContained(expectedValuesCommon, child.getExpectedValues());\r
+\r
+ // Creates a new Map in order not to disturb other context using the\r
+ // same keys\r
+ Map<String, Object> expectedValuesCommonChild = new TreeMap<String, Object>(\r
+ expectedValuesCommon);\r
+ putNotContained(expectedValuesCommonChild,\r
+ child.getExpectedValues());\r
+\r
+ if (child instanceof ParentContextAware) {\r
+ // Recursive sync\r
+ synchronize((ParentContextAware) child,\r
+ expectedValuesCommonChild);\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Put into common map the values from child map which are not already\r
+ * defined in common map.\r
+ */\r
+ public static void putNotContained(Map<String, Object> commonMap,\r
+ Map<String, Object> childMap) {\r
+ for (String key : childMap.keySet()) {\r
+ if (!commonMap.containsKey(key)) {\r
+ commonMap.put(key, childMap.get(key));\r
+ }\r
+ }\r
+ }\r
+\r
+ /** Overrides child map values with the values already set in common map */\r
+ public static void overrideContained(Map<String, Object> commonMap,\r
+ Map<String, Object> childMap) {\r
+ for (String key : childMap.keySet()) {\r
+ if (commonMap.containsKey(key)) {\r
+ childMap.put(key, commonMap.get(key));\r
+ }\r
+ }\r
+ }\r
+\r
+ /** Makes sure this cannot be instantiated. */\r
+ private ContextUtils() {\r
+\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import org.argeo.slc.core.test.TestDataUtils;\r
+import org.argeo.slc.test.TestData;\r
+import org.argeo.slc.test.TestDataProvider;\r
+\r
+public class DefaultContextTestData extends SimpleContextAware implements\r
+ TestData, TestDataProvider {\r
+\r
+ public <T extends TestData> T getTestData(Class<T> clss, String key) {\r
+ return TestDataUtils.getItSelf(clss, this);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+\r
+import org.springframework.beans.factory.InitializingBean;\r
+\r
+import org.argeo.slc.SlcException;\r
+import org.argeo.slc.test.context.ContextAware;\r
+import org.argeo.slc.test.context.ParentContextAware;\r
+\r
+public class SimpleContextAware implements ContextAware, InitializingBean {\r
+ private ParentContextAware parentContext;\r
+\r
+ private Map<String, Object> values = new TreeMap<String, Object>();\r
+ private Map<String, Object> expectedValues = new TreeMap<String, Object>();\r
+\r
+ private String contextSkipFlag = DEFAULT_SKIP_FLAG;\r
+ private String contextAnyFlag = DEFAULT_ANY_FLAG;\r
+\r
+ public Map<String, Object> getValues() {\r
+ return values;\r
+ }\r
+\r
+ public void setValues(Map<String, Object> values) {\r
+ this.values = values;\r
+ }\r
+\r
+ public Map<String, Object> getExpectedValues() {\r
+ return expectedValues;\r
+ }\r
+\r
+ public void setExpectedValues(Map<String, Object> expectedValues) {\r
+ this.expectedValues = expectedValues;\r
+ }\r
+\r
+ /** Used to add this context as a child by setting a property. */\r
+ public void setParentContext(ParentContextAware parentContextAware) {\r
+ if (parentContext != null)\r
+ throw new SlcException("Parent context already set");\r
+ this.parentContext = parentContextAware;\r
+ this.parentContext.addChildContext(this);\r
+ }\r
+\r
+ protected ParentContextAware getParentContext() {\r
+ return parentContext;\r
+ }\r
+\r
+ public void afterPropertiesSet() throws Exception {\r
+ if (parentContext != null) {\r
+ ContextUtils.synchronize(parentContext);\r
+ }\r
+ }\r
+\r
+ public String getContextSkipFlag() {\r
+ return contextSkipFlag;\r
+ }\r
+\r
+ public void setContextSkipFlag(String contextSkipFlag) {\r
+ this.contextSkipFlag = contextSkipFlag;\r
+ }\r
+\r
+ public String getContextAnyFlag() {\r
+ return contextAnyFlag;\r
+ }\r
+\r
+ public void setContextAnyFlag(String contextAnyFlag) {\r
+ this.contextAnyFlag = contextAnyFlag;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Collection;\r
+import java.util.List;\r
+import java.util.Vector;\r
+\r
+import org.argeo.slc.test.context.ContextAware;\r
+import org.argeo.slc.test.context.ParentContextAware;\r
+import org.springframework.beans.factory.InitializingBean;\r
+\r
+public class SimpleParentContextAware extends SimpleContextAware implements\r
+ ParentContextAware, InitializingBean {\r
+ private List<ContextAware> children = new Vector<ContextAware>();\r
+\r
+ public Collection<ContextAware> getChildContexts() {\r
+ return children;\r
+ }\r
+\r
+ public void addChildContext(ContextAware contextAware) {\r
+ children.add(contextAware);\r
+ }\r
+\r
+ @Override\r
+ public void afterPropertiesSet() throws Exception {\r
+ if (getParentContext() != null) {\r
+ // If has a parent, sync it.\r
+ super.afterPropertiesSet();\r
+ } else {\r
+ if (children.size() > 0) {\r
+ // No need to synchronize if no children\r
+ ContextUtils.synchronize(this);\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+Context variables to be passed between parts of tests.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+SLC Test: test of software systems.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2007-2012 Argeo GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
+ default-lazy-init="true">
+
+ <bean name="slcDefault.test.testRun"
+ class="org.argeo.slc.core.test.SimpleTestRun"
+ scope="prototype">
+ </bean>
+
+ <bean name="slcDefault.test.uuid" class="java.util.UUID"
+ factory-method="randomUUID" scope="prototype">
+ </bean>
+
+ <bean id="slcDefault.test.basicSimpleTestResult"
+ class="org.argeo.slc.core.test.SimpleTestResult"
+ abstract="true">
+ <property name="uuid">
+ <bean factory-bean="slcDefault.test.uuid"
+ factory-method="toString">
+ </bean>
+ </property>
+ </bean>
+
+</beans>
\ No newline at end of file
</properties>
<modules>
<module>org.argeo.slc.api</module>
+ <module>org.argeo.slc.core</module>
<!-- <module>runtime</module> -->
<!-- <module>modules</module> -->
+++ /dev/null
-http\://www.argeo.org/schema/slc-flow=org.argeo.slc.core.execution.xml.FlowNamespaceHandler
\ No newline at end of file
+++ /dev/null
-http\://www.argeo.org/schema/slc-flow.xsd=org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd
-http\://www.argeo.org/schema/slc-flow-1.2.xsd=org/argeo/slc/core/execution/xml/slc-flow-1.2.xsd
-http\://www.argeo.org/schema/slc-flow-0.12.xsd=org/argeo/slc/core/execution/xml/slc-flow-0.12.xsd
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-public interface Attachment {
- public String getUuid();
-
- public void setUuid(String uuid);
-
- public String getName();
-
- public String getContentType();
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-import org.springframework.core.io.Resource;
-
-public interface AttachmentUploader {
- public void upload(Attachment attachment, Resource resource);
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-public interface AttachmentsEnabled {
- public void addAttachment(Attachment attachment);
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-
-public interface AttachmentsStorage {
- public void retrieveAttachment(Attachment attachment,
- OutputStream outputStream);
-
- /** Does NOT close the provided input stream. */
- public void storeAttachment(Attachment attachment, InputStream inputStream);
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.core.io.Resource;
-
-public class FileAttachmentsStorage implements AttachmentsStorage,
- AttachmentUploader, InitializingBean {
- private final static Log log = LogFactory
- .getLog(FileAttachmentsStorage.class);
-
- private File attachmentsDirectory;
-
- private String attachmentsTocFileName = "attachmentsToc.csv";
-
- private DateFormat dateFormatDay = new SimpleDateFormat("yyyy-MM-dd");
- private DateFormat dateFormatTime = new SimpleDateFormat("HH:mm:ss");
-
- public void afterPropertiesSet() {
- if (attachmentsDirectory == null) {
-
- String osgiInstanceArea = System.getProperty("osgi.instance.area");
- if (osgiInstanceArea != null) {
- if (osgiInstanceArea.startsWith("file:"))
- osgiInstanceArea = osgiInstanceArea.substring("file:"
- .length());
- attachmentsDirectory = new File(osgiInstanceArea
- + File.separator + "slcAttachments");
- }
-
- if (attachmentsDirectory == null) {
- String tempDir = System.getProperty("java.io.tmpdir");
- attachmentsDirectory = new File(tempDir + File.separator
- + "slcAttachments");
- }
- }
- if (!attachmentsDirectory.exists())
- attachmentsDirectory.mkdirs();
- if (log.isDebugEnabled())
- log.debug("File attachment storage initialized in directory "
- + attachmentsDirectory);
- }
-
- public void retrieveAttachment(Attachment attachment,
- OutputStream outputStream) {
- File file = getFile(attachment);
- InputStream in = null;
- try {
- byte[] buffer = new byte[1024 * 1024];
- in = new FileInputStream(file);
- int read = -1;
- while ((read = in.read(buffer)) >= 0) {
- outputStream.write(buffer, 0, read);
- }
- if (log.isTraceEnabled())
- log.trace("Read " + attachment + " from " + file);
- } catch (IOException e) {
- throw new SlcException("Cannot write attachment " + attachment
- + " to " + file, e);
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- public void storeAttachment(Attachment attachment, InputStream inputStream) {
- File file = getFile(attachment);
- FileOutputStream out = null;
- try {
- byte[] buffer = new byte[1024 * 1024];
- out = new FileOutputStream(file);
- int read = -1;
- while ((read = inputStream.read(buffer)) >= 0) {
- out.write(buffer, 0, read);
- }
- if (log.isTraceEnabled())
- log.trace("Wrote " + attachment + " to " + file);
- updateAttachmentToc(attachment, file);
- } catch (IOException e) {
- throw new SlcException("Cannot write attachment " + attachment
- + " to " + file, e);
- } finally {
- IOUtils.closeQuietly(out);
- }
-
- }
-
- public void upload(Attachment attachment, Resource resource) {
- try {
- storeAttachment(attachment, resource.getInputStream());
- } catch (IOException e) {
- throw new SlcException("Cannot upload attachment " + attachment, e);
- }
- }
-
- /** For monitoring purposes only */
- protected void updateAttachmentToc(Attachment attachment, File file) {
- Date date = new Date(file.lastModified());
- FileWriter writer = null;
- try {
- writer = new FileWriter(attachmentsDirectory + File.separator
- + attachmentsTocFileName, true);
- writer.append(dateFormatDay.format(date));
- writer.append(',');
- writer.append(dateFormatTime.format(date));
- writer.append(',');
- writer.append(attachment.getUuid());
- writer.append(',');
- writer.append(attachment.getName());
- writer.append(',');
- writer.append(attachment.getContentType());
- writer.append(',');
- writer.append(Long.toString(file.length()));
- writer.append(',');
- writer.append(file.getCanonicalPath());
- writer.append('\n');
- } catch (IOException e) {
- log.warn("Could not update attachments TOC for " + attachment
- + " and file " + file, e);
- } finally {
- IOUtils.closeQuietly(writer);
- }
-
- }
-
- protected File getFile(Attachment attachment) {
- File file = new File(attachmentsDirectory + File.separator
- + attachment.getUuid());
- return file;
- }
-
- public void setAttachmentsDirectory(File attachmentsDirectory) {
- this.attachmentsDirectory = attachmentsDirectory;
- }
-
- public void setAttachmentsTocFileName(String attachmentsTocFileName) {
- this.attachmentsTocFileName = attachmentsTocFileName;
- }
-
- public void setDateFormatDay(DateFormat dateFormatDay) {
- this.dateFormatDay = dateFormatDay;
- }
-
- public void setDateFormatTime(DateFormat dateFormatTime) {
- this.dateFormatTime = dateFormatTime;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.attachment;
-
-import java.io.Serializable;
-import java.util.UUID;
-
-public class SimpleAttachment implements Attachment, Serializable {
- private static final long serialVersionUID = 6615155908800610606L;
- private String uuid = UUID.randomUUID().toString();
- private String name;
- private String contentType = "";
-
- public SimpleAttachment() {
- }
-
- public SimpleAttachment(String uuid, String name, String contentType) {
- super();
- this.uuid = uuid;
- this.name = name;
- this.contentType = contentType;
- }
-
- public String getUuid() {
- return uuid;
- }
-
- public void setUuid(String uuid) {
- this.uuid = uuid;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getContentType() {
- return contentType;
- }
-
- public void setContentType(String contentType) {
- this.contentType = contentType;
- }
-
- public String toString() {
- return "Attachment #" + uuid + "(" + name + ", " + contentType + ")";
- }
-
- public boolean equals(Object obj) {
- if (obj instanceof Attachment) {
- Attachment attachment = (Attachment) obj;
- if (uuid != null && attachment.getUuid() != null)
- return uuid.equals(attachment.getUuid());
-
- if (name != null && attachment.getName() != null)
- return name.equals(attachment.getName());
-
- return hashCode() == attachment.hashCode();
- }
- return false;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.build;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.argeo.slc.SlcException;
-import org.argeo.slc.StreamReadable;
-import org.argeo.slc.build.Distribution;
-import org.springframework.core.io.Resource;
-
-/** A software distribution archive accessible via a {@link Resource}. */
-public class ResourceDistribution implements Distribution, StreamReadable {
- private Resource resource;
-
- public ResourceDistribution() {
- }
-
- public ResourceDistribution(Resource location) {
- this.resource = location;
- }
-
- public String getDistributionId() {
- return resource.toString();
- }
-
- public Resource getResource() {
- return resource;
- }
-
- public void setResource(Resource resource) {
- this.resource = resource;
- }
-
- public InputStream getInputStream() {
- try {
- return resource.getInputStream();
- } catch (IOException e) {
- throw new SlcException("Cannot get input stream", e);
- }
- }
-
- @Override
- public String toString() {
- return resource.toString();
- }
-
-}
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.build;\r
-\r
-import java.util.StringTokenizer;\r
-\r
-/**\r
- * <p>\r
- * An implementation of the distribution id using the standard\r
- * Major.Minor.Release notation. And additional arbitrary string can also be\r
- * added.\r
- * </p>\r
- * \r
- * <p>\r
- * <b>Examples:</b><br>\r
- * 0.2.6<br>\r
- * 2.4.12.RC1\r
- * </p>\r
- */\r
-public class VersionDistributionId {\r
-\r
- private Integer major;\r
- private Integer minor;\r
- private Integer release;\r
- private String additional;\r
-\r
- /** Parse the provided string in order to set the various components. */\r
- public void setVersionString(String str) {\r
- StringTokenizer st = new StringTokenizer(str, ".");\r
- if (st.hasMoreTokens())\r
- major = Integer.parseInt(st.nextToken());\r
- if (st.hasMoreTokens())\r
- minor = Integer.parseInt(st.nextToken());\r
- if (st.hasMoreTokens())\r
- release = Integer.parseInt(st.nextToken());\r
- if (st.hasMoreTokens())\r
- additional = st.nextToken();\r
- }\r
-\r
- public Integer getMajor() {\r
- return major;\r
- }\r
-\r
- public void setMajor(Integer major) {\r
- this.major = major;\r
- }\r
-\r
- public Integer getMinor() {\r
- return minor;\r
- }\r
-\r
- public void setMinor(Integer minor) {\r
- this.minor = minor;\r
- }\r
-\r
- public Integer getRelease() {\r
- return release;\r
- }\r
-\r
- public void setRelease(Integer release) {\r
- this.release = release;\r
- }\r
-\r
- public String getAdditional() {\r
- return additional;\r
- }\r
-\r
- public void setAdditional(String additional) {\r
- this.additional = additional;\r
- }\r
-\r
- @Override\r
- public boolean equals(Object obj) {\r
- // TODO Auto-generated method stub\r
- return super.equals(obj);\r
- }\r
-\r
- @Override\r
- public String toString() {\r
- return major + "." + minor + "." + release\r
- + (additional != null ? "." + additional : "");\r
- }\r
-\r
-}\r
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.build;
-
-import org.argeo.slc.NameVersion;
-import org.springframework.core.io.Resource;
-
-/**
- * The distribution of a software package (jar, zip, RPM, etc.) which is
- * versioned. The archive itself is accessible via a {@link Resource}.
- */
-public class VersionedResourceDistribution extends ResourceDistribution
- implements NameVersion {
- private String name;
- private String version;
-
- public VersionedResourceDistribution() {
- super();
- }
-
- public VersionedResourceDistribution(NameVersion nameVersion,
- Resource resource) {
- this(nameVersion.getName(), nameVersion.getVersion(), resource);
- }
-
- public VersionedResourceDistribution(String name, String version,
- Resource resource) {
- super(resource);
- this.name = name;
- this.version = version;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getVersion() {
- return version;
- }
-
- public void setVersion(String version) {
- this.version = version;
- }
-
-}
+++ /dev/null
-<html>\r
-<head></head>\r
-<body>\r
-SLC Build: building of software systems.\r
-</body>\r
-</html>
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.context.ResourceLoaderAware;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.ResourceLoader;
-import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
-import org.springframework.core.io.support.ResourcePatternResolver;
-import org.springframework.util.AntPathMatcher;
-import org.springframework.util.PathMatcher;
-
-public class DefaultResourceSet implements ResourceLoaderAware,
- InitializingBean, ResourceSet {
- private final static Log log = LogFactory.getLog(DefaultResourceSet.class);
- public final static String DEFAULT_EXCLUDES = "**/.svn/**";
-
- private String base;
- private String include;
- private List<String> includes = new ArrayList<String>();
- private String exclude;
- private List<String> excludes = new ArrayList<String>();
- private Boolean useDefaultExcludes = true;
- private ResourcePatternResolver resourcePatternResolver;
- private PathMatcher excludePathMatcher = new AntPathMatcher();
-
- private ResourceLoader resourceLoader;
-
- /** List the resources, identified by their relative path. */
- public Map<String, Resource> listResources() {
- try {
- Map<String, Resource> res = new TreeMap<String, Resource>();
- if (base == null)
- return res;
- String baseResUrl = getResourceLoaderToUse().getResource(base)
- .getURL().toString();
- for (String includePattern : includes)
- processInclude(res, includePattern, baseResUrl);
- return res;
- } catch (IOException e) {
- throw new SlcException("Cannot list resource from " + base, e);
- }
- }
-
- protected void processInclude(Map<String, Resource> res, String include,
- String baseResUrl) throws IOException {
- String pattern = base + "/" + include;
- if (log.isTraceEnabled())
- log.trace("Look for resources with pattern '" + pattern
- + "' in base url " + baseResUrl);
- Resource[] resources = resourcePatternResolver.getResources(pattern);
- resources: for (Resource resource : resources) {
- String url = resource.getURL().toString();
- String relPath = url.substring(baseResUrl.length());
-
- // skip dir
- if (relPath.charAt(relPath.length() - 1) == '/') {
- if (log.isTraceEnabled())
- log.trace("Skip directory " + relPath + "=" + resource);
- continue resources;
- }
-
- // make sure there is not starting '/'
- if (relPath.charAt(0) == '/')
- relPath = relPath.substring(1);
-
- // skip excludes
- for (String exclude : excludes)
- if (excludePathMatcher.match(exclude, relPath)) {
- if (log.isTraceEnabled())
- log.trace("Exclude " + relPath + "=" + resource);
- continue resources;
- }
-
- // check if already exists
- if (res.containsKey(relPath))
- log.warn(relPath + " already matched by " + res.get(relPath)
- + ", " + resource + " will override it.");
-
- // store the marched resource
- res.put(relPath, resource);
- if (log.isTraceEnabled())
- log.trace(relPath + "=" + resource);
- }
-
- }
-
- public void afterPropertiesSet() throws Exception {
- if (resourcePatternResolver == null)
- resourcePatternResolver = new PathMatchingResourcePatternResolver(
- getResourceLoaderToUse());
- if (include != null)
- addCommaSeparatedToList(include, includes);
- if (exclude != null)
- addCommaSeparatedToList(exclude, excludes);
-
- if (includes.size() == 0)
- includes.add("**");
-
- if (useDefaultExcludes)
- addCommaSeparatedToList(DEFAULT_EXCLUDES, excludes);
- }
-
- private void addCommaSeparatedToList(String str, List<String> lst) {
- StringTokenizer st = new StringTokenizer(str, ",");
- while (st.hasMoreTokens()) {
- String token = st.nextToken();
- if (!lst.contains(token))
- lst.add(token);
- }
- }
-
- public void setResourceLoader(ResourceLoader resourceLoader) {
- this.resourceLoader = resourceLoader;
- }
-
- /**
- * Can be overridden in order to provide the proper resource loader used to
- * resolve resources.
- */
- public ResourceLoader getResourceLoaderToUse() {
- return resourceLoader;
- }
-
- public void setBase(String base) {
- this.base = base;
- }
-
- public void setInclude(String include) {
- this.include = include;
- }
-
- public void setIncludes(List<String> includes) {
- this.includes = includes;
- }
-
- public void setExclude(String exclude) {
- this.exclude = exclude;
- }
-
- public void setExcludes(List<String> excludes) {
- this.excludes = excludes;
- }
-
- public void setUseDefaultExcludes(Boolean useDefaultExcludes) {
- this.useDefaultExcludes = useDefaultExcludes;
- }
-
- public void setExcludePathMatcher(PathMatcher excludePathMatcher) {
- this.excludePathMatcher = excludePathMatcher;
- }
-
- public void setResourcePatternResolver(
- ResourcePatternResolver resourcePatternResolver) {
- this.resourcePatternResolver = resourcePatternResolver;
- }
-
- public ResourcePatternResolver getResourcePatternResolver() {
- return resourcePatternResolver;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.argeo.slc.SlcException;
-import org.argeo.util.security.DigestUtils;
-import org.springframework.core.io.Resource;
-
-/** Add Spring capabilities to {@link DigestUtils} */
-public class DigestCheck extends DigestUtils {
- public static String digest(String algorithm, Resource resource) {
- try {
- File file = resource.getFile();
- return digest(algorithm, file);
- } catch (IOException e) {
- try {
- return digest(algorithm, resource.getInputStream());
- } catch (IOException e1) {
- throw new SlcException("Cannot digest " + resource
- + " with algorithm " + algorithm, e);
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Map;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.argeo.slc.SlcException;
-import org.springframework.core.io.Resource;
-
-public class LocalFilesDeployment implements Runnable {
- private String targetBase = "";
- private ResourceSet resourceSet;
-
- public LocalFilesDeployment() {
- }
-
- public LocalFilesDeployment(ResourceSet resourceSet) {
- this.resourceSet = resourceSet;
- }
-
- public void run() {
- Map<String, Resource> resources = resourceSet.listResources();
- for (String relPath : resources.keySet()) {
- File targetFile = new File(targetBase + File.separator + relPath);
- File parentDir = targetFile.getParentFile();
- if (!parentDir.exists())
- parentDir.mkdirs();
-
- Resource resource = resources.get(relPath);
-
- InputStream in = null;
- OutputStream out = null;
- try {
- in = resource.getInputStream();
- out = FileUtils.openOutputStream(targetFile);
- IOUtils.copy(in, out);
- } catch (IOException e) {
- throw new SlcException("Cannot extract " + resource + " to "
- + targetFile, e);
- } finally {
- IOUtils.closeQuietly(in);
- IOUtils.closeQuietly(out);
- }
- }
- }
-
- public void setTargetBase(String targetBase) {
- this.targetBase = targetBase;
- }
-
- public void setResourceSet(ResourceSet resourceSet) {
- this.resourceSet = resourceSet;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.springframework.core.io.Resource;
-
-public class MultiResourceSet implements ResourceSet {
- private List<ResourceSet> resourceSets = new ArrayList<ResourceSet>();
-
- public Map<String, Resource> listResources() {
- Map<String, Resource> res = new HashMap<String, Resource>();
- for (ResourceSet resourceSet : resourceSets) {
- res.putAll(resourceSet.listResources());
- }
- return res;
- }
-
- /** Last listed override previous for the same relative paths. */
- public void setResourceSets(List<ResourceSet> resourceSets) {
- this.resourceSets = resourceSets;
- }
-
- public List<ResourceSet> getResourceSets() {
- return resourceSets;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.util.Map;
-
-import org.springframework.core.io.Resource;
-
-public interface ResourceSet {
- /**
- * List the resources, identified by their relative path. Relative paths
- * must NOT start with a '/'.
- */
- public Map<String, Resource> listResources();
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.io.File;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.build.Distribution;
-import org.argeo.slc.deploy.DeploymentData;
-import org.argeo.slc.deploy.InstalledExecutables;
-import org.argeo.slc.deploy.TargetData;
-
-public class SimpleExecutables implements InstalledExecutables {
- private final static Log log = LogFactory.getLog(SimpleExecutables.class);
-
- private String baseDir;
- private Map<String, String> paths = new TreeMap<String, String>();
-
- private Distribution distribution;
-
- public String getExecutablePath(String key) {
- String path = paths.get(key);
- if (path == null) {
- if (log.isDebugEnabled())
- log.debug("No executable path found for key " + key
- + ", using the key as executable name.");
- path = key;
- }
-
- if (baseDir != null)
- path = baseDir + File.separator + path;
- return path;
- }
-
- public String getDeployedSystemId() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public DeploymentData getDeploymentData() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public Distribution getDistribution() {
- return distribution;
- }
-
- public TargetData getTargetData() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public String getBaseDir() {
- return baseDir;
- }
-
- public void setBaseDir(String baseDir) {
- this.baseDir = baseDir;
- }
-
- public Map<String, String> getPaths() {
- return paths;
- }
-
- public void setPaths(Map<String, String> paths) {
- this.paths = paths;
- }
-
- public void setDistribution(Distribution distribution) {
- this.distribution = distribution;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.deploy.VersioningDriver;
-
-/**
- * Synchronizes an URL to a local directory, taking into account versioning
- * information if possible.
- */
-public class VersionedDirSync implements Runnable {
- private final static Log log = LogFactory.getLog(VersionedDirSync.class);
-
- private VersioningDriver versioningDriver;
- private File dir;
- private String url;
- private Boolean clean = false;
-
- private Boolean changed = null;
-
- public void run() {
- changed = null;
- if (clean) {
- try {
- log.info("Clean " + dir);
- FileUtils.deleteDirectory(dir);
- } catch (IOException e) {
- throw new SlcException("Cannot delete checkout directory "
- + dir, e);
- }
- dir.mkdirs();
- }
- log.info("Checkout " + url + " to " + dir);
- changed = versioningDriver.checkout(url, dir, true);
- if (log.isDebugEnabled())
- log.debug("Synchronized " + url + " to " + dir);
- }
-
- public void setVersioningDriver(VersioningDriver versioningDriver) {
- this.versioningDriver = versioningDriver;
- }
-
- public void setDir(File dir) {
- this.dir = dir;
- }
-
- public void setUrl(String url) {
- this.url = url;
- }
-
- /** Delete before checkout */
- public void setClean(Boolean clean) {
- this.clean = clean;
- }
-
- /** Whether last call has changed the directory */
- public Boolean getChanged() {
- if (changed == null)
- throw new SlcException("Sync has not run");
- return changed;
- }
-
-}
+++ /dev/null
-<html>\r
-<head></head>\r
-<body>\r
-SLC Deploy: deployment of software systems.\r
-</body>\r
-</html>
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.GenericBeanDefinition;
-import org.springframework.core.Ordered;
-import org.springframework.core.PriorityOrdered;
-
-public abstract class AbstractExecutionFlowGenerator implements
- BeanFactoryPostProcessor, PriorityOrdered {
- private final Log log = LogFactory.getLog(getClass());
-
- protected abstract Map<String, BeanDefinition> createExecutionFlowDefinitions(
- ConfigurableListableBeanFactory beanFactory);
-
- public void postProcessBeanFactory(
- ConfigurableListableBeanFactory beanFactory) throws BeansException {
- if (!(beanFactory instanceof BeanDefinitionRegistry)) {
- throw new SlcException("Can only work on "
- + BeanDefinitionRegistry.class);
- }
-
- Map<String, BeanDefinition> definitions = createExecutionFlowDefinitions(beanFactory);
-
- for (String beanName : definitions.keySet()) {
- if (log.isTraceEnabled())
- log.debug("Registering execution flow " + beanName);
- ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(
- beanName, definitions.get(beanName));
- }
- }
-
- protected GenericBeanDefinition createDefaultFlowDefinition(
- List<Runnable> executables) {
- GenericBeanDefinition bd = new GenericBeanDefinition();
- bd.setBeanClass(DefaultExecutionFlow.class);
-
- MutablePropertyValues mpv = new MutablePropertyValues();
- mpv.addPropertyValue("executables", executables);
-
- bd.setPropertyValues(mpv);
- return bd;
- }
-
- public int getOrder() {
- return Ordered.HIGHEST_PRECEDENCE;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.execution.ExecutionContext;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.RealizedFlow;
-
-/** Provides the base feature of an execution module manager. */
-public abstract class AbstractExecutionModulesManager implements
- ExecutionModulesManager {
- private final static Log log = LogFactory
- .getLog(AbstractExecutionModulesManager.class);
-
-// private List<FilteredNotifier> filteredNotifiers = Collections
-// .synchronizedList(new ArrayList<FilteredNotifier>());
-
- protected abstract ExecutionFlow findExecutionFlow(String moduleName,
- String moduleVersion, String flowName);
-
- protected abstract ExecutionContext findExecutionContext(String moduleName,
- String moduleVersion);
-
- protected abstract ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
- String moduleName, String moduleVersion);
-
- public void execute(RealizedFlow realizedFlow) {
- if (log.isTraceEnabled())
- log.trace("Executing " + realizedFlow);
-
- String moduleName = realizedFlow.getModuleName();
- String moduleVersion = realizedFlow.getModuleVersion();
-
- Map<? extends String, ? extends Object> variablesToAdd = getExecutionFlowDescriptorConverter(
- moduleName, moduleVersion).convertValues(
- realizedFlow.getFlowDescriptor());
- ExecutionContext executionContext = findExecutionContext(moduleName,
- moduleVersion);
- for (String key : variablesToAdd.keySet())
- executionContext.setVariable(key, variablesToAdd.get(key));
-
- ExecutionFlow flow = findExecutionFlow(moduleName, moduleVersion,
- realizedFlow.getFlowDescriptor().getName());
-
- //
- // Actually runs the flow, IN THIS THREAD
- //
- flow.run();
- //
- //
- //
- }
-
-// public void dispatchUpdateStatus(ExecutionProcess process,
-// String oldStatus, String newStatus) {
-// // filtered notifiers
-// for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
-// .hasNext();) {
-// FilteredNotifier filteredNotifier = it.next();
-// if (filteredNotifier.receiveFrom(process))
-// filteredNotifier.getNotifier().updateStatus(process, oldStatus,
-// newStatus);
-// }
-//
-// }
-
-// public void dispatchAddSteps(ExecutionProcess process,
-// List<ExecutionStep> steps) {
-// process.addSteps(steps);
-// for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
-// .hasNext();) {
-// FilteredNotifier filteredNotifier = it.next();
-// if (filteredNotifier.receiveFrom(process))
-// filteredNotifier.getNotifier().addSteps(process, steps);
-// }
-// }
-
-// public void registerProcessNotifier(ExecutionProcessNotifier notifier,
-// Map<String, String> properties) {
-// filteredNotifiers.add(new FilteredNotifier(notifier, properties));
-// }
-//
-// public void unregisterProcessNotifier(ExecutionProcessNotifier notifier,
-// Map<String, String> properties) {
-// filteredNotifiers.remove(notifier);
-// }
-
-// protected class FilteredNotifier {
-// private final ExecutionProcessNotifier notifier;
-// private final String processId;
-//
-// public FilteredNotifier(ExecutionProcessNotifier notifier,
-// Map<String, String> properties) {
-// super();
-// this.notifier = notifier;
-// if (properties == null)
-// properties = new HashMap<String, String>();
-// if (properties.containsKey(SLC_PROCESS_ID))
-// processId = properties.get(SLC_PROCESS_ID);
-// else
-// processId = null;
-// }
-//
-// /**
-// * Whether event from this process should be received by this listener.
-// */
-// public Boolean receiveFrom(ExecutionProcess process) {
-// if (processId != null)
-// if (process.getUuid().equals(processId))
-// return true;
-// else
-// return false;
-// return true;
-// }
-//
-// @Override
-// public int hashCode() {
-// return notifier.hashCode();
-// }
-//
-// @Override
-// public boolean equals(Object obj) {
-// if (obj instanceof FilteredNotifier) {
-// FilteredNotifier fn = (FilteredNotifier) obj;
-// return notifier.equals(fn.notifier);
-// } else if (obj instanceof ExecutionProcessNotifier) {
-// ExecutionProcessNotifier epn = (ExecutionProcessNotifier) obj;
-// return notifier.equals(epn);
-// } else
-// return false;
-// }
-//
-// public ExecutionProcessNotifier getNotifier() {
-// return notifier;
-// }
-//
-// }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.Serializable;
-
-/** Value to be used by an execution */
-public abstract class AbstractExecutionValue implements Serializable {
- private static final long serialVersionUID = 1558444746120706961L;
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.Serializable;
-
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-
-/** Canonical implementation of the execution spec attribute booleans. */
-public abstract class AbstractSpecAttribute implements ExecutionSpecAttribute,
- Serializable {
- private static final long serialVersionUID = 6494963738891709440L;
- private Boolean isImmutable = false;
- private Boolean isConstant = false;
- private Boolean isHidden = false;
-
- private String description;
-
- /** Has to be set at instantiation */
- public Boolean getIsImmutable() {
- return isImmutable;
- }
-
- public void setIsImmutable(Boolean isImmutable) {
- this.isImmutable = isImmutable;
- }
-
- /** Cannot be overridden at runtime */
- public Boolean getIsConstant() {
- return isConstant;
- }
-
- public void setIsConstant(Boolean isConstant) {
- this.isConstant = isConstant;
- }
-
- /** Should not be shown to the end user */
- public Boolean getIsHidden() {
- return isHidden;
- }
-
- public void setIsHidden(Boolean isHidden) {
- this.isHidden = isHidden;
- }
-
- /*
- * DEPRECATED
- */
- /** @deprecated use {@link #getIsImmutable()} instead */
- public Boolean getIsParameter() {
- return isImmutable;
- }
-
- /** @deprecated use {@link #getIsConstant()} instead */
- public Boolean getIsFrozen() {
- return isConstant;
- }
-
- /** @deprecated use {@link #setIsImmutable(Boolean)} instead */
- public void setIsParameter(Boolean isParameter) {
- this.isImmutable = isParameter;
- }
-
- /** @deprecated use {@link #setIsConstant(Boolean)} instead */
- public void setIsFrozen(Boolean isFrozen) {
- this.isConstant = isFrozen;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public String getDescription() {
- return description;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.argeo.slc.execution.ExecutionModule;
-
-@Deprecated
-public abstract class AbstractSpringExecutionModule implements ExecutionModule
- {
-/*
- protected ApplicationContext applicationContext;
-
- protected ExecutionContext executionContext;
-
- protected ExecutionFlowDescriptorConverter descriptorConverter = new DefaultDescriptorConverter();
-
- public ExecutionModuleDescriptor getDescriptor() {
- ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
- md.setName(getName());
- md.setVersion(getVersion());
-
- Map<String, ExecutionFlow> executionFlows = listFlows();
- for (String name : executionFlows.keySet()) {
- ExecutionFlow executionFlow = executionFlows.get(name);
-
- Assert.notNull(executionFlow.getName());
- Assert.state(name.equals(executionFlow.getName()));
-
- ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
- Assert.notNull(executionSpec);
- Assert.notNull(executionSpec.getName());
-
- Map<String, Object> values = new TreeMap<String, Object>();
- for (String key : executionSpec.getAttributes().keySet()) {
- ExecutionSpecAttribute attribute = executionSpec
- .getAttributes().get(key);
-
- if (executionFlow.isSetAsParameter(key)) {
- Object value = executionFlow.getParameter(key);
- if (attribute instanceof PrimitiveSpecAttribute) {
- PrimitiveValue primitiveValue = new PrimitiveValue();
- primitiveValue
- .setType(((PrimitiveSpecAttribute) attribute)
- .getType());
- primitiveValue.setValue(value);
- values.put(key, primitiveValue);
- } else if (attribute instanceof RefSpecAttribute) {
- RefValue refValue = new RefValue();
- if (value instanceof ScopedObject) {
- refValue.setLabel("RUNTIME "
- + value.getClass().getName());
- } else {
- refValue.setLabel("STATIC "
- + value.getClass().getName());
- }
- values.put(key, refValue);
- } else if (attribute instanceof ResourceSpecAttribute) {
- PrimitiveValue primitiveValue = new PrimitiveValue();
- primitiveValue
- .setType(((ResourceSpecAttribute) attribute)
- .getType());
- primitiveValue.setValue(value);
- values.put(key, primitiveValue);
- } else {
- throw new SlcException("Unkown spec attribute type "
- + attribute.getClass());
- }
- }
-
- }
-
- ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name,
- values, executionSpec);
- if (executionFlow.getPath() != null)
- efd.setPath(executionFlow.getPath());
-
- // Add execution spec if necessary
- if (!md.getExecutionSpecs().contains(executionSpec))
- md.getExecutionSpecs().add(executionSpec);
-
- // Add execution flow
- md.getExecutionFlows().add(efd);
- }
-
- return md;
- }
-
- protected Map<String, ExecutionFlow> listFlows() {
- GenericBeanFactoryAccessor accessor = new GenericBeanFactoryAccessor(
- applicationContext);
- Map<String, ExecutionFlow> executionFlows = accessor
- .getBeansOfType(ExecutionFlow.class);
- return executionFlows;
- }
-
- public void execute(ExecutionFlowDescriptor executionFlowDescriptor) {
- if (descriptorConverter != null)
- executionContext.addVariables(descriptorConverter
- .convertValues(executionFlowDescriptor));
- ExecutionFlow flow = (ExecutionFlow) applicationContext.getBean(
- executionFlowDescriptor.getName(), ExecutionFlow.class);
- flow.run();
- }
-
- public void setApplicationContext(ApplicationContext applicationContext)
- throws BeansException {
- this.applicationContext = applicationContext;
- }
-
- public void setExecutionContext(ExecutionContext executionContext) {
- this.executionContext = executionContext;
- }
-
- public void setDescriptorConverter(
- ExecutionFlowDescriptorConverter descriptorConverter) {
- this.descriptorConverter = descriptorConverter;
- }*/
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLDecoder;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import org.argeo.slc.BasicNameVersion;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionModuleDescriptor;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.ExecutionProcess;
-import org.argeo.slc.execution.SlcAgent;
-
-/** Implements the base methods of an SLC agent. */
-public class DefaultAgent implements SlcAgent {
- // private final static Log log = LogFactory.getLog(DefaultAgent.class);
- /** UTF-8 charset for encoding. */
- private final static String UTF8 = "UTF-8";
-
- private String agentUuid = null;
- private ExecutionModulesManager modulesManager;
-
- private ThreadGroup processesThreadGroup;
- private Map<String, ProcessThread> runningProcesses = Collections
- .synchronizedMap(new HashMap<String, ProcessThread>());
-
- private String defaultModulePrefix = null;
-
- /*
- * LIFECYCLE
- */
- /** Initialization */
- public void init() {
- agentUuid = initAgentUuid();
- processesThreadGroup = new ThreadGroup("SLC Processes of Agent #"
- + agentUuid);
- }
-
- /** Clean up (needs to be called by overriding method) */
- public void destroy() {
- }
-
- /**
- * Called during initialization in order to determines the agent UUID. To be
- * overridden. By default creates a new one per instance.
- */
- protected String initAgentUuid() {
- return UUID.randomUUID().toString();
- }
-
- /*
- * SLC AGENT
- */
- public void process(ExecutionProcess process) {
- ProcessThread processThread = createProcessThread(processesThreadGroup,
- modulesManager, process);
- processThread.start();
- runningProcesses.put(process.getUuid(), processThread);
-
- // clean up old processes
- Iterator<ProcessThread> it = runningProcesses.values().iterator();
- while (it.hasNext()) {
- ProcessThread pThread = it.next();
- if (!pThread.isAlive())
- it.remove();
- }
- }
-
- public String process(List<URI> uris) {
- DefaultProcess process = new DefaultProcess();
- for (URI uri : uris) {
- String[] path = uri.getPath().split("/");
- if (path.length < 3)
- throw new SlcException("Badly formatted URI: " + uri);
- NameVersion nameVersion = new BasicNameVersion(path[1]);
- StringBuilder flow = new StringBuilder();
- for (int i = 2; i < path.length; i++)
- flow.append('/').append(path[i]);
-
- Map<String, Object> values = getQueryMap(uri.getQuery());
- // Get execution module descriptor
- ExecutionModuleDescriptor emd = getExecutionModuleDescriptor(
- nameVersion.getName(), nameVersion.getVersion());
- process.getRealizedFlows().add(
- emd.asRealizedFlow(flow.toString(), values));
- }
- process(process);
- return process.getUuid();
- }
-
- public void kill(String processUuid) {
- if (runningProcesses.containsKey(processUuid)) {
- runningProcesses.get(processUuid).interrupt();
- } else {
- // assume is finished
- }
- }
-
- public void waitFor(String processUuid, Long millis) {
- if (runningProcesses.containsKey(processUuid)) {
- try {
- if (millis != null)
- runningProcesses.get(processUuid).join(millis);
- else
- runningProcesses.get(processUuid).join();
- } catch (InterruptedException e) {
- // silent
- }
- } else {
- // assume is finished
- }
- }
-
- /** Creates the thread which will coordinate the execution for this agent. */
- protected ProcessThread createProcessThread(
- ThreadGroup processesThreadGroup,
- ExecutionModulesManager modulesManager, ExecutionProcess process) {
- ProcessThread processThread = new ProcessThread(processesThreadGroup,
- modulesManager, process);
- return processThread;
- }
-
- public ExecutionModuleDescriptor getExecutionModuleDescriptor(
- String moduleName, String moduleVersion) {
- // Get execution module descriptor
- ExecutionModuleDescriptor emd;
- try {
- modulesManager
- .start(new BasicNameVersion(moduleName, moduleVersion));
- emd = modulesManager.getExecutionModuleDescriptor(moduleName,
- moduleVersion);
- } catch (SlcException e) {
- if (defaultModulePrefix != null) {
- moduleName = defaultModulePrefix + "." + moduleName;
- modulesManager.start(new BasicNameVersion(moduleName,
- moduleVersion));
- emd = modulesManager.getExecutionModuleDescriptor(moduleName,
- moduleVersion);
- } else
- throw e;
- }
- return emd;
- }
-
- public List<ExecutionModuleDescriptor> listExecutionModuleDescriptors() {
- return modulesManager.listExecutionModules();
- }
-
- public boolean ping() {
- return true;
- }
-
- /*
- * UTILITIES
- */
- /**
- * @param query
- * can be null
- */
- static Map<String, Object> getQueryMap(String query) {
- Map<String, Object> map = new LinkedHashMap<String, Object>();
- if (query == null)
- return map;
- String[] params = query.split("&");
- for (String param : params) {
- String[] arr = param.split("=");
- String name = arr[0];
- Object value = arr.length > 1 ? param.split("=")[1] : Boolean.TRUE;
- try {
- map.put(URLDecoder.decode(name, UTF8),
- URLDecoder.decode(value.toString(), UTF8));
- } catch (UnsupportedEncodingException e) {
- throw new SlcException("Cannot decode '" + param + "'", e);
- }
- }
- return map;
- }
-
- /*
- * BEAN
- */
- public void setModulesManager(ExecutionModulesManager modulesManager) {
- this.modulesManager = modulesManager;
- }
-
- public void setDefaultModulePrefix(String defaultModulePrefix) {
- this.defaultModulePrefix = defaultModulePrefix;
- }
-
- public String getAgentUuid() {
- return agentUuid;
- }
-
- @Override
- public String toString() {
- return "Agent #" + getAgentUuid();
- }
-}
+++ /dev/null
-package org.argeo.slc.core.execution;
-
-import java.net.URI;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.security.OsAuthenticationToken;
-import org.argeo.slc.BasicNameVersion;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionFlowDescriptor;
-import org.argeo.slc.execution.ExecutionModuleDescriptor;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.argeo.slc.execution.SlcAgent;
-import org.argeo.slc.execution.SlcAgentCli;
-import org.springframework.security.Authentication;
-import org.springframework.security.AuthenticationManager;
-import org.springframework.security.context.SecurityContextHolder;
-
-/**
- * Authenticates thread and executes synchronously a command line execution.
- * Reference implementation of args to URIs algorithm.
- */
-public class DefaultAgentCli implements SlcAgentCli {
- private final static Log log = LogFactory.getLog(DefaultAgentCli.class);
-
- private final static String UTF8 = "UTF-8";
- private SlcAgent agent;
- private AuthenticationManager authenticationManager;
-
- private Long timeout = 24 * 60 * 60 * 1000l;
-
- public String process(String[] args) {
- if (SecurityContextHolder.getContext().getAuthentication() == null) {
- OsAuthenticationToken oat = new OsAuthenticationToken();
- Authentication authentication = authenticationManager
- .authenticate(oat);
- SecurityContextHolder.getContext()
- .setAuthentication(authentication);
- }
-
- if (args.length > 0 && args[0].equals("help")) {
- StringBuilder buf = new StringBuilder();
- help(args, buf);
- log.info("\n" + buf);
- return buf.toString();
- } else {
- List<URI> uris = asURIs(args);
- String processUuid = agent.process(uris);
- agent.waitFor(processUuid, timeout);
- return processUuid;
- }
- }
-
- protected void help(String[] rawArgs, StringBuilder buf) {
- String[] args = Arrays.copyOfRange(rawArgs, 1, rawArgs.length);
- if (args.length == 0) {// modules
- for (ExecutionModuleDescriptor emd : agent
- .listExecutionModuleDescriptors()) {
- appendModule(emd, buf);
- }
- } else if (args.length == 1 && !args[0].contains("/")) {// single module
- NameVersion nameVersion = new BasicNameVersion(args[0]);
- ExecutionModuleDescriptor emd = agent.getExecutionModuleDescriptor(
- nameVersion.getName(), nameVersion.getVersion());
- appendModule(emd, buf);
-
- // flows
- for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) {
- buf.append(" ").append(efd.getName());
- if (efd.getDescription() != null
- && !efd.getDescription().trim().equals(""))
- buf.append(" : ").append(" ").append(efd.getDescription());
- buf.append('\n');
- }
- return;
- } else {
- List<URI> uris = asURIs(args);
- for (URI uri : uris) {
- appendUriHelp(uri, buf);
- }
- }
- }
-
- protected void appendUriHelp(URI uri, StringBuilder buf) {
- String[] path = uri.getPath().split("/");
- NameVersion nameVersion = new BasicNameVersion(path[1]);
- ExecutionModuleDescriptor emd = agent.getExecutionModuleDescriptor(
- nameVersion.getName(), nameVersion.getVersion());
-
- StringBuilder flow = new StringBuilder();
- for (int i = 2; i < path.length; i++)
- flow.append('/').append(path[i]);
- String flowPath = flow.toString();
- ExecutionFlowDescriptor efd = findExecutionFlowDescriptor(emd, flowPath);
- if (efd == null)
- throw new SlcException("Flow " + uri + " not found");
-
- appendModule(emd, buf);
-
- buf.append(" ").append(efd.getName());
- if (efd.getDescription() != null
- && !efd.getDescription().trim().equals(""))
- buf.append(" : ").append(" ").append(efd.getDescription());
- buf.append('\n');
- Map<String, Object> values = DefaultAgent.getQueryMap(uri.getQuery());
- ExecutionSpec spec = efd.getExecutionSpec();
- for (String attrKey : spec.getAttributes().keySet()) {
- ExecutionSpecAttribute esa = spec.getAttributes().get(attrKey);
- buf.append(" --").append(attrKey);
- if (values.containsKey(attrKey))
- buf.append(" ").append(values.get(attrKey));
- if (esa.getValue() != null)
- buf.append(" (").append(esa.getValue()).append(')');
- buf.append('\n');
- }
- }
-
- private void appendModule(ExecutionModuleDescriptor emd, StringBuilder buf) {
- buf.append("# ").append(emd.getName());
- if (emd.getDescription() != null
- && !emd.getDescription().trim().equals(""))
- buf.append(" : ").append(emd.getDescription());
- if (emd.getVersion() != null)
- buf.append(" (v").append(emd.getVersion()).append(")");
- buf.append('\n');
- }
-
- public static List<URI> asURIs(String[] args) {
- try {
- List<URI> uris = new ArrayList<URI>();
- List<String> leftOvers = new ArrayList<String>();
-
- Boolean hasArgs = false;
- String currKey = null;
- StringBuilder currUri = null;
- Iterator<String> argIt = Arrays.asList(args).iterator();
- while (argIt.hasNext()) {
- String arg = argIt.next();
- if (!arg.startsWith("-")) {
- if (currKey != null) {// value
- currUri.append(URLEncoder.encode(arg, UTF8));
- currKey = null;
- } else { // module
- if (currUri != null) {
- uris.add(new URI(currUri.toString()));
- }
- currUri = new StringBuilder("flow:");
-
- String currModule = arg;
- currUri.append('/').append(currModule);
- if (!arg.contains("/")) {
- // flow path not in arg go to next arg
- if (!argIt.hasNext())
- throw new SlcException("No flow found");
- String currFlow = argIt.next();
- if (!currFlow.startsWith("/"))
- currFlow = "/" + currFlow;
- currUri.append(currFlow);
- }
- }
- } else {
- if (currUri == null) {// first args
- leftOvers.add(arg);
- } else {
- String key;
- if (arg.startsWith("--"))
- key = arg.substring(2);
- else if (arg.startsWith("-"))
- key = arg.substring(1);
- else {
- throw new SlcException("Cannot intepret key: "
- + arg);
- }
-
- if (!hasArgs) {
- currUri.append('?');
- hasArgs = true;
- } else {
- currUri.append('&');
- }
-
- // deal with boolean keys
- if (currKey != null) {// value
- currUri.append(URLEncoder.encode("true", UTF8));
- currKey = null;
- }
-
- currKey = key;
- currUri.append(URLEncoder.encode(key, UTF8))
- .append('=');
- }
- }
- }
- if (currUri != null)
- uris.add(new URI(currUri.toString()));
- return uris;
- } catch (Exception e) {
- throw new SlcException("Cannot convert " + Arrays.toString(args)
- + " to flow URI", e);
- }
- }
-
- private ExecutionFlowDescriptor findExecutionFlowDescriptor(
- ExecutionModuleDescriptor emd, String flowPath) {
- ExecutionFlowDescriptor flowDescriptor = null;
- for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) {
- String name = efd.getName();
- // normalize name as flow path
- if (!name.startsWith("/"))
- name = "/" + name;
- if (name.endsWith("/"))
- name = name.substring(0, name.length() - 1);
- if (name.equals(flowPath)) {
- flowDescriptor = efd;
- break;
- }
- }
- return flowDescriptor;
- }
-
- public void setAgent(SlcAgent agent) {
- this.agent = agent;
- }
-
- public void setAuthenticationManager(
- AuthenticationManager authenticationManager) {
- this.authenticationManager = authenticationManager;
- }
-
- public void setTimeout(Long timeout) {
- this.timeout = timeout;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.springframework.beans.factory.BeanNameAware;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.validation.MapBindingResult;
-
-/** Default implementation of an execution flow. */
-public class DefaultExecutionFlow implements ExecutionFlow, InitializingBean,
- BeanNameAware {
- private final static Log log = LogFactory
- .getLog(DefaultExecutionFlow.class);
-
- private final ExecutionSpec executionSpec;
- private String name = null;
- private Map<String, Object> parameters = new HashMap<String, Object>();
- private List<Runnable> executables = new ArrayList<Runnable>();
-
- private String path;
-
- private Boolean failOnError = true;
-
- public DefaultExecutionFlow() {
- this.executionSpec = new DefaultExecutionSpec();
- }
-
- public DefaultExecutionFlow(ExecutionSpec executionSpec) {
- this.executionSpec = executionSpec;
- }
-
- public DefaultExecutionFlow(ExecutionSpec executionSpec,
- Map<String, Object> parameters) {
- // be sure to have an execution spec
- this.executionSpec = (executionSpec == null) ? new DefaultExecutionSpec()
- : executionSpec;
-
- // only parameters contained in the executionSpec can be set
- for (String parameter : parameters.keySet()) {
- if (!executionSpec.getAttributes().containsKey(parameter)) {
- throw new SlcException("Parameter " + parameter
- + " is not defined in the ExecutionSpec");
- }
- }
-
- // set the parameters
- this.parameters.putAll(parameters);
-
- // check that all the required parameters are defined
- MapBindingResult errors = new MapBindingResult(parameters, "execution#"
- + getName());
- for (String key : executionSpec.getAttributes().keySet()) {
- ExecutionSpecAttribute attr = executionSpec.getAttributes()
- .get(key);
-
- if (attr.getIsImmutable() && !isSetAsParameter(key)) {
- errors.rejectValue(key, "Immutable but not set");
- break;
- }
-
- if (attr.getIsConstant() && !isSetAsParameter(key)) {
- errors.rejectValue(key, "Constant but not set as parameter");
- break;
- }
-
- if (attr.getIsHidden() && !isSetAsParameter(key)) {
- errors.rejectValue(key, "Hidden but not set as parameter");
- break;
- }
- }
-
- if (errors.hasErrors())
- throw new SlcException("Could not prepare execution flow: "
- + errors.toString());
-
- }
-
- public void run() {
- try {
- for (Runnable executable : executables) {
- if (Thread.interrupted()) {
- log.error("Flow '" + getName() + "' killed before '"
- + executable + "'");
- Thread.currentThread().interrupt();
- return;
- // throw new ThreadDeath();
- }
- this.doExecuteRunnable(executable);
- }
- } catch (RuntimeException e) {
- if (Thread.interrupted()) {
- log.error("Flow '" + getName()
- + "' killed while receiving an unrelated exception", e);
- Thread.currentThread().interrupt();
- return;
- // throw new ThreadDeath();
- }
- if (failOnError)
- throw e;
- else {
- log.error("Execution flow failed,"
- + " but process did not fail"
- + " because failOnError property"
- + " is set to false: " + e);
- if (log.isTraceEnabled())
- e.printStackTrace();
- }
- }
- }
-
- /**
- * List sub-runnables that would be executed if run() method would be
- * called.
- */
- public Iterator<Runnable> runnables() {
- return executables.iterator();
- }
-
- /**
- * If there is one and only one runnable wrapped return it, throw an
- * exeception otherwise.
- */
- public Runnable getRunnable() {
- if (executables.size() == 1)
- return executables.get(0);
- else
- throw new SlcException("There are " + executables.size()
- + " runnables in flow " + getName());
- }
-
- public void doExecuteRunnable(Runnable runnable) {
- runnable.run();
- }
-
- public void afterPropertiesSet() throws Exception {
- if (path == null) {
- if (name.charAt(0) == '/') {
- path = name.substring(0, name.lastIndexOf('/'));
- }
- }
-
- if (path != null) {
- for (Runnable executable : executables) {
- if (executable instanceof DefaultExecutionFlow) {
- // so we don't need to have DefaultExecutionFlow
- // implementing StructureAware
- // FIXME: probably has side effects
- DefaultExecutionFlow flow = (DefaultExecutionFlow) executable;
- String newPath = path + '/' + flow.getName();
- flow.setPath(newPath);
- log.warn(newPath + " was forcibly set on " + flow);
- }
- }
- }
- }
-
- public void setBeanName(String name) {
- this.name = name;
- }
-
- public void setExecutables(List<Runnable> executables) {
- this.executables = executables;
- }
-
- public void setParameters(Map<String, Object> attributes) {
- this.parameters = attributes;
- }
-
- public String getName() {
- return name;
- }
-
- public ExecutionSpec getExecutionSpec() {
- return executionSpec;
- }
-
- public Object getParameter(String parameterName) {
- // Verify that there is a spec attribute
- ExecutionSpecAttribute specAttr = null;
- if (executionSpec.getAttributes().containsKey(parameterName)) {
- specAttr = executionSpec.getAttributes().get(parameterName);
- } else {
- throw new SlcException("Key " + parameterName
- + " is not defined in the specifications of " + toString());
- }
-
- if (parameters.containsKey(parameterName)) {
- Object paramValue = parameters.get(parameterName);
- return paramValue;
- } else {
- if (specAttr.getValue() != null) {
- return specAttr.getValue();
- }
- }
- throw new SlcException("Key " + parameterName
- + " is not set as parameter in " + toString());
- }
-
- public Boolean isSetAsParameter(String key) {
- return parameters.containsKey(key)
- || (executionSpec.getAttributes().containsKey(key) && executionSpec
- .getAttributes().get(key).getValue() != null);
- }
-
- @Override
- public String toString() {
- return new StringBuffer("Execution flow ").append(name).toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- return ((ExecutionFlow) obj).getName().equals(name);
- }
-
- @Override
- public int hashCode() {
- return name.hashCode();
- }
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- public Boolean getFailOnError() {
- return failOnError;
- }
-
- public void setFailOnError(Boolean failOnError) {
- this.failOnError = failOnError;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionFlowDescriptor;
-import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
-import org.argeo.slc.execution.ExecutionModuleDescriptor;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.springframework.aop.scope.ScopedObject;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.util.StringUtils;
-
-/**
- * Performs conversion in both direction between data exchanged with the agent
- * and the data in the application context.
- */
-public class DefaultExecutionFlowDescriptorConverter implements
- ExecutionFlowDescriptorConverter, ApplicationContextAware {
- public final static String REF_VALUE_TYPE_BEAN_NAME = "beanName";
-
- /** Workaround for https://www.spartadn.com/bugzilla/show_bug.cgi?id=206 */
- private final static String REF_VALUE_INTERNAL = "[internal]";
-
- private final static Log log = LogFactory
- .getLog(DefaultExecutionFlowDescriptorConverter.class);
-
- private ApplicationContext applicationContext;
-
- @SuppressWarnings("unused")
- public Map<String, Object> convertValues(
- ExecutionFlowDescriptor executionFlowDescriptor) {
- Map<String, Object> values = executionFlowDescriptor.getValues();
- Map<String, Object> convertedValues = new HashMap<String, Object>();
- ExecutionSpec executionSpec = executionFlowDescriptor
- .getExecutionSpec();
-
- if (executionSpec == null && log.isTraceEnabled())
- log.warn("Execution spec is null for " + executionFlowDescriptor);
-
- if (values != null && executionSpec != null) {
- values: for (String key : values.keySet()) {
- ExecutionSpecAttribute attribute = executionSpec
- .getAttributes().get(key);
-
- if (attribute == null)
- throw new FlowConfigurationException(
- "No spec attribute defined for '" + key + "'");
-
- if (attribute.getIsConstant())
- continue values;
-
- Object value = values.get(key);
- if (value instanceof PrimitiveValue) {
- PrimitiveValue primitiveValue = (PrimitiveValue) value;
- // TODO: check class <=> type
- convertedValues.put(key, primitiveValue.getValue());
- } else if (value instanceof RefValue) {
- RefValue refValue = (RefValue) value;
- String type = refValue.getType();
- if (REF_VALUE_TYPE_BEAN_NAME.equals(type)) {
- // FIXME: UI should send all information about spec
- // - targetClass
- // - name
- // String executionSpecName = executionSpec.getName();
- // ExecutionSpec localSpec = (ExecutionSpec)
- // applicationContext
- // .getBean(executionSpecName);
- // RefSpecAttribute localAttr = (RefSpecAttribute)
- // localSpec
- // .getAttributes().get(key);
- // Class<?> targetClass = localAttr.getTargetClass();
- //
- // String primitiveType = PrimitiveUtils
- // .classAsType(targetClass);
- String primitiveType = null;
- if (primitiveType != null) {
- // not active
- String ref = refValue.getRef();
- Object obj = PrimitiveUtils.convert(primitiveType,
- ref);
- convertedValues.put(key, obj);
- } else {
- String ref = refValue.getRef();
- if (ref != null && !ref.equals(REF_VALUE_INTERNAL)) {
- Object obj = null;
- if (applicationContext.containsBean(ref)) {
- obj = applicationContext.getBean(ref);
- } else {
- // FIXME: hack in order to pass primitive
- obj = ref;
- }
- convertedValues.put(key, obj);
- } else {
- log.warn("Cannot interpret " + refValue);
- }
- }
- } else if (PrimitiveUtils.typeAsClass(type) != null) {
- String ref = refValue.getRef();
- Object obj = PrimitiveUtils.convert(type, ref);
- convertedValues.put(key, obj);
- } else {
- throw new FlowConfigurationException(
- "Ref value type not supported: "
- + refValue.getType());
- }
- } else {
- // default is to take the value as is
- convertedValues.put(key, value);
- }
- }
- }
- return convertedValues;
- }
-
- public void addFlowsToDescriptor(ExecutionModuleDescriptor md,
- Map<String, ExecutionFlow> executionFlows) {
- SortedSet<ExecutionFlowDescriptor> set = new TreeSet<ExecutionFlowDescriptor>(
- new ExecutionFlowDescriptorComparator());
- for (String name : executionFlows.keySet()) {
- ExecutionFlow executionFlow = executionFlows.get(name);
-
- ExecutionFlowDescriptor efd = getExecutionFlowDescriptor(executionFlow);
- ExecutionSpec executionSpec = efd.getExecutionSpec();
-
- // Add execution spec if necessary
- if (!md.getExecutionSpecs().contains(executionSpec))
- md.getExecutionSpecs().add(executionSpec);
-
- // Add execution flow
- set.add(efd);
- // md.getExecutionFlows().add(efd);
- }
- md.getExecutionFlows().addAll(set);
- }
-
- @SuppressWarnings("deprecation")
- public ExecutionFlowDescriptor getExecutionFlowDescriptor(
- ExecutionFlow executionFlow) {
- if (executionFlow.getName() == null)
- throw new FlowConfigurationException("Flow name is null: "
- + executionFlow);
- String name = executionFlow.getName();
-
- ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
- if (executionSpec == null)
- throw new FlowConfigurationException("Execution spec is null: "
- + executionFlow);
- if (executionSpec.getName() == null)
- throw new FlowConfigurationException(
- "Execution spec name is null: " + executionSpec);
-
- Map<String, Object> values = new TreeMap<String, Object>();
- for (String key : executionSpec.getAttributes().keySet()) {
- ExecutionSpecAttribute attribute = executionSpec.getAttributes()
- .get(key);
-
- if (attribute instanceof PrimitiveSpecAttribute) {
- if (executionFlow.isSetAsParameter(key)) {
- Object value = executionFlow.getParameter(key);
- PrimitiveValue primitiveValue = new PrimitiveValue();
- primitiveValue.setType(((PrimitiveSpecAttribute) attribute)
- .getType());
- primitiveValue.setValue(value);
- values.put(key, primitiveValue);
- } else {
- // no need to add a primitive value if it is not set,
- // all necessary information is in the spec
- }
- } else if (attribute instanceof RefSpecAttribute) {
- if (attribute.getIsConstant()) {
- values.put(key, new RefValue(REF_VALUE_INTERNAL));
- } else
- values.put(
- key,
- buildRefValue((RefSpecAttribute) attribute,
- executionFlow, key));
- } else {
- throw new FlowConfigurationException(
- "Unkown spec attribute type " + attribute.getClass());
- }
-
- }
-
- ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name, null,
- values, executionSpec);
- if (executionFlow.getPath() != null)
- efd.setPath(executionFlow.getPath());
- else
- efd.setPath("");
-
- // Takes description from spring
- BeanFactory bf = getBeanFactory();
- if (bf != null) {
- BeanDefinition bd = getBeanFactory().getBeanDefinition(name);
- efd.setDescription(bd.getDescription());
- }
- return efd;
- }
-
- @SuppressWarnings(value = { "unchecked" })
- protected RefValue buildRefValue(RefSpecAttribute rsa,
- ExecutionFlow executionFlow, String key) {
- RefValue refValue = new RefValue();
- // FIXME: UI should be able to deal with other types
- refValue.setType(REF_VALUE_TYPE_BEAN_NAME);
- Class<?> targetClass = rsa.getTargetClass();
- String primitiveType = PrimitiveUtils.classAsType(targetClass);
- if (primitiveType != null) {
- if (executionFlow.isSetAsParameter(key)) {
- Object value = executionFlow.getParameter(key);
- refValue.setRef(value.toString());
- }
- refValue.setType(primitiveType);
- return refValue;
- } else {
-
- if (executionFlow.isSetAsParameter(key)) {
- String ref = null;
- Object value = executionFlow.getParameter(key);
- if (applicationContext == null) {
- log.warn("No application context declared, cannot scan ref value.");
- ref = value.toString();
- } else {
-
- // look for a ref to the value
- Map<String, Object> beans = getBeanFactory()
- .getBeansOfType(targetClass, false, false);
- // TODO: also check scoped beans
- beans: for (String beanName : beans.keySet()) {
- Object obj = beans.get(beanName);
- if (value instanceof ScopedObject) {
- // don't call methods of the target of the scope
- if (obj instanceof ScopedObject)
- if (value == obj) {
- ref = beanName;
- break beans;
- }
- } else {
- if (obj.equals(value)) {
- ref = beanName;
- break beans;
- }
- }
- }
- }
- if (ref == null) {
- if (log.isTraceEnabled())
- log.trace("Cannot define reference for ref spec attribute "
- + key
- + " in "
- + executionFlow
- + " ("
- + rsa
- + ")."
- + " If it is an inner bean consider put it frozen.");
- ref = REF_VALUE_INTERNAL;
- } else {
- if (log.isTraceEnabled())
- log.trace(ref
- + " is the reference for ref spec attribute "
- + key + " in " + executionFlow + " (" + rsa
- + ")");
- }
- refValue.setRef(ref);
- }
- return refValue;
- }
- }
-
- /** @return can be null */
- private ConfigurableListableBeanFactory getBeanFactory() {
- if (applicationContext == null)
- return null;
- return ((ConfigurableApplicationContext) applicationContext)
- .getBeanFactory();
- }
-
- /** Must be use within the execution application context */
- public void setApplicationContext(ApplicationContext applicationContext)
- throws BeansException {
- this.applicationContext = applicationContext;
- }
-
- private static class ExecutionFlowDescriptorComparator implements
- Comparator<ExecutionFlowDescriptor> {
- @SuppressWarnings("deprecation")
- public int compare(ExecutionFlowDescriptor o1,
- ExecutionFlowDescriptor o2) {
- // TODO: write unit tests for this
-
- String name1 = o1.getName();
- String name2 = o2.getName();
-
- String path1 = o1.getPath();
- String path2 = o2.getPath();
-
- // Check whether name include path
- int lastIndex1 = name1.lastIndexOf('/');
- // log.debug(name1+", "+lastIndex1);
- if (!StringUtils.hasText(path1) && lastIndex1 >= 0) {
- path1 = name1.substring(0, lastIndex1);
- name1 = name1.substring(lastIndex1 + 1);
- }
-
- int lastIndex2 = name2.lastIndexOf('/');
- if (!StringUtils.hasText(path2) && lastIndex2 >= 0) {
- path2 = name2.substring(0, lastIndex2);
- name2 = name2.substring(lastIndex2 + 1);
- }
-
- // Perform the actual comparison
- if (StringUtils.hasText(path1) && StringUtils.hasText(path2)) {
- if (path1.equals(path2))
- return name1.compareTo(name2);
- else if (path1.startsWith(path2))
- return -1;
- else if (path2.startsWith(path1))
- return 1;
- else
- return path1.compareTo(path2);
- } else if (!StringUtils.hasText(path1)
- && StringUtils.hasText(path2)) {
- return 1;
- } else if (StringUtils.hasText(path1)
- && !StringUtils.hasText(path2)) {
- return -1;
- } else if (!StringUtils.hasText(path1)
- && !StringUtils.hasText(path2)) {
- return name1.compareTo(name2);
- } else {
- return 0;
- }
- }
-
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.springframework.beans.factory.BeanNameAware;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ConfigurableApplicationContext;
-
-/** Spring based implementation of execution specifications. */
-public class DefaultExecutionSpec implements ExecutionSpec, BeanNameAware,
- ApplicationContextAware, InitializingBean, Serializable {
- private static final long serialVersionUID = 5159882223926926539L;
- private final static Log log = LogFactory
- .getLog(DefaultExecutionSpec.class);
- private transient ApplicationContext applicationContext;
-
- private String description;
- private Map<String, ExecutionSpecAttribute> attributes = new HashMap<String, ExecutionSpecAttribute>();
-
- private String name = INTERNAL_NAME;
-
- public Map<String, ExecutionSpecAttribute> getAttributes() {
- return attributes;
- }
-
- public void setAttributes(Map<String, ExecutionSpecAttribute> attributes) {
- this.attributes = attributes;
- }
-
- public void setBeanName(String name) {
- this.name = name;
- }
-
- /**
- * The Spring bean name (only relevant for specs declared has high-level
- * beans)
- */
- public String getName() {
- return name;
- }
-
- public boolean equals(Object obj) {
- return ((ExecutionSpec) obj).getName().equals(name);
- }
-
- /**
- * The Spring bean description (only relevant for specs declared has
- * high-level beans)
- */
- public String getDescription() {
- return description;
- }
-
- private ConfigurableListableBeanFactory getBeanFactory() {
- return ((ConfigurableApplicationContext) applicationContext)
- .getBeanFactory();
- }
-
- public void setApplicationContext(ApplicationContext applicationContext) {
- this.applicationContext = applicationContext;
- }
-
- public void afterPropertiesSet() throws Exception {
- if (description == null) {
- try {
- description = getBeanFactory().getBeanDefinition(name)
- .getDescription();
- } catch (NoSuchBeanDefinitionException e) {
- // silent
- }
- }
-
- for (String key : attributes.keySet()) {
- ExecutionSpecAttribute attr = attributes.get(key);
- if (attr instanceof RefSpecAttribute) {
- RefSpecAttribute rsa = (RefSpecAttribute) attr;
- if (rsa.getChoices() == null) {
- List<RefValueChoice> choices = buildRefValueChoices(rsa);
- rsa.setChoices(choices);
- }
- if (log.isTraceEnabled())
- log.debug("Spec attr " + key + " has "
- + rsa.getChoices().size() + " choices");
- }
- }
- }
-
- /**
- * Generates a list of ref value choices based on the bean available in the
- * application ocntext.
- */
- protected List<RefValueChoice> buildRefValueChoices(RefSpecAttribute rsa) {
- List<RefValueChoice> choices = new ArrayList<RefValueChoice>();
- if (applicationContext == null) {
- log.warn("No application context declared,"
- + " cannot scan ref value choices.");
- return choices;
- }
-
- for (String beanName : getBeanFactory().getBeanNamesForType(
- rsa.getTargetClass(), true, false)) {
-
- // Since Spring 3, systemProperties is implicitly defined but has no
- // bean definition
- // if (beanName.equals("systemProperties"))
- // continue beanNames;
-
- BeanDefinition bd = getBeanFactory().getBeanDefinition(beanName);
- RefValueChoice choice = new RefValueChoice();
- choice.setName(beanName);
- choice.setDescription(bd.getDescription());
- if (log.isTraceEnabled())
- log.debug("Found choice " + beanName + " for " + rsa);
-
- choices.add(choice);
-
- }
- return choices;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
-import java.util.UUID;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.argeo.slc.execution.ExecutionStack;
-
-/** Canonical implementation of an execution stack. */
-public class DefaultExecutionStack implements ExecutionStack {
-
- private final static Log log = LogFactory
- .getLog(DefaultExecutionStack.class);
-
- private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
-
- public synchronized void enterFlow(ExecutionFlow executionFlow) {
- ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
- stack.push(runtime);
-
- Map<String, ExecutionSpecAttribute> specAttrs = executionFlow
- .getExecutionSpec().getAttributes();
- for (String key : specAttrs.keySet()) {
- if (executionFlow.isSetAsParameter(key)) {
- runtime.getLocalVariables().put(key,
- executionFlow.getParameter(key));
- }
- }
- }
-
- public synchronized String getCurrentStackLevelUuid() {
- return stack.peek().getUuid();
- }
-
- public synchronized Integer getStackSize() {
- return stack.size();
- }
-
- /**
- * Looks for a set variable in the stack, starting at the upper flows
- *
- * @return the variable or <code>null</code> if not found
- */
- public synchronized Object findLocalVariable(String key) {
- Object obj = null;
- for (int i = 0; i < stack.size(); i++) {
- if (stack.get(i).getLocalVariables().containsKey(key)) {
- obj = stack.get(i).getLocalVariables().get(key);
- break;
- }
- }
- return obj;
- }
-
- public synchronized void leaveFlow(ExecutionFlow executionFlow) {
- ExecutionFlowRuntime leftEf = stack.pop();
-
- if (!leftEf.getExecutionFlow().getName()
- .equals(executionFlow.getName()))
- throw new SlcException("Asked to leave " + executionFlow
- + " but last is " + leftEf);
-
- leftEf.getScopedObjects().clear();
- leftEf.getLocalVariables().clear();
- }
-
- public synchronized void addScopedObject(String name, Object obj) {
- ExecutionFlowRuntime runtime = stack.peek();
- // TODO: check that the object is not set yet ?
- if (log.isDebugEnabled()) {
- Object existing = findScopedObject(name);
- if (existing != null)
- log.warn("Scoped object " + name + " of type " + obj.getClass()
- + " already registered in " + runtime);
- }
- runtime.getScopedObjects().put(name, obj);
- }
-
- /** @return </code>null<code> if not found */
- public synchronized Object findScopedObject(String name) {
- Object obj = null;
- for (int i = stack.size() - 1; i >= 0; i--) {
- if (stack.get(i).getScopedObjects().containsKey(name)) {
- obj = stack.get(i).getScopedObjects().get(name);
- break;
- }
- }
- return obj;
- }
-
- protected static class ExecutionFlowRuntime {
- private final ExecutionFlow executionFlow;
- private final Map<String, Object> scopedObjects = new HashMap<String, Object>();
- private final Map<String, Object> localVariables = new HashMap<String, Object>();
- private final String uuid = UUID.randomUUID().toString();
-
- public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
- this.executionFlow = executionFlow;
- }
-
- public ExecutionFlow getExecutionFlow() {
- return executionFlow;
- }
-
- public Map<String, Object> getScopedObjects() {
- return scopedObjects;
- }
-
- public String getUuid() {
- return uuid;
- }
-
- public Map<String, Object> getLocalVariables() {
- return localVariables;
- }
-
- @Override
- public String toString() {
- return "Stack Level #" + uuid;
- }
-
- }
-}
+++ /dev/null
-package org.argeo.slc.core.execution;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import org.argeo.slc.execution.ExecutionProcess;
-import org.argeo.slc.execution.ExecutionStep;
-import org.argeo.slc.execution.RealizedFlow;
-
-/** Canonical implementation of an {@link ExecutionProcess} as a bean. */
-public class DefaultProcess implements ExecutionProcess {
- private String uuid = UUID.randomUUID().toString();
- private String status = ExecutionProcess.NEW;
-
- private List<ExecutionStep> steps = new ArrayList<ExecutionStep>();
- private List<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();
-
- public String getUuid() {
- return uuid;
- }
-
- public String getStatus() {
- return status;
- }
-
- public void setStatus(String status) {
- this.status = status;
- }
-
- public void addSteps(List<ExecutionStep> steps) {
- steps.addAll(steps);
- }
-
- public List<RealizedFlow> getRealizedFlows() {
- return realizedFlows;
- }
-
- public List<ExecutionStep> getSteps() {
- return steps;
- }
-
- public void setSteps(List<ExecutionStep> steps) {
- this.steps = steps;
- }
-
- public void setUuid(String uuid) {
- this.uuid = uuid;
- }
-
- public void setRealizedFlows(List<RealizedFlow> realizedFlows) {
- this.realizedFlows = realizedFlows;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.execution.ExecutionContext;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionStack;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-
-@Aspect
-/** Aspect intercepting calls on execution flows and contexts. */
-public class ExecutionAspect {
- private final static Log log = LogFactory.getLog(ExecutionAspect.class);
-
- private ExecutionStack executionStack;
- private ExecutionContext executionContext;
-
- @Around("flowExecution()")
- public void aroundFlow(ProceedingJoinPoint pjp) throws Throwable {
- // IMPORTANT: Make sure that the execution context is called before the
- // execution stack
- executionContext.getUuid();
-
- ExecutionFlow executionFlow = (ExecutionFlow) pjp.getTarget();
- executionStack.enterFlow(executionFlow);
- executionContext.setVariable(ExecutionContext.VAR_FLOW_ID,
- executionStack.getCurrentStackLevelUuid());
- executionContext.setVariable(ExecutionContext.VAR_FLOW_NAME,
- executionFlow.getName());
-
- logStackEvent("=> ", executionFlow);
- try {
- // Actually execute the flow
- pjp.proceed();
- } finally {
- logStackEvent("<= ", executionFlow);
- executionStack.leaveFlow(executionFlow);
- }
- }
-
- @Around("getVariable()")
- public Object aroundGetVariable(ProceedingJoinPoint pjp) throws Throwable {
- Object obj = pjp.proceed();
- // if the variable was not found, look in the stack starting at the
- // upper flows
- if (obj == null) {
- String key = pjp.getArgs()[0].toString();
- obj = executionStack.findLocalVariable(key);
- }
- return obj;
- }
-
- @Pointcut("execution(void org.argeo.slc.execution.ExecutionFlow.run())")
- public void flowExecution() {
- }
-
- @Pointcut("execution(* org.argeo.slc.execution.ExecutionContext.getVariable(..))")
- public void getVariable() {
- }
-
- public void setExecutionStack(ExecutionStack executionStack) {
- this.executionStack = executionStack;
- }
-
- public void setExecutionContext(ExecutionContext executionContext) {
- this.executionContext = executionContext;
- }
-
- protected void logStackEvent(String symbol, ExecutionFlow executionFlow) {
- Integer stackSize = executionStack.getStackSize();
- if (log.isTraceEnabled())
- log.debug(depthSpaces(stackSize) + symbol + executionFlow + " #"
- + executionStack.getCurrentStackLevelUuid() + ", depth="
- + stackSize);
- if (log.isDebugEnabled())
- log.debug(depthSpaces(stackSize) + symbol + executionFlow);
- }
-
- protected void logRunnableExecution(ExecutionFlow executionFlow,
- Runnable runnable) {
- Integer stackSize = executionStack.getStackSize();
- if (log.isDebugEnabled())
- log.debug(depthSpaces(stackSize + 1)
- + runnable.getClass().getSimpleName() + " in "
- + executionFlow);
- }
-
- private String depthSpaces(int depth) {
- StringBuffer buf = new StringBuffer(depth * 2);
- for (int i = 0; i < depth; i++)
- buf.append(" ");
- return buf.toString();
- }
-
-}
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution;\r
-\r
-import java.beans.PropertyDescriptor;\r
-import java.util.HashSet;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.execution.ExecutionContext;\r
-import org.argeo.slc.execution.ExecutionFlow;\r
-import org.springframework.beans.BeansException;\r
-import org.springframework.beans.MutablePropertyValues;\r
-import org.springframework.beans.PropertyValue;\r
-import org.springframework.beans.PropertyValues;\r
-import org.springframework.beans.factory.BeanDefinitionStoreException;\r
-import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;\r
-import org.springframework.beans.factory.config.TypedStringValue;\r
-import org.springframework.beans.factory.support.ManagedList;\r
-import org.springframework.beans.factory.support.ManagedMap;\r
-import org.springframework.beans.factory.support.ManagedSet;\r
-import org.springframework.util.ObjectUtils;\r
-import org.springframework.util.StringUtils;\r
-\r
-/**\r
- * Spring post processor which ensures that execution parameters are properly\r
- * set. It is used at two levels: first during instantiation for instantiation\r
- * parameters which allow to implement templates, then at runtime in order to\r
- * interpret @{} placeholders when object of scope execution are instantiated.\r
- */\r
-public class ExecutionParameterPostProcessor extends\r
- InstantiationAwareBeanPostProcessorAdapter {\r
-\r
- private final static Log log = LogFactory\r
- .getLog(ExecutionParameterPostProcessor.class);\r
-\r
- private ExecutionContext executionContext;\r
- private InstantiationManager instantiationManager;\r
-\r
- private String placeholderPrefix = "@{";\r
- private String placeholderSuffix = "}";\r
- private String nullValue;\r
-\r
- @Override\r
- public PropertyValues postProcessPropertyValues(PropertyValues pvs,\r
- PropertyDescriptor[] pds, Object bean, String beanName)\r
- throws BeansException {\r
-\r
- // TODO: resolve at execution only if scope is execution\r
- // TODO: deal with placeholders in RuntimeBeanReference and\r
- // RuntimeBeanNameReference\r
-\r
- MutablePropertyValues newPvs = new MutablePropertyValues();\r
-\r
- boolean changesOccured = false;\r
-\r
- for (PropertyValue pv : pvs.getPropertyValues()) {\r
- Object convertedValue = resolveValue(beanName, bean, pv.getValue());\r
- newPvs.addPropertyValue(new PropertyValue(pv, convertedValue));\r
- if (convertedValue != pv.getValue()) {\r
- changesOccured = true;\r
- }\r
- }\r
-\r
- return changesOccured ? newPvs : pvs;\r
- }\r
-\r
- @Override\r
- public boolean postProcessAfterInstantiation(Object bean, String beanName)\r
- throws BeansException {\r
- if (bean instanceof ExecutionFlow)\r
- instantiationManager.flowInitializationStarted(\r
- (ExecutionFlow) bean, beanName);\r
- return true;\r
- }\r
-\r
- @Override\r
- public Object postProcessAfterInitialization(Object bean, String beanName)\r
- throws BeansException {\r
- if (bean instanceof ExecutionFlow)\r
- instantiationManager.flowInitializationFinished(\r
- (ExecutionFlow) bean, beanName);\r
- return bean;\r
- }\r
-\r
- protected String resolvePlaceholder(Object bean, String placeholder) {\r
- if (instantiationManager.isInFlowInitialization())\r
- return instantiationManager.getInitializingFlowParameter(\r
- placeholder).toString();\r
-\r
- else {// execution\r
- // next call fail if no execution context available\r
- Object obj = executionContext.getVariable(placeholder);\r
- if (obj != null) {\r
- return obj.toString();\r
- }\r
- }\r
-\r
- return null;\r
- }\r
-\r
- @SuppressWarnings(value = { "unchecked" })\r
- public Object resolveValue(String beanName, Object bean, Object value) {\r
- if (value instanceof TypedStringValue) {\r
- TypedStringValue tsv = (TypedStringValue) value;\r
- String originalValue = tsv.getValue();\r
-\r
- String convertedValue = resolveString(beanName, bean, originalValue);\r
- if (convertedValue == null)\r
- return null;\r
- return convertedValue.equals(originalValue) ? value\r
- : new TypedStringValue(convertedValue);\r
- } else if (value instanceof String) {\r
- String originalValue = value.toString();\r
- String convertedValue = resolveString(beanName, bean, originalValue);\r
- if (convertedValue == null)\r
- return null;\r
- return convertedValue.equals(originalValue) ? value\r
- : convertedValue;\r
- } else if (value instanceof ManagedMap) {\r
- Map<?, ?> mapVal = (Map<?, ?>) value;\r
-\r
- Map<Object, Object> newContent = new ManagedMap();\r
- boolean entriesModified = false;\r
- for (Iterator<?> it = mapVal.entrySet().iterator(); it.hasNext();) {\r
- Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next();\r
- Object key = entry.getKey();\r
- int keyHash = (key != null ? key.hashCode() : 0);\r
- Object newKey = resolveValue(beanName, bean, key);\r
- int newKeyHash = (newKey != null ? newKey.hashCode() : 0);\r
- Object val = entry.getValue();\r
- Object newVal = resolveValue(beanName, bean, val);\r
- newContent.put(newKey, newVal);\r
- entriesModified = entriesModified\r
- || (newVal != val || newKey != key || newKeyHash != keyHash);\r
- }\r
-\r
- return entriesModified ? newContent : value;\r
- } else if (value instanceof ManagedList) {\r
- List<?> listVal = (List<?>) value;\r
- List<Object> newContent = new ManagedList();\r
- boolean valueModified = false;\r
-\r
- for (int i = 0; i < listVal.size(); i++) {\r
- Object elem = listVal.get(i);\r
- Object newVal = resolveValue(beanName, bean, elem);\r
- newContent.add(newVal);\r
- if (!ObjectUtils.nullSafeEquals(newVal, elem)) {\r
- valueModified = true;\r
- }\r
- }\r
- return valueModified ? newContent : value;\r
- } else if (value instanceof ManagedSet) {\r
- Set<?> setVal = (Set<?>) value;\r
- Set<Object> newContent = new ManagedSet();\r
- boolean entriesModified = false;\r
- for (Iterator<?> it = setVal.iterator(); it.hasNext();) {\r
- Object elem = it.next();\r
- int elemHash = (elem != null ? elem.hashCode() : 0);\r
- Object newVal = resolveValue(beanName, bean, elem);\r
- int newValHash = (newVal != null ? newVal.hashCode() : 0);\r
- newContent.add(newVal);\r
- entriesModified = entriesModified\r
- || (newVal != elem || newValHash != elemHash);\r
- }\r
- return entriesModified ? newContent : value;\r
- } else {\r
- // log.debug(beanName + ": " + value.getClass() + " : " + value);\r
- return value;\r
- }\r
-\r
- }\r
-\r
- private String resolveString(String beanName, Object bean, String strVal) {\r
- // in case <null/> is passed\r
- if (strVal == null)\r
- return null;\r
-\r
- String value = parseStringValue(bean, strVal, new HashSet<String>());\r
-\r
- if (value == null)\r
- throw new SlcException("Could not resolve placeholder '" + strVal\r
- + "' in bean '" + beanName + "'");\r
-\r
- return (value.equals(nullValue) ? null : value);\r
- }\r
-\r
- public void setPlaceholderPrefix(String placeholderPrefix) {\r
- this.placeholderPrefix = placeholderPrefix;\r
- }\r
-\r
- public void setPlaceholderSuffix(String placeholderSuffix) {\r
- this.placeholderSuffix = placeholderSuffix;\r
- }\r
-\r
- public void setNullValue(String nullValue) {\r
- this.nullValue = nullValue;\r
- }\r
-\r
- public void setInstantiationManager(\r
- InstantiationManager instantiationManager) {\r
- this.instantiationManager = instantiationManager;\r
- }\r
-\r
- public void setExecutionContext(ExecutionContext executionContext) {\r
- this.executionContext = executionContext;\r
- }\r
-\r
- //\r
- // Following methods hacked from the internals of\r
- // PropertyPlaceholderConfigurer\r
- //\r
-\r
- protected String parseStringValue(Object bean, String strVal,\r
- Set<String> visitedPlaceholders)\r
- throws BeanDefinitionStoreException {\r
-\r
- // in case <null/> is passed\r
- if (strVal == null)\r
- return null;\r
-\r
- StringBuffer buf = new StringBuffer(strVal);\r
-\r
- int startIndex = strVal.indexOf(placeholderPrefix);\r
- while (startIndex != -1) {\r
- int endIndex = findPlaceholderEndIndex(buf, startIndex);\r
- if (endIndex != -1) {\r
- String placeholder = buf.substring(startIndex\r
- + placeholderPrefix.length(), endIndex);\r
- if (!visitedPlaceholders.add(placeholder)) {\r
- throw new BeanDefinitionStoreException(\r
- "Circular placeholder reference '" + placeholder\r
- + "' in property definitions");\r
- }\r
- // Recursive invocation, parsing placeholders contained in\r
- // the placeholder key.\r
- placeholder = parseStringValue(bean, placeholder,\r
- visitedPlaceholders);\r
- // Now obtain the value for the fully resolved key...\r
- String propVal = resolvePlaceholder(bean, placeholder);\r
- if (propVal != null) {\r
- // Recursive invocation, parsing placeholders contained\r
- // in the\r
- // previously resolved placeholder value.\r
- propVal = parseStringValue(bean, propVal,\r
- visitedPlaceholders);\r
- buf.replace(startIndex,\r
- endIndex + placeholderSuffix.length(), propVal);\r
- if (log.isTraceEnabled()) {\r
- log.trace("Resolved placeholder '" + placeholder + "'");\r
- }\r
- startIndex = buf.indexOf(placeholderPrefix, startIndex\r
- + propVal.length());\r
- } else {\r
- throw new BeanDefinitionStoreException(\r
- "Could not resolve placeholder '" + placeholder\r
- + "'");\r
- }\r
- visitedPlaceholders.remove(placeholder);\r
- } else {\r
- startIndex = -1;\r
- }\r
- }\r
-\r
- return buf.toString();\r
- }\r
-\r
- private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {\r
- int index = startIndex + placeholderPrefix.length();\r
- int withinNestedPlaceholder = 0;\r
- while (index < buf.length()) {\r
- if (StringUtils.substringMatch(buf, index, placeholderSuffix)) {\r
- if (withinNestedPlaceholder > 0) {\r
- withinNestedPlaceholder--;\r
- index = index + placeholderSuffix.length();\r
- } else {\r
- return index;\r
- }\r
- } else if (StringUtils\r
- .substringMatch(buf, index, placeholderPrefix)) {\r
- withinNestedPlaceholder++;\r
- index = index + placeholderPrefix.length();\r
- } else {\r
- index++;\r
- }\r
- }\r
- return -1;\r
- }\r
-\r
-}\r
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-
-import org.springframework.core.io.Resource;
-
-/** Provides write access to resources during execution */
-public interface ExecutionResources {
- /** The base directory where this execution can write */
- public File getWritableBaseDir();
-
- /** Allocates a local file in the writable area and return it as a resource. */
- public Resource getWritableResource(String relativePath);
-
- /**
- * Allocates a local file in the writable area and return it as a fully
- * qualified OS path.
- */
- public String getWritableOsPath(String relativePath);
-
- /**
- * Allocates a local file in the writable area and return it as a
- * {@link File}.
- */
- public File getWritableOsFile(String relativePath);
-
- /**
- * Returns the resource as a file path. If the resource is not writable it
- * is copied as a file in the writable area and the path to this local file
- * is returned.
- */
- public String getAsOsPath(Resource resource, Boolean overwrite);
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.core.io.Resource;
-import org.springframework.util.Assert;
-
-/** Workaround when execution placedholders needs to be passed.*/
-public class ExecutionResourcesFactoryBean implements FactoryBean {
- private ExecutionResources executionResources;
- private String relativePath;
-
- public Object getObject() throws Exception {
- Assert.notNull(executionResources, "executionResources is null");
- Assert.notNull(relativePath, "relativePath is null");
- return executionResources.getWritableResource(relativePath);
- }
-
- public Class<? extends Object> getObjectType() {
- return Resource.class;
- }
-
- public boolean isSingleton() {
- return true;
- }
-
- public void setExecutionResources(ExecutionResources executionResources) {
- this.executionResources = executionResources;
- }
-
- public void setRelativePath(String relativePath) {
- this.relativePath = relativePath;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.UnsupportedException;
-import org.argeo.slc.execution.ExecutionContext;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionStack;
-import org.springframework.beans.factory.ObjectFactory;
-import org.springframework.beans.factory.config.Scope;
-
-/**
- * When Spring beans are instantiated with this scope, the same instance is
- * reused across an execution.
- */
-public class ExecutionScope implements Scope {
- private final static Log log = LogFactory.getLog(ExecutionScope.class);
-
- private final ThreadLocal<ExecutionStack> executionStack = new ThreadLocal<ExecutionStack>();
- public final ThreadLocal<String> executionStackBeanName = new ThreadLocal<String>();
-
- private final ThreadLocal<ExecutionContext> executionContext = new ThreadLocal<ExecutionContext>();
- private final ThreadLocal<String> executionContextBeanName = new ThreadLocal<String>();
-
- public Object get(String name, ObjectFactory objectFactory) {
- if (log.isTraceEnabled())
- log.debug("Get execution scoped bean " + name);
-
- // shortcuts
- if (executionStackBeanName.get() != null
- && name.equals(executionStackBeanName.get())) {
- return executionStack.get();
- }
-
- if (executionContextBeanName.get() != null
- && name.equals(executionContextBeanName.get())) {
- return executionContext.get();
- }
-
- // execution context must be defined first
- if (executionContext.get() == null) {
- Object obj = objectFactory.getObject();
- if (obj instanceof ExecutionContext) {
- return dealWithSpecialScopedObject(name, executionContext,
- executionContextBeanName, (ExecutionContext) obj);
- } else {
- // TODO: use execution context wrapper
- throw new SlcException("No execution context has been defined.");
- }
- }
-
- // for other scoped objects, an executions stack must be available
- if (executionStack.get() == null) {
- Object obj = objectFactory.getObject();
- if (obj instanceof ExecutionStack) {
- return dealWithSpecialScopedObject(name, executionStack,
- executionStackBeanName, (ExecutionStack) obj);
- } else {
- throw new SlcException("No execution stack has been defined.");
- }
- }
-
- // see if the execution stack already knows the object
- Object obj = executionStack.get().findScopedObject(name);
- if (obj == null) {
- obj = objectFactory.getObject();
- if (obj instanceof ExecutionContext)
- throw new SlcException(
- "Only one execution context can be defined per thread");
- if (obj instanceof ExecutionStack)
- throw new SlcException(
- "Only one execution stack can be defined per thread");
-
- checkForbiddenClasses(obj);
-
- executionStack.get().addScopedObject(name, obj);
- }
- return obj;
-
- }
-
- protected <T> T dealWithSpecialScopedObject(String name,
- ThreadLocal<T> threadLocal,
- ThreadLocal<String> threadLocalBeanName, T newObj) {
-
- T obj = threadLocal.get();
- if (obj == null) {
- obj = newObj;
- threadLocal.set(obj);
- threadLocalBeanName.set(name);
- if (log.isTraceEnabled()) {
- log.debug(obj.getClass() + " instantiated. (beanName=" + name
- + ")");
- }
- return obj;
- } else {
- throw new SlcException("Only one scoped " + obj.getClass()
- + " can be defined per thread");
- }
-
- }
-
- protected void checkForbiddenClasses(Object obj) {
- Class<?> clss = obj.getClass();
- if (ExecutionFlow.class.isAssignableFrom(clss)
- || ExecutionSpec.class.isAssignableFrom(clss)) {
- throw new UnsupportedException("Execution scoped object", clss);
- }
- }
-
- public String getConversationId() {
- // TODO: is it the most relevant?
- return executionContext.get().getUuid();
- }
-
- public void registerDestructionCallback(String name, Runnable callback) {
- if (Thread.currentThread() instanceof ExecutionThread) {
- ExecutionThread executionThread = (ExecutionThread) Thread
- .currentThread();
- executionThread.registerDestructionCallback(name, callback);
- }
- }
-
- public Object remove(String name) {
- if (log.isDebugEnabled())
- log.debug("Remove object " + name);
- throw new UnsupportedOperationException();
- }
-
- public Object resolveContextualObject(String key) {
- return executionContext.get().getVariable(key);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionFlowDescriptor;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.ExecutionStep;
-import org.argeo.slc.execution.RealizedFlow;
-import org.springframework.security.Authentication;
-import org.springframework.security.context.SecurityContextHolder;
-
-/** Thread of a single execution */
-public class ExecutionThread extends Thread {
- public final static String SYSPROP_EXECUTION_AUTO_UPGRADE = "slc.execution.autoupgrade";
- private final static Log log = LogFactory.getLog(ExecutionThread.class);
-
- private ExecutionModulesManager executionModulesManager;
- private final RealizedFlow realizedFlow;
-
- private List<Runnable> destructionCallbacks = new ArrayList<Runnable>();
-
- public ExecutionThread(ProcessThreadGroup processThreadGroup,
- ExecutionModulesManager executionModulesManager,
- RealizedFlow realizedFlow) {
- super(processThreadGroup, "Flow "
- + realizedFlow.getFlowDescriptor().getName());
- this.realizedFlow = realizedFlow;
- this.executionModulesManager = executionModulesManager;
- }
-
- public void run() {
- // authenticate thread
- Authentication authentication = getProcessThreadGroup()
- .getAuthentication();
- if (authentication == null)
- throw new SlcException("Can only execute authenticated threads");
- SecurityContextHolder.getContext().setAuthentication(authentication);
-
- // Retrieve execution flow descriptor
- ExecutionFlowDescriptor executionFlowDescriptor = realizedFlow
- .getFlowDescriptor();
- String flowName = executionFlowDescriptor.getName();
-
- getProcessThreadGroup().dispatchAddStep(
- new ExecutionStep(realizedFlow.getModuleName(),
- ExecutionStep.PHASE_START, "Flow " + flowName));
-
- try {
- String autoUpgrade = System
- .getProperty(SYSPROP_EXECUTION_AUTO_UPGRADE);
- if (autoUpgrade != null && autoUpgrade.equals("true"))
- executionModulesManager.upgrade(realizedFlow
- .getModuleNameVersion());
- executionModulesManager.start(realizedFlow.getModuleNameVersion());
- //
- // START FLOW
- //
- executionModulesManager.execute(realizedFlow);
- // END FLOW
- } catch (FlowConfigurationException e) {
- String msg = "Configuration problem with flow " + flowName + ":\n"
- + e.getMessage();
- log.error(msg);
- getProcessThreadGroup().dispatchAddStep(
- new ExecutionStep(realizedFlow.getModuleName(),
- ExecutionStep.ERROR, msg + " " + e.getMessage()));
- } catch (Exception e) {
- // TODO: re-throw exception ?
- String msg = "Execution of flow " + flowName + " failed.";
- log.error(msg, e);
- getProcessThreadGroup().dispatchAddStep(
- new ExecutionStep(realizedFlow.getModuleName(),
- ExecutionStep.ERROR, msg + " " + e.getMessage()));
- } finally {
- getProcessThreadGroup().dispatchAddStep(
- new ExecutionStep(realizedFlow.getModuleName(),
- ExecutionStep.PHASE_END, "Flow " + flowName));
- processDestructionCallbacks();
- }
- }
-
- private synchronized void processDestructionCallbacks() {
- for (int i = destructionCallbacks.size() - 1; i >= 0; i--) {
- try {
- destructionCallbacks.get(i).run();
- } catch (Exception e) {
- log.warn("Could not process destruction callback " + i
- + " in thread " + getName(), e);
- }
- }
- }
-
- /**
- * Gather object destruction callback to be called in reverse order at the
- * end of the thread
- */
- synchronized void registerDestructionCallback(String name, Runnable callback) {
- destructionCallbacks.add(callback);
- }
-
- protected ProcessThreadGroup getProcessThreadGroup() {
- return (ProcessThreadGroup) getThreadGroup();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionContext;
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.core.io.Resource;
-import org.springframework.util.Assert;
-
-/** Implements write access to resources based on standard Java {@link File} */
-public class FileExecutionResources implements ExecutionResources {
- private final static Log log = LogFactory
- .getLog(FileExecutionResources.class);
- protected final static String DEFAULT_EXECUTION_RESOURCES_DIRNAME = "executionResources";
- public final static String DEFAULT_EXECUTION_RESOURCES_TMP_PATH = System
- .getProperty("java.io.tmpdir")
- + File.separator
- + System.getProperty("user.name")
- + File.separator
- + "slc"
- + File.separator + DEFAULT_EXECUTION_RESOURCES_DIRNAME;
-
- private File baseDir;
- private ExecutionContext executionContext;
- private String prefixDatePattern = "yyMMdd_HHmmss_SSS";
- private SimpleDateFormat sdf = null;
-
- private Boolean withExecutionSubdirectory = true;
-
- public FileExecutionResources() {
- // Default base directory
- String osgiInstanceArea = System.getProperty("osgi.instance.area");
- String osgiInstanceAreaDefault = System
- .getProperty("osgi.instance.area.default");
-
- if (osgiInstanceArea != null) {
- // within OSGi with -data specified
- osgiInstanceArea = removeFilePrefix(osgiInstanceArea);
- baseDir = new File(osgiInstanceArea + File.separator
- + DEFAULT_EXECUTION_RESOURCES_DIRNAME);
- } else if (osgiInstanceAreaDefault != null) {
- // within OSGi without -data specified
- osgiInstanceAreaDefault = removeFilePrefix(osgiInstanceAreaDefault);
- baseDir = new File(osgiInstanceAreaDefault + File.separator
- + DEFAULT_EXECUTION_RESOURCES_DIRNAME);
- } else {// outside OSGi
- baseDir = new File(DEFAULT_EXECUTION_RESOURCES_TMP_PATH);
- }
- }
-
- protected SimpleDateFormat sdf() {
- // Lazy init in case prefix has been externally set
- if (sdf == null)
- sdf = new SimpleDateFormat(prefixDatePattern);
- return sdf;
- }
-
- public Resource getWritableResource(String relativePath) {
- File file = getFile(relativePath);
- File parentDir = file.getParentFile();
-
- if (!parentDir.exists()) {
- // Creates if necessary
- if (log.isTraceEnabled())
- log.trace("Creating parent directory " + parentDir);
- parentDir.mkdirs();
- }
- Resource resource = new FileSystemResource(file);
-
- if (log.isTraceEnabled())
- log.trace("Returns writable resource " + resource);
- return resource;
- }
-
- public String getWritableOsPath(String relativePath) {
- try {
- return getFile(relativePath).getCanonicalPath();
- } catch (IOException e) {
- throw new SlcException("Cannot find canonical path", e);
- }
- }
-
- public File getWritableOsFile(String relativePath) {
- return getFile(relativePath);
- }
-
- public String getAsOsPath(Resource resource, Boolean overwrite) {
- File file = fileFromResource(resource);
- if (file != null)
- try {
- if (log.isTraceEnabled())
- log.debug("Directly interpret " + resource + " as OS file "
- + file);
- return file.getCanonicalPath();
- } catch (IOException e1) {
- // silent
- }
-
- if (log.isTraceEnabled())
- log.trace("Resource " + resource
- + " is not available on the file system. Retrieving it...");
-
- InputStream in = null;
- OutputStream out = null;
- try {
- String path = resource.getURL().getPath();
- file = getFile(path);
- if (file.exists() && !overwrite)
- return file.getCanonicalPath();
-
- file.getParentFile().mkdirs();
- in = resource.getInputStream();
- out = new FileOutputStream(file);
- IOUtils.copy(in, out);
- if (log.isDebugEnabled())
- log.debug("Retrieved " + resource + " to OS file " + file);
- return file.getCanonicalPath();
- } catch (IOException e) {
- throw new SlcException("Could not make resource " + resource
- + " an OS file.", e);
- } finally {
- IOUtils.closeQuietly(in);
- IOUtils.closeQuietly(out);
- }
- }
-
- /**
- * Extract the underlying file from the resource.
- *
- * @return the file or null if no files support this resource.
- */
- protected File fileFromResource(Resource resource) {
- try {
- return resource.getFile();
- } catch (IOException e) {
- return null;
- }
-
- }
-
- protected File getFile(String relativePath) {
- File writableBaseDir = getWritableBaseDir();
- return new File(writableBaseDir.getPath() + File.separator
- + relativePath.replace('/', File.separatorChar));
- }
-
- public File getWritableBaseDir() {
- if (withExecutionSubdirectory) {
- Date executionContextCreationDate = (Date) executionContext
- .getVariable(ExecutionContext.VAR_EXECUTION_CONTEXT_CREATION_DATE);
- Assert.notNull(executionContext, "execution context is null");
- String path = baseDir.getPath() + File.separator
- + sdf().format(executionContextCreationDate);
- // TODO write execution id somewhere? like in a txt file
- return new File(path);
- } else {
- return baseDir;
- }
- }
-
- protected String removeFilePrefix(String url) {
- if (url.startsWith("file:"))
- return url.substring("file:".length());
- else if (url.startsWith("reference:file:"))
- return url.substring("reference:file:".length());
- else
- return url;
- }
-
- public void setBaseDir(File baseDir) {
- this.baseDir = baseDir;
- }
-
- public void setExecutionContext(ExecutionContext executionContext) {
- this.executionContext = executionContext;
- }
-
- public void setPrefixDatePattern(String prefixDatePattern) {
- this.prefixDatePattern = prefixDatePattern;
- }
-
- public File getBaseDir() {
- return baseDir;
- }
-
- public ExecutionContext getExecutionContext() {
- return executionContext;
- }
-
- public String getPrefixDatePattern() {
- return prefixDatePattern;
- }
-
- /** Default is true. */
- public void setWithExecutionSubdirectory(Boolean withExecutionSubdirectory) {
- this.withExecutionSubdirectory = withExecutionSubdirectory;
- }
-
-}
+++ /dev/null
-package org.argeo.slc.core.execution;
-
-import org.argeo.slc.SlcException;
-
-/** The stack trace of such exceptions does not need to be displayed */
-public class FlowConfigurationException extends SlcException {
- private static final long serialVersionUID = 8456260596346797321L;
-
- public FlowConfigurationException(String message) {
- super(message);
- }
-}
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution;\r
-\r
-import java.util.Stack;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.execution.ExecutionFlow;\r
-import org.argeo.slc.execution.ExecutionSpecAttribute;\r
-\r
-/** Manage parameters that need to be set during the instantiation of a flow */\r
-public class InstantiationManager {\r
-\r
- private final static Log log = LogFactory\r
- .getLog(InstantiationManager.class);\r
-\r
- private ThreadLocal<Stack<ExecutionFlow>> flowStack = new ThreadLocal<Stack<ExecutionFlow>>();\r
-\r
- public Object createRef(String name) {\r
-\r
- if ((flowStack.get() == null) || flowStack.get().empty()) {\r
- throw new SlcException("No flow is currently initializing."\r
- + " Declare ParameterRef as inner beans or prototypes.");\r
- }\r
-\r
- return getInitializingFlowParameter(name);\r
- }\r
-\r
- public void flowInitializationStarted(ExecutionFlow flow, String flowName) {\r
- // set the flow name if it is DefaultExecutionFlow\r
- if (flow instanceof DefaultExecutionFlow) {\r
- ((DefaultExecutionFlow) flow).setBeanName(flowName);\r
- }\r
-\r
- if (log.isTraceEnabled())\r
- log.trace("Start initialization of " + flow.hashCode() + " ("\r
- + flow + " - " + flow.getClass() + ")");\r
-\r
- // log.info("# flowInitializationStarted " + flowName);\r
- // create a stack for this thread if there is none\r
- if (flowStack.get() == null) {\r
- flowStack.set(new Stack<ExecutionFlow>());\r
- }\r
- flowStack.get().push(flow);\r
- }\r
-\r
- public void flowInitializationFinished(ExecutionFlow flow, String flowName) {\r
- if (log.isTraceEnabled())\r
- log.trace("Finish initialization of " + flow.hashCode() + " ("\r
- + flow + " - " + flow.getClass() + ")");\r
-\r
- if (flowStack.get() != null) {\r
- ExecutionFlow registeredFlow = flowStack.get().pop();\r
- if (registeredFlow != null) {\r
- if (!flow.getName().equals(registeredFlow.getName()))\r
- throw new SlcException("Current flow is " + flow);\r
- // log.info("# flowInitializationFinished " + flowName);\r
- // initializingFlow.set(null);\r
- }\r
- } else {\r
- // happens for flows imported as services\r
- log.warn("flowInitializationFinished - Flow Stack is null");\r
- }\r
- }\r
-\r
- protected ExecutionFlow findInitializingFlowWithParameter(String key) {\r
- if ((flowStack.get() == null) || flowStack.get().empty())\r
- throw new SlcException("No initializing flow available.");\r
-\r
- // first look in the outer flow (that may override parameters)\r
- for (int i = 0; i < flowStack.get().size(); i++) {\r
- if (flowStack.get().elementAt(i).isSetAsParameter(key)) {\r
- return flowStack.get().elementAt(i);\r
- }\r
- }\r
- throw new SlcException("Key " + key + " is not set as parameter in "\r
- + flowStack.get().firstElement().toString() + " (stack size="\r
- + flowStack.get().size() + ")");\r
-\r
- }\r
-\r
- public Object getInitializingFlowParameter(String key) {\r
- return findInitializingFlowWithParameter(key).getParameter(key);\r
- }\r
-\r
- public Class<?> getInitializingFlowParameterClass(String key) {\r
- ExecutionSpecAttribute attr = findInitializingFlowWithParameter(key)\r
- .getExecutionSpec().getAttributes().get(key);\r
- if (attr instanceof RefSpecAttribute)\r
- return ((RefSpecAttribute) attr).getTargetClass();\r
- else if (attr instanceof PrimitiveSpecAttribute) {\r
- String type = ((PrimitiveSpecAttribute) attr).getType();\r
- Class<?> clss = PrimitiveUtils.typeAsClass(type);\r
- if (clss == null)\r
- throw new SlcException("Cannot convert type " + type\r
- + " to class.");\r
- return clss;\r
- } else\r
- return null;\r
- }\r
-\r
- public Boolean isInFlowInitialization() {\r
- return (flowStack.get() != null) && !flowStack.get().empty();\r
- }\r
-}\r
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionContext;
-import org.springframework.beans.BeanWrapper;
-import org.springframework.beans.BeanWrapperImpl;
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-
-public class MapExecutionContext implements ExecutionContext,
- ApplicationContextAware {
- private final Map<String, Object> variables = Collections
- .synchronizedMap(new HashMap<String, Object>());
-
- private final String uuid;
-
- private ApplicationContext applicationContext;
-
- public MapExecutionContext() {
- uuid = UUID.randomUUID().toString();
- variables.put(VAR_EXECUTION_CONTEXT_ID, uuid);
- variables.put(VAR_EXECUTION_CONTEXT_CREATION_DATE, new Date());
- }
-
- public void setVariable(String key, Object value) {
- // check if we do not refer to a bean
- int lastInd = key.lastIndexOf('.');
- if (applicationContext != null && lastInd > 0) {
- String beanName = key.substring(0, lastInd);
- String propertyName = key.substring(lastInd + 1);
- if (applicationContext.containsBean(beanName)) {
- BeanWrapper beanWrapper = new BeanWrapperImpl(
- applicationContext.getBean(beanName));
- if (!beanWrapper.isWritableProperty(propertyName))
- throw new SlcException("No writable property "
- + propertyName + " in bean " + beanName);
- beanWrapper.setPropertyValue(propertyName, value);
- }
- }
-
- variables.put(key, value);
- }
-
- public Object getVariable(String key) {
- // check if we do not refer to a bean
- int lastInd = key.lastIndexOf('.');
- if (applicationContext != null && lastInd > 0) {
- String beanName = key.substring(0, lastInd);
- String propertyName = key.substring(lastInd + 1);
- if (applicationContext.containsBean(beanName)) {
- BeanWrapper beanWrapper = new BeanWrapperImpl(
- applicationContext.getBean(beanName));
- if (!beanWrapper.isReadableProperty(propertyName))
- throw new SlcException("No readable property "
- + propertyName + " in bean " + beanName);
- Object obj = beanWrapper.getPropertyValue(propertyName);
- return obj;
- }
- }
-
- Object value = variables.get(key);
- // try system property in last resort
- if (value == null)
- value = System.getProperty(key);
- return value;
- }
-
- public String getUuid() {
- return uuid;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof ExecutionContext)
- return uuid.equals(((ExecutionContext) obj).getUuid());
- return false;
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName() + "#" + uuid;
- }
-
- public void setApplicationContext(ApplicationContext applicationContext)
- throws BeansException {
- this.applicationContext = applicationContext;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.core.io.Resource;
-import org.springframework.util.Assert;
-
-/** Retrieve an OS File from the given resource. */
-public class OsFileFactoryBean implements FactoryBean {
- private ExecutionResources executionResources;
- private Resource resource;
- private Boolean overwrite = false;
-
- /** Return an existing file on the file system. */
- public Object getObject() throws Exception {
- Assert.notNull(executionResources, "executionResources is null");
- Assert.notNull(resource, "resource is null");
- return executionResources.getAsOsPath(resource, overwrite);
- }
-
- /** Return {@link Object} because CGLIB is unable to proxy {@link File}.*/
- public Class<? extends Object> getObjectType() {
- return CharSequence.class;
- }
-
- public boolean isSingleton() {
- return false;
- }
-
- /** The execution resources object. */
- public void setExecutionResources(ExecutionResources executionResources) {
- this.executionResources = executionResources;
- }
-
- /** The resource to access. */
- public void setResource(Resource resource) {
- this.resource = resource;
- }
-
- /**
- * Whether to overwrite the resource if it already exists. Default is
- * <code>false</code>.
- */
- public void setOverwrite(Boolean overwrite) {
- this.overwrite = overwrite;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.FactoryBean;
-
-public class ParameterRef implements FactoryBean {
- private final static Log log = LogFactory.getLog(ParameterRef.class);
-
- private InstantiationManager instantiationManager;
- private String name;
-
- /** Cached object. */
- private Object object;
-
- public ParameterRef() {
- }
-
- public ParameterRef(String name) {
- this.name = name;
- }
-
- public Object getObject() throws Exception {
- if (log.isTraceEnabled())
- log.debug("Parameter ref called for " + name);
-
- if (object == null)
- object = instantiationManager.getInitializingFlowParameter(name);
- return object;
- }
-
- public Class<?> getObjectType() {
- if (object == null)
- return instantiationManager.getInitializingFlowParameterClass(name);
- else
- return object.getClass();
- }
-
- public boolean isSingleton() {
- return true;
- }
-
- public void setInstantiationManager(
- InstantiationManager instantiationManager) {
- this.instantiationManager = instantiationManager;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-/** Abstraction of access to primitive values */
-public interface PrimitiveAccessor {
- public final static String TYPE_STRING = "string";
- /**
- * As of Argeo 1, passwords are NOT stored encrypted, just hidden in the UI,
- * but stored in plain text in JCR. Use keyring instead.
- */
- public final static String TYPE_PASSWORD = "password";
- public final static String TYPE_INTEGER = "integer";
- public final static String TYPE_LONG = "long";
- public final static String TYPE_FLOAT = "float";
- public final static String TYPE_DOUBLE = "double";
- public final static String TYPE_BOOLEAN = "boolean";
-
- public String getType();
-
- public Object getValue();
-
- public void setValue(Object value);
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.argeo.slc.SlcException;
-
-/**
- * A spec attribute wrapping a primitive value.
- *
- * @see PrimitiveAccessor
- */
-public class PrimitiveSpecAttribute extends AbstractSpecAttribute implements
- PrimitiveAccessor {
- private static final long serialVersionUID = -566676381839825483L;
- private String type = "string";
- private Object value = null;
-
- public PrimitiveSpecAttribute() {
- }
-
- public PrimitiveSpecAttribute(String type, Object value) {
- this.type = type;
- this.value = value;
- }
-
- public Object getValue() {
- return value;
- }
-
- public void setValue(Object value) {
- this.value = value;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- // check whether type is recognized.
- if (PrimitiveUtils.typeAsClass(type) == null)
- throw new SlcException("Unrecognized type " + type);
- this.type = type;
-
- }
-
- @Override
- public String toString() {
- return "Primitive spec attribute [" + type + "]"
- + (value != null ? "=" + value : "");
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-/** Converts to and from primitive types. */
-public class PrimitiveUtils {
- /**
- * @deprecated Use {@link PrimitiveAccessor#TYPE_STRING} instead
- */
- public final static String TYPE_STRING = PrimitiveAccessor.TYPE_STRING;
- /**
- * @deprecated Use {@link PrimitiveAccessor#TYPE_INTEGER} instead
- */
- public final static String TYPE_INTEGER = PrimitiveAccessor.TYPE_INTEGER;
- /**
- * @deprecated Use {@link PrimitiveAccessor#TYPE_LONG} instead
- */
- public final static String TYPE_LONG = PrimitiveAccessor.TYPE_LONG;
- /**
- * @deprecated Use {@link PrimitiveAccessor#TYPE_FLOAT} instead
- */
- public final static String TYPE_FLOAT = PrimitiveAccessor.TYPE_FLOAT;
- /**
- * @deprecated Use {@link PrimitiveAccessor#TYPE_DOUBLE} instead
- */
- public final static String TYPE_DOUBLE = PrimitiveAccessor.TYPE_DOUBLE;
- /**
- * @deprecated Use {@link PrimitiveAccessor#TYPE_BOOLEAN} instead
- */
- public final static String TYPE_BOOLEAN = PrimitiveAccessor.TYPE_BOOLEAN;
-
- private PrimitiveUtils() {
-
- }
-
- /** @return the class or null if the provided type is not a primitive */
- public static Class<?> typeAsClass(String type) {
- if (PrimitiveAccessor.TYPE_STRING.equals(type))
- return String.class;
- else if (PrimitiveAccessor.TYPE_PASSWORD.equals(type))
- return char[].class;
- else if (PrimitiveAccessor.TYPE_INTEGER.equals(type))
- return Integer.class;
- else if (PrimitiveAccessor.TYPE_LONG.equals(type))
- return Long.class;
- else if (PrimitiveAccessor.TYPE_FLOAT.equals(type))
- return Float.class;
- else if (PrimitiveAccessor.TYPE_DOUBLE.equals(type))
- return Double.class;
- else if (PrimitiveAccessor.TYPE_BOOLEAN.equals(type))
- return Boolean.class;
- else
- return null;
- }
-
- /** @return the type or null if the provided class is not a primitive */
- public static String classAsType(Class<?> clss) {
- if (String.class.isAssignableFrom(clss))
- return PrimitiveAccessor.TYPE_STRING;
- else if (char[].class.isAssignableFrom(clss))
- return PrimitiveAccessor.TYPE_PASSWORD;
- else if (Integer.class.isAssignableFrom(clss))
- return PrimitiveAccessor.TYPE_INTEGER;
- else if (Long.class.isAssignableFrom(clss))
- return PrimitiveAccessor.TYPE_LONG;
- else if (Float.class.isAssignableFrom(clss))
- return PrimitiveAccessor.TYPE_FLOAT;
- else if (Double.class.isAssignableFrom(clss))
- return PrimitiveAccessor.TYPE_DOUBLE;
- else if (Boolean.class.isAssignableFrom(clss))
- return PrimitiveAccessor.TYPE_BOOLEAN;
- else
- return null;
- }
-
- /** Parse string as an object. Passwords are returned as String.*/
- public static Object convert(String type, String str) {
- if (PrimitiveAccessor.TYPE_STRING.equals(type)) {
- return str;
- } else if (PrimitiveAccessor.TYPE_PASSWORD.equals(type)) {
- return str;
- } else if (PrimitiveAccessor.TYPE_INTEGER.equals(type)) {
- return (Integer.parseInt(str));
- } else if (PrimitiveAccessor.TYPE_LONG.equals(type)) {
- return (Long.parseLong(str));
- } else if (PrimitiveAccessor.TYPE_FLOAT.equals(type)) {
- return (Float.parseFloat(str));
- } else if (PrimitiveAccessor.TYPE_DOUBLE.equals(type)) {
- return (Double.parseDouble(str));
- } else if (PrimitiveAccessor.TYPE_BOOLEAN.equals(type)) {
- return (Boolean.parseBoolean(str));
- } else {
- return str;
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-/** Primitive value to be used by an execution. */
-public class PrimitiveValue extends AbstractExecutionValue implements
- PrimitiveAccessor {
- private static final long serialVersionUID = 533414290998374166L;
-
- private String type;
-
- private Object value;
-
- public PrimitiveValue() {
- }
-
- public PrimitiveValue(String type, Object value) {
- super();
- this.type = type;
- this.value = value;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public Object getValue() {
- return value;
- }
-
- public void setValue(Object value) {
- this.value = value;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.ExecutionProcess;
-import org.argeo.slc.execution.ExecutionStep;
-import org.argeo.slc.execution.RealizedFlow;
-import org.springframework.security.Authentication;
-import org.springframework.security.context.SecurityContextHolder;
-
-/**
- * Main thread coordinating an {@link ExecutionProcess}, launching parallel or
- * sequential {@link ExecutionThread}s.
- */
-public class ProcessThread extends Thread {
- private final static Log log = LogFactory.getLog(ProcessThread.class);
-
- private final ExecutionModulesManager executionModulesManager;
- private final ExecutionProcess process;
- private final ProcessThreadGroup processThreadGroup;
-
- private Set<ExecutionThread> executionThreads = Collections
- .synchronizedSet(new HashSet<ExecutionThread>());
-
- // private Boolean hadAnError = false;
- private Boolean killed = false;
-
- public ProcessThread(ThreadGroup processesThreadGroup,
- ExecutionModulesManager executionModulesManager,
- ExecutionProcess process) {
- super(processesThreadGroup, "SLC Process #" + process.getUuid());
- this.executionModulesManager = executionModulesManager;
- this.process = process;
- processThreadGroup = new ProcessThreadGroup(process);
- }
-
- public final void run() {
- // authenticate thread
- Authentication authentication = getProcessThreadGroup()
- .getAuthentication();
- if (authentication == null)
- throw new SlcException("Can only execute authenticated threads");
- SecurityContextHolder.getContext().setAuthentication(authentication);
-
- log.info("\n##\n## SLC Process #" + process.getUuid()
- + " STARTED\n##\n");
-
- // Start logging
- new LoggingThread().start();
-
- process.setStatus(ExecutionProcess.RUNNING);
- try {
- process();
- } catch (InterruptedException e) {
- die();
- return;
- } catch (Exception e) {
- String msg = "Process " + getProcess().getUuid()
- + " failed unexpectedly.";
- log.error(msg, e);
- getProcessThreadGroup().dispatchAddStep(
- new ExecutionStep("Process", ExecutionStep.ERROR, msg + " "
- + e.getMessage()));
- }
-
- // waits for all execution threads to complete (in case they were
- // started asynchronously)
- for (ExecutionThread executionThread : executionThreads) {
- if (executionThread.isAlive()) {
- try {
- executionThread.join();
- } catch (InterruptedException e) {
- die();
- return;
- }
- }
- }
-
- computeFinalStatus();
- }
-
- /** Make sure this is called BEFORE all the threads are interrupted. */
- private void computeFinalStatus() {
- // String oldStatus = process.getStatus();
- // TODO: error management at flow level?
- if (killed)
- process.setStatus(ExecutionProcess.KILLED);
- else if (processThreadGroup.hadAnError())
- process.setStatus(ExecutionProcess.ERROR);
- else
- process.setStatus(ExecutionProcess.COMPLETED);
- // executionModulesManager.dispatchUpdateStatus(process, oldStatus,
- // process.getStatus());
- log.info("\n## SLC Process #" + process.getUuid() + " "
- + process.getStatus() + "\n");
- }
-
- /** Called when being killed */
- private synchronized void die() {
- killed = true;
- computeFinalStatus();
- for (ExecutionThread executionThread : executionThreads) {
- try {
- executionThread.interrupt();
- } catch (Exception e) {
- log.error("Cannot interrupt " + executionThread);
- }
- }
- processThreadGroup.interrupt();
- }
-
- /**
- * Implementation specific execution. To be overridden in order to deal with
- * custom process types. Default expects an {@link SlcExecution}.
- */
- protected void process() throws InterruptedException {
- List<RealizedFlow> flowsToProcess = new ArrayList<RealizedFlow>();
- flowsToProcess.addAll(process.getRealizedFlows());
- while (flowsToProcess.size() > 0) {
- RealizedFlow realizedFlow = flowsToProcess.remove(0);
- execute(realizedFlow, true);
- }
- }
-
- /** @return the (distinct) thread used for this execution */
- protected final void execute(RealizedFlow realizedFlow, Boolean synchronous)
- throws InterruptedException {
- if (killed)
- return;
-
- ExecutionThread thread = new ExecutionThread(processThreadGroup,
- executionModulesManager, realizedFlow);
- executionThreads.add(thread);
- thread.start();
-
- if (synchronous)
- thread.join();
-
- return;
- }
-
- // public void notifyError() {
- // hadAnError = true;
- // }
- //
- // public synchronized void flowCompleted() {
- // // notifyAll();
- // }
-
- public ExecutionProcess getProcess() {
- return process;
- }
-
- public ProcessThreadGroup getProcessThreadGroup() {
- return processThreadGroup;
- }
-
- public ExecutionModulesManager getExecutionModulesManager() {
- return executionModulesManager;
- }
-
- private class LoggingThread extends Thread {
-
- public LoggingThread() {
- super("SLC Process Logger #" + process.getUuid());
- }
-
- public void run() {
- boolean run = true;
- while (run) {
- List<ExecutionStep> newSteps = new ArrayList<ExecutionStep>();
- processThreadGroup.getSteps().drainTo(newSteps);
- if (newSteps.size() > 0) {
- // System.out.println(steps.size() + " steps");
- process.addSteps(newSteps);
- }
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- break;
- }
-
- if (!ProcessThread.this.isAlive()
- && processThreadGroup.getSteps().size() == 0)
- run = false;
- }
- }
-
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-
-import org.argeo.slc.execution.ExecutionProcess;
-import org.argeo.slc.execution.ExecutionStep;
-import org.springframework.security.Authentication;
-import org.springframework.security.context.SecurityContextHolder;
-
-/** The thread group attached to a given {@link SlcExecution}. */
-public class ProcessThreadGroup extends ThreadGroup {
- // private final ExecutionModulesManager executionModulesManager;
- // private final ProcessThread processThread;
- private final Authentication authentication;
- private final static Integer STEPS_BUFFER_CAPACITY = 5000;
-
- private BlockingQueue<ExecutionStep> steps = new ArrayBlockingQueue<ExecutionStep>(
- STEPS_BUFFER_CAPACITY);
-
- private Boolean hadAnError = false;
-
- public ProcessThreadGroup(ExecutionProcess executionProcess) {
- super("SLC Process #" + executionProcess.getUuid() + " thread group");
- // this.executionModulesManager = executionModulesManager;
- // this.processThread = processThread;
- this.authentication = SecurityContextHolder.getContext()
- .getAuthentication();
- }
-
- public Authentication getAuthentication() {
- return authentication;
- }
-
- public void dispatchAddStep(ExecutionStep step) {
- // ExecutionProcess slcProcess = processThread.getProcess();
- // List<ExecutionStep> steps = new ArrayList<ExecutionStep>();
- // steps.add(step);
- // TODO clarify why we don't dispatch steps, must be a reason
- // dispatchAddSteps(steps);
- // slcProcess.addSteps(steps);
- if (step.getType().equals(ExecutionStep.ERROR))
- hadAnError = true;
- this.steps.add(step);
- }
-
- // public void dispatchAddSteps(List<ExecutionStep> steps) {
- // ExecutionProcess slcProcess = processThread.getProcess();
- // executionModulesManager.dispatchAddSteps(slcProcess, steps);
- // }
-
- public BlockingQueue<ExecutionStep> getSteps() {
- return steps;
- }
-
- public Boolean hadAnError() {
- return hadAnError;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.util.List;
-
-/** A spec attribute whose value is a reference to a full fledged object. */
-public class RefSpecAttribute extends AbstractSpecAttribute implements
- Cloneable {
- private static final long serialVersionUID = -3427797452955753574L;
- private transient Class<?> targetClass = String.class;
- /** Read only. */
- private String targetClassName;
- private transient Object value = null;
-
- /** List to be chosen from */
- private List<RefValueChoice> choices = null;
-
- public Object getValue() {
- return value;
- }
-
- public void setValue(Object value) {
- this.value = value;
- }
-
- /** Default is {@link String} */
- public Class<?> getTargetClass() {
- return targetClass;
- }
-
- public void setTargetClass(Class<?> targetClass) {
- this.targetClass = targetClass;
- this.targetClassName = targetClass.getName();
- }
-
- public String getTargetClassName() {
- return targetClassName;
- }
-
- /** @return can be null */
- public List<RefValueChoice> getChoices() {
- return choices;
- }
-
- public void setChoices(List<RefValueChoice> choices) {
- this.choices = choices;
- }
-
- @Override
- protected Object clone() throws CloneNotSupportedException {
- RefSpecAttribute rsa = new RefSpecAttribute();
- rsa.setTargetClass(targetClass);
- rsa.setChoices(choices);
- return rsa;
- }
-
- @Override
- public String toString() {
- return "Ref spec attribute [" + targetClass + "]"
- + (value != null ? "=" + value : "");
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-/** Reference value to be used by an execution */
-public class RefValue extends AbstractExecutionValue {
- private static final long serialVersionUID = -8951231456757181687L;
- private String ref;
- private String type;
-
- public RefValue() {
- }
-
- public RefValue(String ref) {
- super();
- this.ref = ref;
- }
-
- public String getRef() {
- return ref;
- }
-
- public void setRef(String ref) {
- this.ref = ref;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- @Override
- public String toString() {
- return "Ref Value [" + type + "=" + ref + "]";
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.Serializable;
-
-/** A choice of ref value to be shown to the end user. */
-public class RefValueChoice implements Serializable {
- private static final long serialVersionUID = -1133645722307507774L;
- private String name;
- private String description;
-
- public RefValueChoice() {
- }
-
- public RefValueChoice(String name, String description) {
- this.name = name;
- this.description = description;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.core.io.ByteArrayResource;
-import org.springframework.core.io.Resource;
-
-/** Experimental and suboptimal */
-public class SedFilteredResource implements FactoryBean, InitializingBean {
- private Resource source;
-
- private List<String> filters = new ArrayList<String>();
- private Map<Pattern, String> patterns = new HashMap<Pattern, String>();
-
- private String charset = "UTF-8";
- private Charset cs;
- private CharsetDecoder decoder;
-
- // private CharsetEncoder encoder;
-
- public Object getObject() throws Exception {
- if (filters.size() == 0)
- return source;
-
- // int capacity = 100 * 1024;// 100 KB
- ByteBuffer bb;
- if (source instanceof ByteArrayResource) {
- bb = ByteBuffer.wrap(((ByteArrayResource) source).getByteArray());
- } else {
- FileInputStream fis = null;
- try {
- File file = source.getFile();
- fis = new FileInputStream(file);
- FileChannel fc = fis.getChannel();
-
- // Get the file's size and then map it into memory
- int sz = (int) fc.size();
- bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
- } catch (IOException e) {
- // ReadableByteChannel channel = Channels.newChannel(source
- // .getInputStream());
- // bb = ByteBuffer.allocateDirect(capacity);
- // int read = 0;
- // do {
- // read = channel.read(bb);
- // } while (read > 0);
- // FIXME : use nio to parse the stream as it goes
- bb = ByteBuffer.wrap(IOUtils.toByteArray(source
- .getInputStream()));
- } finally {
- IOUtils.closeQuietly(fis);
- }
- }
- CharBuffer cb = decoder.decode(bb);
- for (Pattern pattern : patterns.keySet()) {
- Matcher matcher = pattern.matcher(cb);
- String output = matcher.replaceAll(patterns.get(pattern));
- cb = CharBuffer.wrap(output);
- }
- // ByteBuffer bbout = encoder.encode(cb);
- // ByteArrayOutputStream out = new ByteArrayOutputStream(capacity);
- // WritableByteChannel wchannel = Channels.newChannel(out);
- // wchannel.write(bbout);
- ByteArrayResource res = new ByteArrayResource(cb.toString().getBytes());
- return res;
- }
-
- public Class<?> getObjectType() {
- return Resource.class;
- }
-
- public boolean isSingleton() {
- return true;
- }
-
- public void afterPropertiesSet() throws Exception {
- cs = Charset.forName(charset);
- decoder = cs.newDecoder();
- // encoder = cs.newEncoder();
-
- for (String sedStr : filters) {
- sedStr = sedStr.trim();
- if (sedStr.length() < 4)
- throw new SlcException(sedStr + " not properly formatted.");
- if (sedStr.charAt(0) != 's')
- throw new SlcException(sedStr + " not properly formatted.");
- Character sep = sedStr.charAt(1);
- List<String> tokens = new ArrayList<String>(4);
- StringTokenizer st = new StringTokenizer(sedStr, sep.toString());
- while (st.hasMoreTokens())
- tokens.add(st.nextToken());
- if (tokens.size() != 3 && tokens.size() != 4)
- throw new SlcException(sedStr + " not properly formatted.");
- patterns.put(Pattern.compile(tokens.get(1)), tokens.get(2));
- }
- }
-
- public void setSource(Resource source) {
- this.source = source;
- }
-
- public void setFilters(List<String> filters) {
- this.filters = filters;
- }
-
- public void setCharset(String charset) {
- this.charset = charset;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.doc;
-
-import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.PropertyValue;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-
-public class ConsoleContextDescriber implements ContextDescriber {
- public void describeContext(BeanDefinitionRegistry registry) {
- String[] beanNames = registry.getBeanDefinitionNames();
- for (String beanName : beanNames) {
- log("\n## BEAN: " + beanName);
- describeBean(registry.getBeanDefinition(beanName));
- }
- }
-
- public void describeBean(BeanDefinition beanDefinition) {
- log("BeanDefinition class: "+beanDefinition.getClass());
- log("# ATTRIBUTES");
- for(String attr:beanDefinition.attributeNames()){
- log(attr+"="+beanDefinition.getAttribute(attr));
- }
- log("# PROPERTIES");
- MutablePropertyValues pValues = beanDefinition.getPropertyValues();
- for (PropertyValue pv : pValues.getPropertyValues()) {
- log(pv.getName() + "= (" + pv.getValue().getClass() + ") "
- + pv.getValue());
- }
- }
-
- protected void log(Object obj){
- System.out.println(obj);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.doc;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-
-public interface ContextDescriber {
- public void describeContext(BeanDefinitionRegistry registry);
- public void describeBean(BeanDefinition bd);
-}
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.Map;\r
-\r
-import org.argeo.slc.SlcException;\r
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
-\r
-/**\r
- * Composite <code>RunnableFactory</code>, redirecting the Runnable \r
- * creation to on of the configured <code>RunnableFactory</code> depending\r
- * on an entry of the data of the <code>RunnableDataNode</code>.\r
- */\r
-public class CompositeRunnableFactory implements RunnableFactory {\r
-\r
- /**\r
- * Key used to access factory ID in the data of the <code>RunnableDataNode</code>\r
- */\r
- private String factoryKey;\r
-\r
- /**\r
- * Maps a factory ID to an ExecutionFlowFactory\r
- */\r
- private Map<String, RunnableFactory> factories;\r
-\r
- public void createAndRegisterRunnable(RunnableDataNode node,\r
- BeanDefinitionRegistry beanDefinitionRegistry) {\r
- findFactory(node).createAndRegisterRunnable(node, beanDefinitionRegistry);\r
- } \r
- \r
- /**\r
- * Finds the <code>RunnableFactory</code> to use for a <code>RunnableDataNode</code>\r
- * @param node\r
- * @return the <code>RunnableFactory</code> to use for the <code>RunnableDataNode</code>\r
- */\r
- private RunnableFactory findFactory(RunnableDataNode node) {\r
- // get the factory ID from the data of the RunnableDescriptor\r
- Map<String, Object> data = node.getData();\r
- if (!data.containsKey(factoryKey)) {\r
- throw new SlcException("No data value for key '" + factoryKey + "'");\r
- }\r
- String factoryId = data.get(factoryKey).toString();\r
- \r
- // see if we have a factory for the factory ID\r
- if ((factories != null) && factories.containsKey(factoryId)) {\r
- return factories.get(factoryId);\r
- }\r
- // if not, look for a bean of name equals to the factory ID\r
- else {\r
- throw new SlcException("Not implemented");\r
- } \r
- }\r
- \r
- public void setFactoryKey(String factoryKey) {\r
- this.factoryKey = factoryKey;\r
- }\r
-\r
- public void setFactories(Map<String, RunnableFactory> factories) {\r
- this.factories = factories;\r
- }\r
-\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-/**\r
- * Default implementation of <code>RunnableDataNode</code>\r
- *\r
- */\r
-public class DefaultRunnableDataNode implements RunnableDataNode {\r
-\r
- private List<RunnableDataNode> children = new ArrayList<RunnableDataNode>();\r
- \r
- private RunnableDataNode parent;\r
- \r
- /**\r
- * Data of the RunnableDataNode. Does not contain\r
- * parent data.\r
- */\r
- private Map<String, Object> properData = new HashMap<String, Object>();\r
- \r
- private String path;\r
- \r
- private String beanName;\r
-\r
- public boolean isLeaf() {\r
- return children.size() == 0;\r
- }\r
- \r
- public List<RunnableDataNode> getChildren() {\r
- return children;\r
- }\r
-\r
- public void addChild(RunnableDataNode child) {\r
- child.setParent(this);\r
- children.add(child);\r
- }\r
- \r
- public Map<String, Object> getData() {\r
- Map<String, Object> data = new HashMap<String, Object>();\r
- if(parent != null) {\r
- Map<String, Object> parentData = parent.getData();\r
- if(parentData != null) {\r
- data.putAll(parentData);\r
- }\r
- }\r
- // entries defined in parentData can be overridden\r
- // in properData\r
- if(properData != null) {\r
- data.putAll(properData);\r
- }\r
- return data;\r
- }\r
-\r
- public Map<String, Object> getProperData() {\r
- return properData;\r
- }\r
-\r
- public void setProperData(Map<String, Object> properData) {\r
- this.properData = properData;\r
- }\r
-\r
- public String getPath() {\r
- return path;\r
- }\r
-\r
- public void setPath(String path) {\r
- this.path = path;\r
- }\r
-\r
- public String getBeanName() {\r
- return beanName;\r
- }\r
-\r
- public void setBeanName(String beanName) {\r
- this.beanName = beanName;\r
- }\r
-\r
- public void setParent(RunnableDataNode parent) {\r
- this.parent = parent;\r
- }\r
-\r
- public RunnableDataNode getParent() {\r
- return parent;\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.HashMap;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.springframework.aop.scope.ScopedProxyUtils;\r
-import org.springframework.beans.BeansException;\r
-import org.springframework.beans.MutablePropertyValues;\r
-import org.springframework.beans.factory.config.BeanDefinitionHolder;\r
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;\r
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;\r
-import org.springframework.beans.factory.config.RuntimeBeanReference;\r
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
-import org.springframework.beans.factory.support.GenericBeanDefinition;\r
-import org.springframework.core.Ordered;\r
-\r
-/**\r
- * Generates <code>ExecutionFlows</code> and <code>Runnables</code> as\r
- * beans in the Spring Application Context.\r
- * Called by the Application Context as a <code>BeanFactoryPostProcessor</code>.\r
- * Two kinds of beans are generated:\r
- * <code>RunnableCallFlow</code>, calling a list of <code>Runnables</code> from the\r
- * Application Context after configuring the <code>ExecutionContext</code>, \r
- * and outputs of a <code>RunnableFactory</code>.\r
- */\r
-public class ExecutionFlowGenerator implements BeanFactoryPostProcessor,\r
- Ordered {\r
- \r
- private final Log log = LogFactory.getLog(getClass());\r
-\r
- /**\r
- * Source providing a list of <code>RunnableCallFlowDescriptor</code> \r
- * used to create <code>RunnableCallFlow</code> and a list of \r
- * <code>RunnableDataNode</code> used to create any kind of flow via a factory\r
- */\r
- protected ExecutionFlowGeneratorSource source;\r
- \r
- /**\r
- * Factory used to create Runnables in the Application context from\r
- * the <code>RunnableDataNode</code> provided from the source.\r
- */\r
- protected RunnableFactory runnableFactory;\r
- \r
- /**\r
- * Bean name of the <code>ExecutionContext</code>.\r
- * Used to provide the created <code>RunnableCallFlow</code> beans \r
- * with a <code>RuntimeBeanReference</code> to\r
- * the <code>ExecutionContext</code>\r
- */\r
- private String executionContextBeanName = "executionContext";\r
- \r
- /**\r
- * Bean name of the context values Map.\r
- * A bean of class HashMap is created with this name, and a \r
- * <code>RuntimeBeanReference</code> is provided to the created\r
- * <code>RunnableCallFlow</code> beans.\r
- */\r
- private String contextValuesBeanName = "executionFlowGenerator.contextValues";\r
- \r
- /**\r
- * Prefix added to the bean names defined in each \r
- * <code>RunnableCallFlowDescriptor</code>\r
- */\r
- private String flowBeanNamesPrefix = "";\r
- \r
- private int order = Ordered.HIGHEST_PRECEDENCE;\r
- \r
- public void postProcessBeanFactory(\r
- ConfigurableListableBeanFactory beanFactory) throws BeansException {\r
-\r
- // assert that the beanFactory is a BeanDefinitionRegistry\r
- if (!(beanFactory instanceof BeanDefinitionRegistry)) {\r
- throw new SlcException("Can only work on "\r
- + BeanDefinitionRegistry.class);\r
- } \r
- \r
- // add bean for the Context Values Map\r
- createAndRegisterContextValuesBean((BeanDefinitionRegistry) beanFactory);\r
- \r
- // add beans for each RunnableDataNode\r
- for(RunnableDataNode node : source.getRunnableDataNodes()) {\r
- runnableFactory.createAndRegisterRunnable(node, (BeanDefinitionRegistry) beanFactory);\r
- }\r
- \r
- // add beans for each RunnableCallFlowDescriptor of the source to the application context\r
- for (RunnableCallFlowDescriptor descriptor : source\r
- .getRunnableCallFlowDescriptors()) {\r
- createAndRegisterFlowFor(descriptor, (BeanDefinitionRegistry) beanFactory);\r
- }\r
- }\r
-\r
- /**\r
- * Creates a <code>RunnableCallFlow</code> bean\r
- * for a <code>RunnableCallFlowDescriptor</code> and registers \r
- * it in the <code>BeanDefinitionRegistry</code>\r
- * @param flowDescriptor\r
- * @param registry\r
- */\r
- private void createAndRegisterFlowFor(RunnableCallFlowDescriptor flowDescriptor, BeanDefinitionRegistry registry) {\r
- // create the flow bean\r
- GenericBeanDefinition flowBean = new GenericBeanDefinition();\r
- flowBean.setBeanClass(RunnableCallFlow.class);\r
- \r
- String beanName = flowBeanNamesPrefix + flowDescriptor.getBeanName();\r
- \r
- MutablePropertyValues mpv = new MutablePropertyValues(); \r
- mpv.addPropertyValue("runnableCalls", flowDescriptor.getRunnableCalls());\r
- mpv.addPropertyValue("sharedContextValuesMap", new RuntimeBeanReference(contextValuesBeanName));\r
- \r
- mpv.addPropertyValue("name", beanName);\r
- mpv.addPropertyValue("path", flowDescriptor.getPath());\r
-\r
- mpv.addPropertyValue("executionContext", new RuntimeBeanReference(executionContextBeanName));\r
- \r
- flowBean.setPropertyValues(mpv);\r
- \r
- // register it\r
- if(log.isDebugEnabled()) {\r
- log.debug("Registering bean definition for RunnableCallFlow " + beanName);\r
- }\r
- registry.registerBeanDefinition(beanName, flowBean);\r
- }\r
- \r
- /**\r
- * Creates the Context Values bean and register it in the\r
- * <code>BeanDefinitionRegistry</code>\r
- * @param registry\r
- */\r
- private void createAndRegisterContextValuesBean(BeanDefinitionRegistry registry) {\r
- GenericBeanDefinition contextValuesBean = new GenericBeanDefinition();\r
- contextValuesBean.setBeanClass(HashMap.class);\r
- \r
- BeanDefinitionHolder bdh = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(contextValuesBean, contextValuesBeanName), registry, true); \r
- registry.registerBeanDefinition(contextValuesBeanName, bdh.getBeanDefinition()); \r
- }\r
- \r
- public int getOrder() {\r
- return order;\r
- }\r
-\r
- public void setOrder(int order) {\r
- this.order = order;\r
- }\r
-\r
- public void setSource(ExecutionFlowGeneratorSource source) {\r
- this.source = source;\r
- }\r
-\r
- public void setRunnableFactory(RunnableFactory runnableFactory) {\r
- this.runnableFactory = runnableFactory;\r
- }\r
-\r
- public void setExecutionContextBeanName(String executionContextBeanName) {\r
- this.executionContextBeanName = executionContextBeanName;\r
- }\r
-\r
- public void setContextValuesBeanName(String contextValuesBeanName) {\r
- this.contextValuesBeanName = contextValuesBeanName;\r
- }\r
-\r
- public void setFlowBeanNamesPrefix(String flowBeanNamesPrefix) {\r
- this.flowBeanNamesPrefix = flowBeanNamesPrefix;\r
- }\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * Provides 2 types of information required by an <code>ExecutionFlowGenerator</code>: \r
- * a list of <code>RunnableCallFlowDescriptor</code> used to create <code>RunnableCallFlow</code>\r
- * and a list of <code>RunnableDataNode</code> used to create any kind of flow via a factory.\r
- */\r
-public interface ExecutionFlowGeneratorSource {\r
- \r
- /**\r
- * @return a list of <code>RunnableCallFlowDescriptor</code> used \r
- * by a <code>ExecutionFlowGenerator</code> to create <code>RunnableCallFlow</code>\r
- */\r
- public List<RunnableCallFlowDescriptor> getRunnableCallFlowDescriptors();\r
- \r
- /**\r
- * @return a list of <code>RunnableDataNode</code> used \r
- * by a <code>ExecutionFlowGenerator</code> to create any kind of flow via a factory\r
- */\r
- public List<RunnableDataNode> getRunnableDataNodes();\r
- \r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.Map;\r
-\r
-/**\r
- * Storage class for information required to call a flow \r
- * of the Spring execution context: \r
- * bean name of the flow,\r
- * variables to add to the Execution Context before the call \r
- * and variables (context values) to add to a Map \r
- * potentially referenced by the called flow \r
- */\r
-public class RunnableCall {\r
- \r
- /**\r
- * Bean name of the flow to call\r
- */\r
- private String beanName;\r
- \r
- /**\r
- * Variables to add to the execution context before the call\r
- */\r
- private Map<String, Object> executionVariables;\r
- \r
- /**\r
- * Variables to add to the Map potentially referenced by\r
- * the called flow\r
- */\r
- private Map<String, Object> contextValues;\r
-\r
- public String getBeanName() {\r
- return beanName;\r
- }\r
-\r
- public void setBeanName(String beanName) {\r
- this.beanName = beanName;\r
- }\r
-\r
- public Map<String, Object> getExecutionVariables() {\r
- return executionVariables;\r
- }\r
-\r
- public void setExecutionVariables(Map<String, Object> executionVariables) {\r
- this.executionVariables = executionVariables;\r
- }\r
-\r
- public Map<String, Object> getContextValues() {\r
- return contextValues;\r
- }\r
-\r
- public void setContextValues(Map<String, Object> contextValues) {\r
- this.contextValues = contextValues;\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.core.execution.DefaultExecutionSpec;\r
-import org.argeo.slc.execution.ExecutionContext;\r
-import org.argeo.slc.execution.ExecutionFlow;\r
-import org.argeo.slc.execution.ExecutionSpec;\r
-import org.springframework.context.ApplicationContext;\r
-import org.springframework.context.ApplicationContextAware;\r
-\r
-/**\r
- * Execution Flow calling a list of <code>Runnable</code> (identified by their\r
- * bean name in the Spring Application Context) after configuring the Execution\r
- * context and a Map potentially shared by the called <code>Runnable</code>\r
- * \r
- */\r
-public class RunnableCallFlow implements ExecutionFlow, ApplicationContextAware {\r
-\r
- private final static Log log = LogFactory.getLog(RunnableCallFlow.class);\r
-\r
- /**\r
- * Key in the execution context for the index of the call (e.g. 0 for the\r
- * first runnable called, ...)\r
- */\r
- public final static String VAR_CALL_INDEX = "slcVar.runnableCallFlow.callIndex";\r
-\r
- /**\r
- * Name of the flow. Also bean name\r
- */\r
- private String name;\r
-\r
- /**\r
- * Path of the flow\r
- */\r
- private String path;\r
-\r
- /**\r
- * Whether an exception in a <code>Runnable</code> shall stop the execution\r
- * of the flow\r
- */\r
- private Boolean failOnError = true;\r
-\r
- /**\r
- * List of <code>Runnable</code> to call, with bean name, execution\r
- * variables and context values\r
- */\r
- private List<RunnableCall> runnableCalls;\r
-\r
- /**\r
- * Map potentially referenced by called flows. Updated with the context\r
- * values of a Runnable before calling it.\r
- */\r
- private Map<String, Object> sharedContextValuesMap;\r
-\r
- /**\r
- * ExecutionSpec of the flow. Does not contain any attribute.\r
- */\r
- private ExecutionSpec executionSpec = new DefaultExecutionSpec();\r
-\r
- /**\r
- * Reference to the ExecutionContext\r
- */\r
- private ExecutionContext executionContext;\r
-\r
- /**\r
- * Reference to the Spring <code>ApplicationContext</code>. Set via\r
- * <code>setApplicationContext</code>, the class implementing\r
- * <code>ApplicationContextAware</code>\r
- */\r
- private ApplicationContext applicationContext;\r
-\r
- /**\r
- * Runs a <code>Runnable</code> after configuring the Execution Context and\r
- * <code>sharedContextValuesMap</code>\r
- * \r
- * @param runnable\r
- * the <code>Runnable</code> to call\r
- * @param executionVariables\r
- * the variables to add to the <code>ExecutionContext</code>\r
- * @param contextValues\r
- * the variables to add to <code>sharedContextValuesMap</code>\r
- * @param callIndex\r
- * index of the call (0 for the first called\r
- * <code>Runnable</code>) set as variable of the\r
- * <code>ExecutionContext</code>\r
- */\r
- private void run(Runnable runnable, Map<String, Object> executionVariables,\r
- Map<String, Object> contextValues, int callIndex) {\r
- // add all variables to the Execution Context\r
- for (Map.Entry<String, Object> entry : executionVariables.entrySet()) {\r
- executionContext.setVariable(entry.getKey(), entry.getValue());\r
- }\r
-\r
- // add call Index Variable\r
- executionContext.setVariable(VAR_CALL_INDEX, callIndex);\r
-\r
- // clear sharedContextValues and add all values of contextValues\r
- if (sharedContextValuesMap != null) {\r
- sharedContextValuesMap.clear();\r
- sharedContextValuesMap.putAll(contextValues);\r
- }\r
-\r
- // then run the runnable\r
- doExecuteRunnable(runnable);\r
- }\r
-\r
- public void doExecuteRunnable(Runnable runnable) {\r
- runnable.run();\r
- }\r
-\r
- /**\r
- * Executes the flow. For each <code>RunnableCall</code>, the corresponding\r
- * flow is retrieved from the Spring Application Context, the\r
- * <code>ExecutionContext</code> and <code>sharedContextValuesMap</code> are\r
- * configured and the <code>Runnable</code> is called.\r
- */\r
- public void run() {\r
- if (applicationContext == null) {\r
- throw new SlcException("No ApplicationContext defined");\r
- }\r
-\r
- try {\r
- for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
- RunnableCall runnableCall = runnableCalls.get(callIndex);\r
- Object bean = applicationContext.getBean(\r
- runnableCall.getBeanName(), Runnable.class);\r
- if (log.isDebugEnabled())\r
- log.debug("Running flow '" + runnableCall.getBeanName()\r
- + "'");\r
- run((Runnable) bean, runnableCall.getExecutionVariables(),\r
- runnableCall.getContextValues(), callIndex);\r
- }\r
- } catch (RuntimeException e) {\r
- if (failOnError)\r
- throw e;\r
- else {\r
- log.error("Execution flow failed,"\r
- + " but process did not fail"\r
- + " because failOnError property"\r
- + " is set to false: " + e);\r
- if (log.isTraceEnabled())\r
- e.printStackTrace();\r
- }\r
- }\r
- }\r
-\r
- public Iterator<Runnable> runnables() {\r
- List<Runnable> runnables = new ArrayList<Runnable>();\r
- for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
- RunnableCall runnableCall = runnableCalls.get(callIndex);\r
- Object bean = applicationContext.getBean(\r
- runnableCall.getBeanName(), Runnable.class);\r
- runnables.add((Runnable) bean);\r
- }\r
- return runnables.iterator();\r
- }\r
-\r
- public Runnable getRunnable() {\r
- if (runnableCalls.size() == 1)\r
- return runnables().next();\r
- else\r
- throw new SlcException("There are " + runnableCalls.size()\r
- + " runnables in flow " + getName());\r
- }\r
-\r
- @Override\r
- public String toString() {\r
- return new StringBuffer("RunnableCallFlow ").append(name).toString();\r
- }\r
-\r
- public ExecutionSpec getExecutionSpec() {\r
- return executionSpec;\r
- }\r
-\r
- public String getName() {\r
- return name;\r
- }\r
-\r
- public Object getParameter(String key) {\r
- throw new SlcException("RunnableCallFlow have no parameters");\r
- }\r
-\r
- public String getPath() {\r
- return path;\r
- }\r
-\r
- public Boolean isSetAsParameter(String key) {\r
- // The ExecutionSpec having no attribute,\r
- // always return false\r
- return false;\r
- }\r
-\r
- public void setName(String name) {\r
- this.name = name;\r
- }\r
-\r
- public void setPath(String path) {\r
- this.path = path;\r
- }\r
-\r
- public void setExecutionContext(ExecutionContext executionContext) {\r
- this.executionContext = executionContext;\r
- }\r
-\r
- public void setRunnableCalls(List<RunnableCall> runnableCalls) {\r
- this.runnableCalls = runnableCalls;\r
- }\r
-\r
- public void setApplicationContext(ApplicationContext applicationContext) {\r
- this.applicationContext = applicationContext;\r
- }\r
-\r
- public void setSharedContextValuesMap(Map<String, Object> contextValues) {\r
- this.sharedContextValuesMap = contextValues;\r
- }\r
-\r
- public void setFailOnError(Boolean failOnError) {\r
- this.failOnError = failOnError;\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-/**\r
- * Storage Class for information required to\r
- * instantiate a <code>RunnableCallFlow</code>:\r
- * bean name of the flow, \r
- * path of the flow \r
- * and list of <code>RunnableCall</code>. \r
- *\r
- */\r
-public class RunnableCallFlowDescriptor {\r
- \r
- /**\r
- * Bean name of the flow to instantiate\r
- */\r
- private String beanName;\r
- \r
- /**\r
- * Path of the flow to instantiate\r
- */\r
- private String path;\r
- \r
- /**\r
- * List of <code>RunnableCall</code> \r
- */\r
- private List<RunnableCall> runnableCalls = new ArrayList<RunnableCall>();\r
-\r
- public String getBeanName() {\r
- return beanName;\r
- }\r
-\r
- public void setBeanName(String beanName) {\r
- this.beanName = beanName;\r
- }\r
-\r
- public String getPath() {\r
- return path;\r
- }\r
-\r
- public void setPath(String path) {\r
- this.path = path;\r
- }\r
-\r
- public List<RunnableCall> getRunnableCalls() {\r
- return runnableCalls;\r
- }\r
-\r
- public void setRunnableCalls(List<RunnableCall> runnableCalls) {\r
- this.runnableCalls = runnableCalls;\r
- }\r
- \r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-/**\r
- * Stores information relative to a Runnable.\r
- * Allows to structure the information as a tree, each node\r
- * storing data as a Map.\r
- */\r
-public interface RunnableDataNode {\r
-\r
- /**\r
- * @return a Map containing the data associated with this node.\r
- * Data associated with parent nodes are expected\r
- * to be contained in the returned Map\r
- */\r
- public Map<String, Object> getData(); \r
-\r
- /**\r
- * @return the name of the bean to create.\r
- * Can be null if no bean shall be created for the \r
- * <code>RunnableDataNode</code> (e.g. is is a sub-node)\r
- */\r
- public String getBeanName();\r
- \r
- /**\r
- * @return the path of the flow bean to create.\r
- * Can be null if the bean to created is not an\r
- * <code>ExecutionFlow</code> or if no bean shall be created for the \r
- * <code>RunnableDataNode</code> (e.g. is is a sub-node)\r
- */\r
- public String getPath();\r
- \r
- /**\r
- * @return whether the <code>RunnableDataNode</code> has\r
- * children or not.\r
- * Expected to be equivalent to <code>getChildren().empty()</code>\r
- */\r
- public boolean isLeaf();\r
-\r
- /**\r
- * @return the list of <code>RunnableDataNode</code> children.\r
- * Can be empty. Shall not be null.\r
- */\r
- public List<RunnableDataNode> getChildren();\r
- \r
- /**\r
- * @return the <code>RunnableDataNode</code> parent.\r
- * Can be null if no parent is defined (top node).\r
- */\r
- public RunnableDataNode getParent();\r
- \r
- /**\r
- * Sets the <code>RunnableDataNode</code> parent\r
- * @param parent\r
- */\r
- public void setParent(RunnableDataNode parent); \r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;\r
-\r
-/**\r
- * Interprets a <code>RunnableDataNode</code> by creating corresponding\r
- * beans and registering them in a <code>BeanDefinitionRegistry</code>\r
- *\r
- */\r
-public interface RunnableFactory {\r
-\r
- public void createAndRegisterRunnable(RunnableDataNode node,\r
- BeanDefinitionRegistry beanDefinitionRegistry);\r
-}\r
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import org.argeo.slc.test.TestResult;
-
-public class CloseTestResult implements Runnable {
- private TestResult testResult;
-
- public void run() {
- testResult.close();
- }
-
- public void setTestResult(TestResult testResult) {
- this.testResult = testResult;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.core.io.Resource;
-
-public class Echo implements Runnable {
- private final static Log defaultLog = LogFactory.getLog(Echo.class);
- private Resource writeTo = null;
-
- private Log log;
- private Object message;
-
- public void run() {
- log().info(message);
-
- if (writeTo != null) {
- try {
- File file = writeTo.getFile();
- if (log().isDebugEnabled())
- log().debug("Write to " + file);
- if (message != null)
- FileUtils.writeStringToFile(file, message.toString());
- } catch (IOException e) {
- throw new SlcException("Could not write to " + writeTo, e);
- }
- }
- }
-
- private Log log() {
- return log != null ? log : defaultLog;
- }
-
- public void setMessage(Object message) {
- this.message = message;
- }
-
- public void setWriteTo(Resource writeTo) {
- this.writeTo = writeTo;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import org.argeo.slc.SlcException;
-
-/** Conditional execution */
-public class If implements Runnable {
- private Boolean is;
- private Boolean not;
- private Runnable then;
- private Runnable els;
-
- public void run() {
- if (is == null && not == null)
- throw new SlcException("No condition set");
- if (is != null && not != null)
- throw new SlcException("Both is and not cannot be set");
-
- boolean bool = (is != null ? is : !not);
- if (bool) {
- if (then != null)
- then.run();
- } else {
- if (els != null)
- els.run();
- }
-
- }
-
- public void setIs(Boolean bool) {
- this.is = bool;
- }
-
- public void setThen(Runnable then) {
- this.then = then;
- }
-
- public void setEls(Runnable els) {
- this.els = els;
- }
-
- public Boolean getNot() {
- return not;
- }
-
- public void setNot(Boolean not) {
- this.not = not;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.core.io.Resource;
-
-/** A Java Virtual Machine process. */
-public class JvmProcess extends SystemCall implements InitializingBean {
- private Properties systemProperties = new Properties();
- private List<Resource> classpath = new ArrayList<Resource>();
- private List<Resource> pBootClasspath = new ArrayList<Resource>();
- private Resource jvm = null;
- private String mainClass;
- private String mainJar;
- private List<String> jvmArgs = new ArrayList<String>();
- private List<String> args = new ArrayList<String>();
-
- private String systemPropertiesFileProperty = null;
- private String systemPropertiesFileDir = null;
- private String systemPropertiesFileName = null;
-
- public void afterPropertiesSet() throws Exception {
- List<Object> command = new ArrayList<Object>();
- if (jvm != null)
- command.add(asFile(jvm).getPath());
- else
- command.add("java");
-
- if (pBootClasspath.size() > 0) {
- StringBuffer buf = new StringBuffer("-Xbootclasspath/p:");
- Boolean first = true;
- for (Resource res : pBootClasspath) {
- if (first)
- first = false;
- else
- buf.append(File.pathSeparatorChar);
-
- buf.append(asFile(res));
- }
- command.add(buf.toString());
- }
-
- for (String jvmArg : jvmArgs) {
- command.add(jvmArg);
- }
-
- if (classpath.size() > 0) {
- command.add("-cp");
- StringBuffer buf = new StringBuffer("");
- for (Resource res : classpath) {
- if (buf.length() != 0)
- buf.append(File.pathSeparatorChar);
- buf.append(asFile(res));
- }
- command.add(buf.toString());
- }
-
- if (systemPropertiesFileProperty == null) {
- // pass system properties as argument
- for (Map.Entry<Object, Object> entry : systemProperties.entrySet()) {
- command.add("-D" + entry.getKey() + "=" + entry.getValue());
- }
- } else {
- // write system properties in a file to work around OS limitations
- // with command line (e.g. Win XP)
- String dir = systemPropertiesFileDir;
- if (dir == null)
- dir = getExecDirToUse();
- String fileName = systemPropertiesFileName;
- if (fileName == null)
- fileName = systemPropertiesFileProperty + ".properties";
-
- // Write file
- FileOutputStream fos = null;
- File file = new File(dir + File.separator + fileName);
- try {
-
- if (!file.getParentFile().exists())
- file.getParentFile().mkdirs();
- fos = new FileOutputStream(file);
- systemProperties.store(fos, "Automatically generated by "
- + getClass());
- command.add("-D" + systemPropertiesFileProperty + "="
- + file.getCanonicalPath());
- } catch (IOException e) {
- throw new SlcException("Cannot write to system properties to "
- + file, e);
- } finally {
- IOUtils.closeQuietly(fos);
- }
- }
-
- // Program
- if (mainClass != null) {
- command.add(mainClass);
- } else if (mainJar != null) {
- command.add("-jar");
- command.add(mainJar);
- } else {
- throw new SlcException("No main class or jar defined");
- }
-
- for (String arg : args) {
- command.add(arg);
- }
-
- setCommand(command);
- }
-
- protected File asFile(Resource res) {
- try {
- return res.getFile();
- } catch (FileNotFoundException e) {
- return copyToTempFile(res);
- } catch (IOException e) {
- throw new SlcException("Cannot convert resource to file", e);
- }
-
- }
-
- protected File copyToTempFile(Resource res) {
- File tempFile;
- FileOutputStream fos;
- try {
- tempFile = File.createTempFile("slcJvmProcess-", res.getFilename());
- tempFile.deleteOnExit();
- fos = new FileOutputStream(tempFile);
- IOUtils.copy(res.getInputStream(), fos);
- } catch (IOException e) {
- throw new SlcException("Cannot copy " + res + " to temp file.", e);
- }
- IOUtils.closeQuietly(fos);
- return tempFile;
- }
-
- /** Append the argument (for chaining) */
- @Override
- public SystemCall arg(String arg) {
- args.add(arg);
- return this;
- }
-
- /** Append the argument (for chaining) */
- @Override
- public SystemCall arg(String arg, String value) {
- args.add(arg);
- args.add(value);
- return this;
- }
-
- public Properties getSystemProperties() {
- return systemProperties;
- }
-
- public void setSystemProperties(Properties systemProperties) {
- this.systemProperties = systemProperties;
- }
-
- public List<Resource> getClasspath() {
- return classpath;
- }
-
- public void setClasspath(List<Resource> classpath) {
- this.classpath = classpath;
- }
-
- public List<Resource> getPBootClasspath() {
- return pBootClasspath;
- }
-
- public void setPBootClasspath(List<Resource> bootClasspath) {
- pBootClasspath = bootClasspath;
- }
-
- public Resource getJvm() {
- return jvm;
- }
-
- public void setJvm(Resource jvm) {
- this.jvm = jvm;
- }
-
- public String getMainClass() {
- return mainClass;
- }
-
- public void setMainClass(String mainClass) {
- this.mainClass = mainClass;
- }
-
- public String getMainJar() {
- return mainJar;
- }
-
- public void setMainJar(String mainJar) {
- this.mainJar = mainJar;
- }
-
- public List<String> getJvmArgs() {
- return jvmArgs;
- }
-
- public void setJvmArgs(List<String> jvmArgs) {
- this.jvmArgs = jvmArgs;
- }
-
- public List<String> getArgs() {
- return args;
- }
-
- public void setArgs(List<String> args) {
- this.args = args;
- }
-
- public void setSystemPropertiesFileProperty(
- String systemPropertiesFilePropertyName) {
- this.systemPropertiesFileProperty = systemPropertiesFilePropertyName;
- }
-
- public void setSystemPropertiesFileDir(String systemPropertiesFileDir) {
- this.systemPropertiesFileDir = systemPropertiesFileDir;
- }
-
- public void setSystemPropertiesFileName(String systemPropertiesFileName) {
- this.systemPropertiesFileName = systemPropertiesFileName;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.springframework.beans.factory.FactoryBean;
-
-/** Merge the provided lists in one single list, in the order provided. */
-public class MergedLists implements FactoryBean {
- private List<List<Object>> lists = new ArrayList<List<Object>>();
-
- public void setLists(List<List<Object>> lists) {
- this.lists = lists;
- }
-
- public Object getObject() throws Exception {
- List<Object> merged = new ArrayList<Object>();
- for (List<Object> lst : lists) {
- merged.addAll(lst);
- }
- return merged;
- }
-
- public Class<?> getObjectType() {
- return List.class;
- }
-
- public boolean isSingleton() {
- return false;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.springframework.util.Assert;
-import org.springframework.util.ReflectionUtils;
-
-public class MethodCall implements Runnable {
- private Object target;
- private String method;
- private List<Object> args = new ArrayList<Object>();
-
- public void run() {
- Assert.notNull(target, "target");
- Assert.notNull(method, "method");
- Method methodRef = ReflectionUtils
- .findMethod(target.getClass(), method);
- if (args.size() == 0)
- ReflectionUtils.invokeMethod(methodRef, target);
- else
- ReflectionUtils.invokeMethod(methodRef, methodRef, args.toArray());
- }
-
- public void setTarget(Object target) {
- this.target = target;
- }
-
- public void setMethod(String method) {
- this.method = method;
- }
-
- public void setArgs(List<Object> args) {
- this.args = args;
- }
-
-}
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.tasks;\r
-\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.core.test.context.SimpleContextAware;\r
-import org.argeo.slc.test.context.ContextAware;\r
-\r
-/**\r
- * Overrides Values and Expected values of a target \r
- * <code>SimpleContextAware</code> with the corresponding\r
- * values and expected values of a source <code>ContextAware</code>\r
- *\r
- */\r
-public class OverrideContextAware implements Runnable {\r
-\r
- private ContextAware source;\r
-\r
- private SimpleContextAware target;\r
- \r
- /**\r
- * Whether an exception shall be thrown if a value\r
- * or expected value of the source is not defined\r
- * in the target\r
- */\r
- private Boolean failIfUndefinedInSource = true;\r
- \r
- public void run() {\r
- // override values\r
- if(source.getValues() != null)\r
- for(String key : source.getValues().keySet()) {\r
- if(failIfUndefinedInSource && !target.getValues().containsKey(key)) {\r
- throw new SlcException("No entry in target values for key '" + key + "'");\r
- }\r
- target.getValues().put(key, source.getValues().get(key));\r
- }\r
- \r
- // override expected values\r
- if(source.getExpectedValues() != null)\r
- for(String key : source.getExpectedValues().keySet()) {\r
- if(failIfUndefinedInSource && !target.getExpectedValues().containsKey(key)) {\r
- throw new SlcException("No entry in target expected values for key '" + key + "'");\r
- }\r
- target.getExpectedValues().put(key, source.getExpectedValues().get(key));\r
- } \r
- } \r
- \r
- public void setSource(ContextAware source) {\r
- this.source = source;\r
- }\r
-\r
- public void setTarget(SimpleContextAware target) {\r
- this.target = target;\r
- }\r
-\r
- public void setFailIfUndefinedInSource(Boolean failIfUndefinedInSource) {\r
- this.failIfUndefinedInSource = failIfUndefinedInSource;\r
- } \r
-}\r
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.security.auth.callback.CallbackHandler;
-
-import org.apache.commons.exec.CommandLine;
-import org.apache.commons.exec.DefaultExecutor;
-import org.apache.commons.exec.ExecuteException;
-import org.apache.commons.exec.ExecuteResultHandler;
-import org.apache.commons.exec.ExecuteStreamHandler;
-import org.apache.commons.exec.ExecuteWatchdog;
-import org.apache.commons.exec.Executor;
-import org.apache.commons.exec.LogOutputStream;
-import org.apache.commons.exec.PumpStreamHandler;
-import org.apache.commons.exec.ShutdownHookProcessDestroyer;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.UnsupportedException;
-import org.argeo.slc.core.execution.ExecutionResources;
-import org.argeo.slc.core.test.SimpleResultPart;
-import org.argeo.slc.test.TestResult;
-import org.argeo.slc.test.TestStatus;
-import org.springframework.core.io.Resource;
-import org.springframework.security.Authentication;
-import org.springframework.security.context.SecurityContextHolder;
-
-/** Execute an OS specific system call. */
-public class SystemCall implements Runnable {
- public final static String LOG_STDOUT = "System.out";
-
- private final Log log = LogFactory.getLog(getClass());
-
- private String execDir;
-
- private String cmd = null;
- private List<Object> command = null;
-
- private Executor executor = new DefaultExecutor();
- private Boolean synchronous = true;
-
- private String stdErrLogLevel = "ERROR";
- private String stdOutLogLevel = "INFO";
-
- private Resource stdOutFile = null;
- private Resource stdErrFile = null;
-
- private Resource stdInFile = null;
- /**
- * If no {@link #stdInFile} provided, writing to this stream will write to
- * the stdin of the process.
- */
- private OutputStream stdInSink = null;
-
- private Boolean redirectStdOut = false;
-
- private List<SystemCallOutputListener> outputListeners = Collections
- .synchronizedList(new ArrayList<SystemCallOutputListener>());
-
- private Map<String, List<Object>> osCommands = new HashMap<String, List<Object>>();
- private Map<String, String> osCmds = new HashMap<String, String>();
- private Map<String, String> environmentVariables = new HashMap<String, String>();
-
- private Boolean logCommand = false;
- private Boolean redirectStreams = true;
- private Boolean exceptionOnFailed = true;
- private Boolean mergeEnvironmentVariables = true;
-
- private Authentication authentication;
-
- private String osConsole = null;
- private String generateScript = null;
-
- /** 24 hours */
- private Long watchdogTimeout = 24 * 60 * 60 * 1000l;
-
- private TestResult testResult;
-
- private ExecutionResources executionResources;
-
- /** Sudo the command, as root if empty or as user if not. */
- private String sudo = null;
- // TODO make it more secure and robust, test only once
- private final String sudoPrompt = UUID.randomUUID().toString();
- private String askPassProgram = "/usr/libexec/openssh/ssh-askpass";
- private boolean firstLine = true;
- private CallbackHandler callbackHandler;
- /** Chroot to the this path (must not be empty) */
- private String chroot = null;
-
- // Current
- /** Current watchdog, null if process is completed */
- ExecuteWatchdog currentWatchdog = null;
-
- /** Empty constructor */
- public SystemCall() {
-
- }
-
- /**
- * Constructor based on the provided command list.
- *
- * @param command
- * the command list
- */
- public SystemCall(List<Object> command) {
- this.command = command;
- }
-
- /**
- * Constructor based on the provided command.
- *
- * @param cmd
- * the command. If the provided string contains no space a
- * command list is initialized with the argument as first
- * component (useful for chained construction)
- */
- public SystemCall(String cmd) {
- if (cmd.indexOf(' ') < 0) {
- command = new ArrayList<Object>();
- command.add(cmd);
- } else {
- this.cmd = cmd;
- }
- }
-
- /** Executes the system call. */
- public void run() {
- authentication = SecurityContextHolder.getContext().getAuthentication();
-
- // Manage streams
- Writer stdOutWriter = null;
- OutputStream stdOutputStream = null;
- Writer stdErrWriter = null;
- InputStream stdInStream = null;
- if (stdOutFile != null)
- if (redirectStdOut)
- stdOutputStream = createOutputStream(stdOutFile);
- else
- stdOutWriter = createWriter(stdOutFile, true);
-
- if (stdErrFile != null) {
- stdErrWriter = createWriter(stdErrFile, true);
- } else {
- if (stdOutFile != null && !redirectStdOut)
- stdErrWriter = createWriter(stdOutFile, true);
- }
-
- try {
- if (stdInFile != null)
- stdInStream = stdInFile.getInputStream();
- else {
- stdInStream = new PipedInputStream();
- stdInSink = new PipedOutputStream(
- (PipedInputStream) stdInStream);
- }
- } catch (IOException e2) {
- throw new SlcException("Cannot open a stream for " + stdInFile, e2);
- }
-
- if (log.isTraceEnabled()) {
- log.debug("os.name=" + System.getProperty("os.name"));
- log.debug("os.arch=" + System.getProperty("os.arch"));
- log.debug("os.version=" + System.getProperty("os.version"));
- }
-
- // Execution directory
- File dir = new File(getExecDirToUse());
- // if (!dir.exists())
- // dir.mkdirs();
-
- // Watchdog to check for lost processes
- Executor executorToUse;
- if (executor != null)
- executorToUse = executor;
- else
- executorToUse = new DefaultExecutor();
- executorToUse.setWatchdog(createWatchdog());
-
- if (redirectStreams) {
- // Redirect standard streams
- executorToUse.setStreamHandler(createExecuteStreamHandler(
- stdOutWriter, stdOutputStream, stdErrWriter, stdInStream));
- } else {
- // Dummy stream handler (otherwise pump is used)
- executorToUse.setStreamHandler(new DummyexecuteStreamHandler());
- }
-
- executorToUse.setProcessDestroyer(new ShutdownHookProcessDestroyer());
- executorToUse.setWorkingDirectory(dir);
-
- // Command line to use
- final CommandLine commandLine = createCommandLine();
- if (logCommand)
- log.info("Execute command:\n" + commandLine
- + "\n in working directory: \n" + dir + "\n");
-
- // Env variables
- Map<String, String> environmentVariablesToUse = null;
- environmentVariablesToUse = new HashMap<String, String>();
- if (mergeEnvironmentVariables)
- environmentVariablesToUse.putAll(System.getenv());
- if (environmentVariables.size() > 0)
- environmentVariablesToUse.putAll(environmentVariables);
-
- // Execute
- ExecuteResultHandler executeResultHandler = createExecuteResultHandler(commandLine);
-
- //
- // THE EXECUTION PROPER
- //
- try {
- if (synchronous)
- try {
- int exitValue = executorToUse.execute(commandLine,
- environmentVariablesToUse);
- executeResultHandler.onProcessComplete(exitValue);
- } catch (ExecuteException e1) {
- if (e1.getExitValue() == Executor.INVALID_EXITVALUE) {
- Thread.currentThread().interrupt();
- return;
- }
- // Sleep 1s in order to make sure error logs are flushed
- Thread.sleep(1000);
- executeResultHandler.onProcessFailed(e1);
- }
- else
- executorToUse.execute(commandLine, environmentVariablesToUse,
- executeResultHandler);
- } catch (SlcException e) {
- throw e;
- } catch (Exception e) {
- throw new SlcException("Could not execute command " + commandLine,
- e);
- } finally {
- IOUtils.closeQuietly(stdOutWriter);
- IOUtils.closeQuietly(stdErrWriter);
- IOUtils.closeQuietly(stdInStream);
- IOUtils.closeQuietly(stdInSink);
- }
-
- }
-
- public synchronized String function() {
- final StringBuffer buf = new StringBuffer("");
- SystemCallOutputListener tempOutputListener = new SystemCallOutputListener() {
- private Long lineCount = 0l;
-
- public void newLine(SystemCall systemCall, String line,
- Boolean isError) {
- if (!isError) {
- if (lineCount != 0l)
- buf.append('\n');
- buf.append(line);
- lineCount++;
- }
- }
- };
- addOutputListener(tempOutputListener);
- run();
- removeOutputListener(tempOutputListener);
- return buf.toString();
- }
-
- public String asCommand() {
- return createCommandLine().toString();
- }
-
- @Override
- public String toString() {
- return asCommand();
- }
-
- /**
- * Build a command line based on the properties. Can be overridden by
- * specific command wrappers.
- */
- protected CommandLine createCommandLine() {
- // Check if an OS specific command overrides
- String osName = System.getProperty("os.name");
- List<Object> commandToUse = null;
- if (osCommands.containsKey(osName))
- commandToUse = osCommands.get(osName);
- else
- commandToUse = command;
- String cmdToUse = null;
- if (osCmds.containsKey(osName))
- cmdToUse = osCmds.get(osName);
- else
- cmdToUse = cmd;
-
- CommandLine commandLine = null;
-
- // Which command definition to use
- if (commandToUse == null && cmdToUse == null)
- throw new SlcException("Please specify a command.");
- else if (commandToUse != null && cmdToUse != null)
- throw new SlcException(
- "Specify the command either as a line or as a list.");
- else if (cmdToUse != null) {
- if (chroot != null && !chroot.trim().equals(""))
- cmdToUse = "chroot \"" + chroot + "\" " + cmdToUse;
- if (sudo != null) {
- environmentVariables.put("SUDO_ASKPASS", askPassProgram);
- if (!sudo.trim().equals(""))
- cmdToUse = "sudo -p " + sudoPrompt + " -u " + sudo + " "
- + cmdToUse;
- else
- cmdToUse = "sudo -p " + sudoPrompt + " " + cmdToUse;
- }
-
- // GENERATE COMMAND LINE
- commandLine = CommandLine.parse(cmdToUse);
- } else if (commandToUse != null) {
- if (commandToUse.size() == 0)
- throw new SlcException("Command line is empty.");
-
- if (chroot != null && sudo != null) {
- commandToUse.add(0, "chroot");
- commandToUse.add(1, chroot);
- }
-
- if (sudo != null) {
- environmentVariables.put("SUDO_ASKPASS", askPassProgram);
- commandToUse.add(0, "sudo");
- commandToUse.add(1, "-p");
- commandToUse.add(2, sudoPrompt);
- if (!sudo.trim().equals("")) {
- commandToUse.add(3, "-u");
- commandToUse.add(4, sudo);
- }
- }
-
- // GENERATE COMMAND LINE
- commandLine = new CommandLine(commandToUse.get(0).toString());
-
- for (int i = 1; i < commandToUse.size(); i++) {
- if (log.isTraceEnabled())
- log.debug(commandToUse.get(i));
- commandLine.addArgument(commandToUse.get(i).toString());
- }
- } else {
- // all cases covered previously
- throw new UnsupportedException();
- }
-
- if (generateScript != null) {
- File scriptFile = new File(getExecDirToUse() + File.separator
- + generateScript);
- try {
- FileUtils.writeStringToFile(scriptFile,
- (osConsole != null ? osConsole + " " : "")
- + commandLine.toString());
- } catch (IOException e) {
- throw new SlcException("Could not generate script "
- + scriptFile, e);
- }
- commandLine = new CommandLine(scriptFile);
- } else {
- if (osConsole != null)
- commandLine = CommandLine.parse(osConsole + " "
- + commandLine.toString());
- }
-
- return commandLine;
- }
-
- /**
- * Creates a {@link PumpStreamHandler} which redirects streams to the custom
- * logging mechanism.
- */
- protected ExecuteStreamHandler createExecuteStreamHandler(
- final Writer stdOutWriter, final OutputStream stdOutputStream,
- final Writer stdErrWriter, final InputStream stdInStream) {
-
- // Log writers
- OutputStream stdout = stdOutputStream != null ? stdOutputStream
- : new LogOutputStream() {
- protected void processLine(String line, int level) {
- // if (firstLine) {
- // if (sudo != null && callbackHandler != null
- // && line.startsWith(sudoPrompt)) {
- // try {
- // PasswordCallback pc = new PasswordCallback(
- // "sudo password", false);
- // Callback[] cbs = { pc };
- // callbackHandler.handle(cbs);
- // char[] pwd = pc.getPassword();
- // char[] arr = Arrays.copyOf(pwd,
- // pwd.length + 1);
- // arr[arr.length - 1] = '\n';
- // IOUtils.write(arr, stdInSink);
- // stdInSink.flush();
- // } catch (Exception e) {
- // throw new SlcException(
- // "Cannot retrieve sudo password", e);
- // }
- // }
- // firstLine = false;
- // }
-
- if (line != null && !line.trim().equals(""))
- logStdOut(line);
-
- if (stdOutWriter != null)
- appendLineToFile(stdOutWriter, line);
- }
- };
-
- OutputStream stderr = new LogOutputStream() {
- protected void processLine(String line, int level) {
- if (line != null && !line.trim().equals(""))
- logStdErr(line);
- if (stdErrWriter != null)
- appendLineToFile(stdErrWriter, line);
- }
- };
-
- PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(stdout,
- stderr, stdInStream) {
-
- @Override
- public void stop() {
- // prevents the method to block when joining stdin
- if (stdInSink != null)
- IOUtils.closeQuietly(stdInSink);
-
- super.stop();
- }
- };
- return pumpStreamHandler;
- }
-
- /** Creates the default {@link ExecuteResultHandler}. */
- protected ExecuteResultHandler createExecuteResultHandler(
- final CommandLine commandLine) {
- return new ExecuteResultHandler() {
-
- public void onProcessComplete(int exitValue) {
- String msg = "System call '" + commandLine
- + "' properly completed.";
- if (log.isTraceEnabled())
- log.trace(msg);
- if (testResult != null) {
- forwardPath(testResult);
- testResult.addResultPart(new SimpleResultPart(
- TestStatus.PASSED, msg));
- }
- releaseWatchdog();
- }
-
- public void onProcessFailed(ExecuteException e) {
-
- String msg = "System call '" + commandLine + "' failed.";
- if (testResult != null) {
- forwardPath(testResult);
- testResult.addResultPart(new SimpleResultPart(
- TestStatus.ERROR, msg, e));
- } else {
- if (exceptionOnFailed)
- throw new SlcException(msg, e);
- else
- log.error(msg, e);
- }
- releaseWatchdog();
- }
- };
- }
-
- @Deprecated
- protected void forwardPath(TestResult testResult) {
- // TODO: allocate a TreeSPath
- }
-
- /**
- * Shortcut method getting the execDir to use
- */
- protected String getExecDirToUse() {
- try {
- if (execDir != null) {
- return execDir;
- }
- return System.getProperty("user.dir");
- } catch (Exception e) {
- throw new SlcException("Cannot find exec dir", e);
- }
- }
-
- protected void logStdOut(String line) {
- for (SystemCallOutputListener outputListener : outputListeners)
- outputListener.newLine(this, line, false);
- log(stdOutLogLevel, line);
- }
-
- protected void logStdErr(String line) {
- for (SystemCallOutputListener outputListener : outputListeners)
- outputListener.newLine(this, line, true);
- log(stdErrLogLevel, line);
- }
-
- /** Log from the underlying streams. */
- protected void log(String logLevel, String line) {
- // TODO optimize
- if (SecurityContextHolder.getContext().getAuthentication() == null) {
- SecurityContextHolder.getContext()
- .setAuthentication(authentication);
- }
-
- if ("ERROR".equals(logLevel))
- log.error(line);
- else if ("WARN".equals(logLevel))
- log.warn(line);
- else if ("INFO".equals(logLevel))
- log.info(line);
- else if ("DEBUG".equals(logLevel))
- log.debug(line);
- else if ("TRACE".equals(logLevel))
- log.trace(line);
- else if (LOG_STDOUT.equals(logLevel))
- System.out.println(line);
- else if ("System.err".equals(logLevel))
- System.err.println(line);
- else
- throw new SlcException("Unknown log level " + logLevel);
- }
-
- /** Append line to a log file. */
- protected void appendLineToFile(Writer writer, String line) {
- try {
- writer.append(line).append('\n');
- } catch (IOException e) {
- log.error("Cannot write to log file", e);
- }
- }
-
- /** Creates the writer for the output/err files. */
- protected Writer createWriter(Resource target, Boolean append) {
- FileWriter writer = null;
- try {
-
- final File file;
- if (executionResources != null)
- file = new File(executionResources.getAsOsPath(target, true));
- else
- file = target.getFile();
- writer = new FileWriter(file, append);
- } catch (IOException e) {
- log.error("Cannot get file for " + target, e);
- IOUtils.closeQuietly(writer);
- }
- return writer;
- }
-
- /** Creates an outputstream for the output/err files. */
- protected OutputStream createOutputStream(Resource target) {
- FileOutputStream out = null;
- try {
-
- final File file;
- if (executionResources != null)
- file = new File(executionResources.getAsOsPath(target, true));
- else
- file = target.getFile();
- out = new FileOutputStream(file, false);
- } catch (IOException e) {
- log.error("Cannot get file for " + target, e);
- IOUtils.closeQuietly(out);
- }
- return out;
- }
-
- /** Append the argument (for chaining) */
- public SystemCall arg(String arg) {
- if (command == null)
- command = new ArrayList<Object>();
- command.add(arg);
- return this;
- }
-
- /** Append the argument (for chaining) */
- public SystemCall arg(String arg, String value) {
- if (command == null)
- command = new ArrayList<Object>();
- command.add(arg);
- command.add(value);
- return this;
- }
-
- // CONTROL
- public synchronized Boolean isRunning() {
- return currentWatchdog != null;
- }
-
- private synchronized ExecuteWatchdog createWatchdog() {
-// if (currentWatchdog != null)
-// throw new SlcException("A process is already being monitored");
- currentWatchdog = new ExecuteWatchdog(watchdogTimeout);
- return currentWatchdog;
- }
-
- private synchronized void releaseWatchdog() {
- currentWatchdog = null;
- }
-
- public synchronized void kill() {
- if (currentWatchdog != null)
- currentWatchdog.destroyProcess();
- }
-
- /** */
- public void setCmd(String command) {
- this.cmd = command;
- }
-
- public void setCommand(List<Object> command) {
- this.command = command;
- }
-
- public void setExecDir(String execdir) {
- this.execDir = execdir;
- }
-
- public void setStdErrLogLevel(String stdErrLogLevel) {
- this.stdErrLogLevel = stdErrLogLevel;
- }
-
- public void setStdOutLogLevel(String stdOutLogLevel) {
- this.stdOutLogLevel = stdOutLogLevel;
- }
-
- public void setSynchronous(Boolean synchronous) {
- this.synchronous = synchronous;
- }
-
- public void setOsCommands(Map<String, List<Object>> osCommands) {
- this.osCommands = osCommands;
- }
-
- public void setOsCmds(Map<String, String> osCmds) {
- this.osCmds = osCmds;
- }
-
- public void setEnvironmentVariables(Map<String, String> environmentVariables) {
- this.environmentVariables = environmentVariables;
- }
-
- public Map<String, String> getEnvironmentVariables() {
- return environmentVariables;
- }
-
- public void setWatchdogTimeout(Long watchdogTimeout) {
- this.watchdogTimeout = watchdogTimeout;
- }
-
- public void setStdOutFile(Resource stdOutFile) {
- this.stdOutFile = stdOutFile;
- }
-
- public void setStdErrFile(Resource stdErrFile) {
- this.stdErrFile = stdErrFile;
- }
-
- public void setStdInFile(Resource stdInFile) {
- this.stdInFile = stdInFile;
- }
-
- public void setTestResult(TestResult testResult) {
- this.testResult = testResult;
- }
-
- public void setLogCommand(Boolean logCommand) {
- this.logCommand = logCommand;
- }
-
- public void setRedirectStreams(Boolean redirectStreams) {
- this.redirectStreams = redirectStreams;
- }
-
- public void setExceptionOnFailed(Boolean exceptionOnFailed) {
- this.exceptionOnFailed = exceptionOnFailed;
- }
-
- public void setMergeEnvironmentVariables(Boolean mergeEnvironmentVariables) {
- this.mergeEnvironmentVariables = mergeEnvironmentVariables;
- }
-
- public void setOsConsole(String osConsole) {
- this.osConsole = osConsole;
- }
-
- public void setGenerateScript(String generateScript) {
- this.generateScript = generateScript;
- }
-
- public void setExecutionResources(ExecutionResources executionResources) {
- this.executionResources = executionResources;
- }
-
- public void setRedirectStdOut(Boolean redirectStdOut) {
- this.redirectStdOut = redirectStdOut;
- }
-
- public void addOutputListener(SystemCallOutputListener outputListener) {
- outputListeners.add(outputListener);
- }
-
- public void removeOutputListener(SystemCallOutputListener outputListener) {
- outputListeners.remove(outputListener);
- }
-
- public void setOutputListeners(
- List<SystemCallOutputListener> outputListeners) {
- this.outputListeners = outputListeners;
- }
-
- public void setExecutor(Executor executor) {
- this.executor = executor;
- }
-
- public void setSudo(String sudo) {
- this.sudo = sudo;
- }
-
- public void setCallbackHandler(CallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
- }
-
- public void setChroot(String chroot) {
- this.chroot = chroot;
- }
-
- private class DummyexecuteStreamHandler implements ExecuteStreamHandler {
-
- public void setProcessErrorStream(InputStream is) throws IOException {
- }
-
- public void setProcessInputStream(OutputStream os) throws IOException {
- }
-
- public void setProcessOutputStream(InputStream is) throws IOException {
- }
-
- public void start() throws IOException {
- }
-
- public void stop() {
- }
-
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-public interface SystemCallOutputListener {
- public void newLine(SystemCall systemCall, String line, Boolean isError);
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import org.argeo.slc.SlcException;
-import org.argeo.slc.core.attachment.Attachment;
-import org.argeo.slc.core.attachment.AttachmentUploader;
-import org.argeo.slc.core.attachment.AttachmentsEnabled;
-import org.springframework.core.io.Resource;
-
-public class UploadAttachments implements Runnable {
- private AttachmentUploader attachmentUploader;
- private Attachment attachment = null;
- private Resource resource = null;
- private Map<Attachment, Resource> attachments = new HashMap<Attachment, Resource>();
- private List<AttachmentsEnabled> attachTo = new ArrayList<AttachmentsEnabled>();
- private Boolean newUuidPerExecution = true;
-
- public void run() {
- if (attachment != null) {
- if (resource == null)
- throw new SlcException("A resource must be specified.");
- uploadAndAdd(attachment, resource);
- }
-
- for (Attachment attachmentT : attachments.keySet()) {
- Resource resourceT = attachments.get(attachmentT);
- uploadAndAdd(attachmentT, resourceT);
- }
-
- }
-
- protected void uploadAndAdd(Attachment attachment, Resource resource) {
- if (newUuidPerExecution)
- attachment.setUuid(UUID.randomUUID().toString());
- attachmentUploader.upload(attachment, resource);
- for (AttachmentsEnabled attachmentsEnabled : attachTo) {
- attachmentsEnabled.addAttachment(attachment);
- }
- }
-
- public void setAttachmentUploader(AttachmentUploader attachmentUploader) {
- this.attachmentUploader = attachmentUploader;
- }
-
- public void setAttachments(Map<Attachment, Resource> attachments) {
- this.attachments = attachments;
- }
-
- public void setAttachTo(List<AttachmentsEnabled> attachTo) {
- this.attachTo = attachTo;
- }
-
- public void setAttachment(Attachment attachment) {
- this.attachment = attachment;
- }
-
- public void setResource(Resource resource) {
- this.resource = resource;
- }
-
- public void setNewUuidPerExecution(Boolean newUuidPerExecution) {
- this.newUuidPerExecution = newUuidPerExecution;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.core.execution.DefaultExecutionFlow;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.springframework.beans.factory.config.BeanDefinitionHolder;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.ManagedList;
-import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Node;
-
-/** Publishes a {@link Runnable} as an {@link ExecutionFlow} */
-public class AsFlowDecorator implements BeanDefinitionDecorator {
- private Log log = LogFactory.getLog(AsFlowDecorator.class);
-
- @SuppressWarnings("unchecked")
- public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder bean,
- ParserContext ctx) {
- String attrValue = ((Attr) node).getValue();
- if (attrValue.charAt(attrValue.length() - 1) == '/')
- throw new SlcException(attrValue + " cannot end with a path");
- final String flowBeanName = attrValue;
-
- if (log.isTraceEnabled())
- log.trace("flowBeanName=" + flowBeanName);
-
- if (ctx.getRegistry().containsBeanDefinition(flowBeanName))
- throw new SlcException("A bean named " + flowBeanName
- + " is already defined.");
- BeanDefinitionBuilder flow = BeanDefinitionBuilder
- .rootBeanDefinition(DefaultExecutionFlow.class);
- ManagedList executables = new ManagedList(1);
-
- String beanName = bean.getBeanName();
- if (beanName == null)
- executables.add(bean.getBeanDefinition());
- else
- executables.add(new RuntimeBeanReference(beanName));
-
- // if (path != null)
- // flow.addPropertyValue("path", path);
- flow.addPropertyValue("executables", executables);
-
- if (beanName != null)
- ctx.getRegistry().registerBeanDefinition(flowBeanName,
- flow.getBeanDefinition());
- return bean;
- }
-
-}
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.xml;\r
-\r
-import org.springframework.aop.scope.ScopedProxyUtils;\r
-import org.springframework.beans.factory.config.BeanDefinitionHolder;\r
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;\r
-import org.springframework.beans.factory.xml.BeanDefinitionDecorator;\r
-import org.springframework.beans.factory.xml.ParserContext;\r
-import org.w3c.dom.Element;\r
-import org.w3c.dom.Node;\r
-\r
-/**\r
- * Inspired by org.springframework.aop.config.ScopedProxyBeanDefinitionDecorator\r
- */\r
-public class ExecutionScopeDecorator implements BeanDefinitionDecorator { \r
- private static final String PROXY_TARGET_CLASS = "proxy-target-class"; \r
- \r
- public BeanDefinitionHolder decorate(Node node,\r
- BeanDefinitionHolder definition, ParserContext parserContext) {\r
- \r
- definition.getBeanDefinition().setScope("execution");\r
- \r
- // Default: CGLib not used\r
- boolean proxyTargetClass = false;\r
- if (node instanceof Element) {\r
- Element ele = (Element) node;\r
- if (ele.hasAttribute(PROXY_TARGET_CLASS)) {\r
- proxyTargetClass = Boolean.valueOf(ele.getAttribute(PROXY_TARGET_CLASS)).booleanValue();\r
- }\r
- }\r
- \r
- // Register the original bean definition as it will be referenced by the scoped proxy and is relevant for tooling (validation, navigation).\r
- String targetBeanName = ScopedProxyUtils.getTargetBeanName(definition.getBeanName());\r
- parserContext.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(definition.getBeanDefinition(), targetBeanName));\r
- \r
- return ScopedProxyUtils.createScopedProxy(definition, parserContext.getRegistry(), proxyTargetClass); \r
- }\r
-}\r
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.core.execution.DefaultExecutionFlow;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.springframework.beans.factory.BeanDefinitionStoreException;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.ManagedList;
-import org.springframework.beans.factory.support.ManagedMap;
-import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.util.StringUtils;
-import org.springframework.util.xml.DomUtils;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/** Interprets the <flow:flow> tag */
-public class FlowBeanDefinitionParser extends
- AbstractSingleBeanDefinitionParser {
- private Log log = LogFactory.getLog(FlowBeanDefinitionParser.class);
-
- /** Whether the user has already be warned on path attribute usage. */
- private Boolean warnedAboutPathAttribute = false;
-
- @SuppressWarnings("unchecked")
- @Override
- protected void doParse(Element element, ParserContext parserContext,
- BeanDefinitionBuilder builder) {
- String path = element.getAttribute("path");
- if (StringUtils.hasText(path)) {
- builder.addPropertyValue("path", path);
-
- // warns user only once
- if (!warnedAboutPathAttribute)
- log.warn("The path=\"\" attribute is deprecated"
- + " and will be removed in a later release."
- + " Use <flow:flow name=\"/my/path/flowName\">.");
- warnedAboutPathAttribute = true;
- }
-
- String spec = element.getAttribute("spec");
- if (StringUtils.hasText(spec))
- builder.getBeanDefinition().getConstructorArgumentValues()
- .addGenericArgumentValue(new RuntimeBeanReference(spec));
-
- String abstrac = element.getAttribute("abstract");
- if (StringUtils.hasText(abstrac))
- builder.setAbstract(Boolean.parseBoolean(abstrac));
-
- String parent = element.getAttribute("parent");
- if (StringUtils.hasText(parent))
- builder.setParentName(parent);
-
- builder.getBeanDefinition().setDescription(
- DomUtils.getChildElementValueByTagName(element, "description"));
-
- List<Element> argsElems = new ArrayList<Element>();
- List<Element> execElems = new ArrayList<Element>();
- List<Element> specElems = new ArrayList<Element>();
- NodeList nodeList = element.getChildNodes();
- for (int i = 0; i < nodeList.getLength(); i++) {
- Node node = nodeList.item(i);
- if (node instanceof Element) {
- if (DomUtils.nodeNameEquals(node, "arg"))
- argsElems.add((Element) node);
- else if (DomUtils.nodeNameEquals(node, "spec"))
- specElems.add((Element) node);
- else if (!DomUtils.nodeNameEquals(node, "description"))
- execElems.add((Element) node);
- }
- }
-
- // Arguments
- if (argsElems.size() != 0) {
- ManagedMap args = new ManagedMap(argsElems.size());
- for (Element argElem : argsElems) {
- Object value = NamespaceUtils.parseValue(argElem,
- parserContext, builder.getBeanDefinition(), null);
- if (value != null)
- args.put(argElem.getAttribute("name"), value);
- else
- throw new SlcException("No value defined.");
- }
- builder.getBeanDefinition().getConstructorArgumentValues()
- .addGenericArgumentValue(args);
- }
-
- // Execution specs
- if (StringUtils.hasText(spec) && specElems.size() != 0)
- throw new SlcException("A flow cannot have multiple specs");
- if (specElems.size() == 1) {
- Object specObj = NamespaceUtils.parseBeanOrReference(
- specElems.get(0), parserContext,
- builder.getBeanDefinition());
- builder.getBeanDefinition().getConstructorArgumentValues()
- .addGenericArgumentValue(specObj);
- } else if (specElems.size() > 1)
- throw new SlcException("A flow cannot have multiple specs");
-
- // Executables
- if (execElems.size() != 0) {
- ManagedList executables = new ManagedList(execElems.size());
- for (Element child : execElems) {
- // child validity check is performed in xsd
- executables.add(NamespaceUtils.parseBeanOrReference(child,
- parserContext, builder.getBeanDefinition()));
- }
- if (executables.size() > 0)
- builder.addPropertyValue("executables", executables);
- }
- }
-
- @SuppressWarnings("unchecked")
- @Override
- protected Class<? extends ExecutionFlow> getBeanClass(Element element) {
- String clss = element.getAttribute("class");
- if (StringUtils.hasText(clss))
- // TODO: check that it actually works
- try {
- return (Class<? extends ExecutionFlow>) getClass()
- .getClassLoader().loadClass(clss);
- } catch (ClassNotFoundException e) {
- try {
- return (Class<? extends ExecutionFlow>) Thread
- .currentThread().getContextClassLoader()
- .loadClass(clss);
- } catch (ClassNotFoundException e1) {
- throw new SlcException("Cannot load class " + clss, e);
- }
- }
- else
- return DefaultExecutionFlow.class;
- }
-
- // parse nested bean definition
- // private Object parseBeanReference(Element element,
- // ParserContext parserContext, BeanDefinitionBuilder builder) {
- // return parserContext.getDelegate().parsePropertySubElement(element,
- // builder.getBeanDefinition());
- // }
-
- @Override
- protected String resolveId(Element element,
- AbstractBeanDefinition definition, ParserContext parserContext)
- throws BeanDefinitionStoreException {
- String name = element.getAttribute("name");
- if (StringUtils.hasText(name)) {
- return name;
- } else {
- return super.resolveId(element, definition, parserContext);
- }
- }
-
- protected boolean shouldGenerateIdAsFallback() {
- return true;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
-
-public class FlowNamespaceHandler extends NamespaceHandlerSupport {
-
- public void init() {
- registerBeanDefinitionParser("flow", new FlowBeanDefinitionParser());
- registerBeanDefinitionParser("spec", new SpecBeanDefinitionParser());
- registerBeanDefinitionDecoratorForAttribute("as-flow",
- new AsFlowDecorator());
- registerBeanDefinitionParser("param", new ParamDecorator());
-
- // The objective was to replace
- // - attribute scope="execution"
- // - and element "aop:scoped-proxy"
- // by a single attribute, using an attribute decorator
- // this does not work correctly with other attribute decorators (e.g.
- // p namespace) since this decorator needs to be called after all
- // properties have been set on target bean.
- // It works properly with element decorators (called after all attribute
- // decorators
- registerBeanDefinitionDecorator("variable", new ExecutionScopeDecorator());
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.util.xml.DomUtils;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Utilities to simplify common tasks when interpreting a custom namespace and
- * converting it into bean definitions.
- */
-public class NamespaceUtils {
- // private final static Log log = LogFactory.getLog(NamespaceUtils.class);
-
- /**
- * Returns the value defined either: directly by the the 'value' attribute,
- * as reference by the 'ref' attribute or as a nested bean.
- */
- public static Object parseValue(Element element,
- ParserContext parserContext,
- BeanDefinition containingBeanDefintion, String valueTagName) {
- Object value = null;
- if (element.hasAttribute("value")) {
- value = element.getAttribute("value");
- }
-
- if (element.hasAttribute("ref")) {
- if (value != null)
- throw new SlcException("Multiple value definition for "
- + element);
- value = new RuntimeBeanReference(element.getAttribute("ref"));
- }
-
- Element uniqueSubElem = null;
- if (valueTagName != null) {
- Element valueElem = DomUtils.getChildElementByTagName(element,
- valueTagName);
- if (valueElem != null) {
- uniqueSubElem = findUniqueSubElement(valueElem);
- if (uniqueSubElem == null)
- throw new SlcException("No subelement found under "
- + valueElem);
- }
- } else {// no intermediary tag
- uniqueSubElem = findUniqueSubElement(element);
- }
-
- if (uniqueSubElem != null) {
- if (value != null)
- throw new SlcException("Multiple value definition for "
- + element);
- value = parseBeanOrReference(uniqueSubElem, parserContext,
- containingBeanDefintion);
- }
- return value;
- }
-
- public static Element findUniqueSubElement(Element element) {
- NodeList childNodes = element.getChildNodes();
-
- Element uniqueSubElem = null;
- for (int i = 0; i < childNodes.getLength(); i++) {
- Node node = childNodes.item(i);
- if (node != null && node instanceof Element) {
- if (uniqueSubElem == null)
- uniqueSubElem = (Element) node;
- else
- throw new SlcException(
- "There are more than one sub element under "
- + element);
- }
- }
- return uniqueSubElem;
- }
-
- public static Object parseBeanOrReference(Element element,
- ParserContext parserContext, BeanDefinition beanDefinition) {
- // return parserContext.getDelegate().parsePropertySubElement(element,
- // beanDefinition);
-
- BeanDefinitionParserDelegate deleg = parserContext.getDelegate();
- // if ("bean".equals(element.getNodeName()))
- // return deleg.parseBeanDefinitionElement(element, beanDefinition);
- // else
- return deleg.parsePropertySubElement(element, beanDefinition);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import org.argeo.slc.core.execution.ParameterRef;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.util.StringUtils;
-import org.w3c.dom.Element;
-
-public class ParamDecorator extends AbstractSingleBeanDefinitionParser {
-
- // public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder
- // bean,
- // ParserContext ctx) {
- // String paramName = ((Element) node).getAttribute("name");
- // String propertyName = ((Element) node.getParentNode())
- // .getAttribute("name");
- // BeanDefinitionBuilder parameterRef = BeanDefinitionBuilder
- // .genericBeanDefinition(ParameterRef.class);
- // parameterRef.addPropertyReference("instantiationManager",
- // "instantiationManager");
- // parameterRef.addConstructorArgValue(paramName);
- // bean.getBeanDefinition().getPropertyValues().addPropertyValue(
- // propertyName, parameterRef.getBeanDefinition());
- // return bean;
- // }
-
- @Override
- protected void doParse(Element element, ParserContext parserContext,
- BeanDefinitionBuilder builder) {
- String paramName = element.getAttribute("name");
-
- String instantationManagerRef = element
- .getAttribute("instantiationManager");
- if (!StringUtils.hasText(instantationManagerRef))
- instantationManagerRef = "instantiationManager";
- builder.addPropertyReference("instantiationManager",
- instantationManagerRef);
- builder.addConstructorArgValue(paramName);
- }
-
- @Override
- protected Class<ParameterRef> getBeanClass(Element element) {
- return ParameterRef.class;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.core.execution.DefaultExecutionSpec;
-import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
-import org.argeo.slc.core.execution.RefSpecAttribute;
-import org.argeo.slc.core.execution.RefValueChoice;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.ManagedList;
-import org.springframework.beans.factory.support.ManagedMap;
-import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.util.StringUtils;
-import org.springframework.util.xml.DomUtils;
-import org.w3c.dom.Element;
-
-/** Interprets the <flow:spec> tag */
-public class SpecBeanDefinitionParser extends
- AbstractSingleBeanDefinitionParser {
- private Log log = LogFactory.getLog(SpecBeanDefinitionParser.class);
-
- @SuppressWarnings("unchecked")
- @Override
- protected void doParse(Element element, ParserContext parserContext,
- BeanDefinitionBuilder builder) {
- builder.getBeanDefinition().setDescription(
- DomUtils.getChildElementValueByTagName(element, "description"));
-
- ManagedMap attributes = new ManagedMap();
-
- // Primitives
- for (Element child : (List<Element>) DomUtils
- .getChildElementsByTagName(element, "primitive")) {
- BeanDefinitionBuilder childBuilder = BeanDefinitionBuilder
- .genericBeanDefinition(PrimitiveSpecAttribute.class);
- addCommonProperties(child, parserContext, childBuilder);
-
- String type = child.getAttribute("type");
- if (StringUtils.hasText(type))
- childBuilder.addPropertyValue("type", type);
-
- putInAttributes(attributes, child,
- childBuilder.getBeanDefinition(), "primitive");
- }
-
- // Refs
- for (Element refAttrElem : (List<Element>) DomUtils
- .getChildElementsByTagName(element, "ref")) {
- BeanDefinitionBuilder refAttrBuilder = BeanDefinitionBuilder
- .genericBeanDefinition(RefSpecAttribute.class);
- addCommonProperties(refAttrElem, parserContext, refAttrBuilder);
-
- String targetClassName = refAttrElem.getAttribute("targetClass");
- if (StringUtils.hasText(targetClassName))
- refAttrBuilder.addPropertyValue("targetClass", targetClassName);
-
- // Choices
- Element choicesElem = DomUtils.getChildElementByTagName(
- refAttrElem, "choices");
- if (choicesElem != null) {
- List<Element> choices = DomUtils.getChildElementsByTagName(
- choicesElem, "choice");
- ManagedList choiceBeans = new ManagedList(choices.size());
- for (Element choiceElem : choices) {
- BeanDefinitionBuilder choiceBuilder = BeanDefinitionBuilder
- .genericBeanDefinition(RefValueChoice.class);
- choiceBuilder.addPropertyValue("name",
- choiceElem.getAttribute("name"));
- String desc = choiceElem.getAttribute("description");
- if (StringUtils.hasText(desc))
- choiceBuilder.addPropertyValue("description", desc);
-
- choiceBeans.add(choiceBuilder.getBeanDefinition());
- }
- refAttrBuilder.addPropertyValue("choices", choiceBeans);
- }
-
- putInAttributes(attributes, refAttrElem,
- refAttrBuilder.getBeanDefinition(), "ref");
- }
-
- builder.addPropertyValue("attributes", attributes);
- }
-
- protected void addCommonProperties(Element element,
- ParserContext parserContext, BeanDefinitionBuilder specAttr) {
- addBooleanProperty("isImmutable", specAttr, element);
- addBooleanProperty("isConstant", specAttr, element);
- addBooleanProperty("isHidden", specAttr, element);
- addBooleanProperty("isParameter", specAttr, element);
- addBooleanProperty("isFrozen", specAttr, element);
-
- Object value = NamespaceUtils.parseValue(element, parserContext,
- specAttr.getBeanDefinition(), "value");
- if (value != null)
- specAttr.addPropertyValue("value", value);
-
- }
-
- @SuppressWarnings("unchecked")
- protected void putInAttributes(ManagedMap attributes, Element child,
- BeanDefinition beanDefinition, String nature) {
- String name = child.getAttribute("name");
- attributes.put(name, beanDefinition);
- if (log.isTraceEnabled())
- log.debug("Added " + nature + " attribute " + name);
-
- }
-
- private void addBooleanProperty(String name,
- BeanDefinitionBuilder specAttr, Element element) {
- String bool = element.getAttribute(name);
- if (StringUtils.hasText(bool))
- specAttr.addPropertyValue(name, Boolean.parseBoolean(bool));
-
- }
-
- @Override
- protected Class<DefaultExecutionSpec> getBeanClass(Element element) {
- return DefaultExecutionSpec.class;
- }
-
- protected boolean shouldGenerateIdAsFallback() {
- return false;
- }
-
-}
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import org.argeo.slc.test.TestData;\r
-\r
-public class BasicTestData implements TestData {\r
- private Object expected;\r
- private Object reached;\r
-\r
- public Object getExpected() {\r
- return expected;\r
- }\r
-\r
- public void setExpected(Object expected) {\r
- this.expected = expected;\r
- }\r
-\r
- public Object getReached() {\r
- return reached;\r
- }\r
-\r
- public void setReached(Object reached) {\r
- this.reached = reached;\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.core.test.context.ContextUtils;\r
-import org.argeo.slc.test.IncompatibleTestDataException;\r
-import org.argeo.slc.test.TestData;\r
-import org.argeo.slc.test.TestDefinition;\r
-import org.argeo.slc.test.TestResult;\r
-import org.argeo.slc.test.TestRun;\r
-import org.argeo.slc.test.TestStatus;\r
-import org.argeo.slc.test.context.ContextAware;\r
-\r
-/** Understands basic test data and context aware test data. */\r
-public class BasicTestDefinition implements TestDefinition {\r
-\r
- public void execute(TestRun testRun) {\r
- if (testRun.<TestData> getTestData() instanceof BasicTestData) {\r
- BasicTestData testData = testRun.getTestData();\r
- TestResult result = testRun.getTestResult();\r
-\r
- if (result == null)\r
- throw new SlcException("No test result defined.");\r
-\r
- try {\r
- if (testData.getExpected().equals(testData.getReached())) {\r
- result.addResultPart(new SimpleResultPart(\r
- TestStatus.PASSED, "Reached and expected equals"));\r
- } else {\r
- result.addResultPart(new SimpleResultPart(\r
- TestStatus.FAILED, "Expected "\r
- + testData.getExpected() + " but reached "\r
- + testData.getReached()));\r
- }\r
- } catch (Exception e) {\r
- result.addResultPart(new SimpleResultPart(TestStatus.ERROR,\r
- "Could not compare", e));\r
- }\r
- } else if (testRun.<TestData> getTestData() instanceof ContextAware) {\r
- TestData testData = testRun.getTestData();\r
- ContextUtils.compareReachedExpected((ContextAware) testData,\r
- testRun.getTestResult());\r
- } else {\r
- throw new IncompatibleTestDataException(testRun);\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import java.io.Serializable;\r
-\r
-import org.argeo.slc.test.TestResultPart;\r
-import org.argeo.slc.test.TestRun;\r
-import org.argeo.slc.test.TestRunAware;\r
-import org.argeo.slc.test.TestStatus;\r
-\r
-/**\r
- * <p>\r
- * Basic implementation of a result part, implementing the standard three status\r
- * approach for test results.\r
- * </p>\r
- * \r
- * @see TestStatus\r
- */\r
-public class SimpleResultPart implements TestResultPart, TestStatus,\r
- TestRunAware, Serializable {\r
- private static final long serialVersionUID = 6669675957685071901L;\r
-\r
- private Long tid;\r
-\r
- private String testRunUuid;\r
-\r
- /** The status. Default to ERROR since it should always be explicitely set. */\r
- private Integer status = ERROR;\r
- private String message;\r
- private String exceptionMessage;\r
-\r
- public SimpleResultPart() {\r
- }\r
-\r
- public SimpleResultPart(Integer status, String message) {\r
- this(status, message, null);\r
- }\r
-\r
- public SimpleResultPart(Integer status, String message, Exception exception) {\r
- this.status = status;\r
- this.message = message;\r
- setException(exception);\r
- }\r
-\r
- public String getMessage() {\r
- return message;\r
- }\r
-\r
- public void setMessage(String message) {\r
- this.message = message;\r
- }\r
-\r
- public void setStatus(Integer status) {\r
- this.status = status;\r
- }\r
-\r
- public Integer getStatus() {\r
- return status;\r
- }\r
-\r
- public String getExceptionMessage() {\r
- return exceptionMessage;\r
- }\r
-\r
- public void setException(Exception exception) {\r
- if (exception == null)\r
- return;\r
-\r
- StringBuffer buf = new StringBuffer("");\r
- buf.append(exception.toString());\r
- buf.append('\n');\r
- for (StackTraceElement elem : exception.getStackTrace()) {\r
- buf.append('\t').append(elem.toString()).append('\n');\r
- }\r
-\r
- if (exception.getCause() != null)\r
- addRootCause(buf, exception.getCause());\r
-\r
- this.exceptionMessage = buf.toString();\r
- }\r
-\r
- protected void addRootCause(StringBuffer buf, Throwable cause) {\r
- if (cause == null)\r
- return;\r
-\r
- buf.append("Caused by: " + cause.getMessage());\r
- for (StackTraceElement elem : cause.getStackTrace()) {\r
- buf.append('\t').append(elem.toString()).append('\n');\r
- }\r
-\r
- if (cause.getCause() != null) {\r
- addRootCause(buf, cause.getCause());\r
- }\r
- }\r
-\r
- @Override\r
- public String toString() {\r
- StringBuffer buf = new StringBuffer("");\r
- buf.append(SlcTestUtils.statusToString(status));\r
- if (status == PASSED || status == FAILED) {\r
- buf.append(' ');\r
- } else if (status == ERROR) {\r
- buf.append(" ");\r
- }\r
- buf.append(message);\r
- return buf.toString();\r
- }\r
-\r
- /** @deprecated */\r
- Long getTid() {\r
- return tid;\r
- }\r
-\r
- /** @deprecated */\r
- void setTid(Long tid) {\r
- this.tid = tid;\r
- }\r
-\r
- public String getTestRunUuid() {\r
- return testRunUuid;\r
- }\r
-\r
- /** For ORM */\r
- public void setTestRunUuid(String testRunUuid) {\r
- this.testRunUuid = testRunUuid;\r
- }\r
-\r
- public void notifyTestRun(TestRun testRun) {\r
- testRunUuid = testRun.getUuid();\r
- }\r
-\r
- public void setExceptionMessage(String exceptionMessage) {\r
- this.exceptionMessage = exceptionMessage;\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import java.util.Date;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.TreeMap;\r
-import java.util.UUID;\r
-import java.util.Vector;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.test.TestResult;\r
-import org.argeo.slc.test.TestResultPart;\r
-import org.argeo.slc.test.TestRun;\r
-\r
-/**\r
- * Basic implementation of a test result containing only a list of result parts.\r
- */\r
-public class SimpleTestResult implements TestResult {\r
- private static Log log = LogFactory.getLog(SimpleTestResult.class);\r
-\r
- private String uuid;\r
- private String currentTestRunUuid;\r
-\r
- private Boolean throwError = true;\r
-\r
- private Date closeDate;\r
- private List<TestResultPart> parts = new Vector<TestResultPart>();\r
-\r
- private Map<String, String> attributes = new TreeMap<String, String>();\r
-\r
- public void addResultPart(TestResultPart part) {\r
- if (throwError && part.getStatus() == ERROR) {\r
- throw new SlcException(\r
- "There was an error in the underlying test: "\r
- + part.getExceptionMessage());\r
- }\r
- parts.add(part);\r
- if (log.isDebugEnabled())\r
- log.debug(part);\r
- }\r
-\r
- public void close() {\r
- parts.clear();\r
- closeDate = new Date();\r
- }\r
-\r
- public List<TestResultPart> getParts() {\r
- return parts;\r
- }\r
-\r
- public Date getCloseDate() {\r
- return closeDate;\r
- }\r
-\r
- public void setThrowError(Boolean throwError) {\r
- this.throwError = throwError;\r
- }\r
-\r
- public void notifyTestRun(TestRun testRun) {\r
- currentTestRunUuid = testRun.getUuid();\r
- }\r
-\r
- public String getUuid() {\r
- if (uuid == null) {\r
- uuid = UUID.randomUUID().toString();\r
- }\r
- return uuid;\r
- }\r
-\r
- public void setUuid(String uuid) {\r
- this.uuid = uuid;\r
- }\r
-\r
- public String getCurrentTestRunUuid() {\r
- return currentTestRunUuid;\r
- }\r
-\r
- public Map<String, String> getAttributes() {\r
- return attributes;\r
- }\r
-\r
- public void setAttributes(Map<String, String> attributes) {\r
- this.attributes = attributes;\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import java.util.UUID;\r
-\r
-import org.argeo.slc.deploy.DeployedSystem;\r
-import org.argeo.slc.test.ExecutableTestRun;\r
-import org.argeo.slc.test.TestData;\r
-import org.argeo.slc.test.TestDefinition;\r
-import org.argeo.slc.test.TestResult;\r
-import org.argeo.slc.test.WritableTestRun;\r
-\r
-/**\r
- * A basic bean implementation of a <code>WritableTestRun</code>, holding\r
- * references to the various parts of a test run.\r
- */\r
-public class SimpleTestRun implements WritableTestRun, ExecutableTestRun {\r
- private String uuid;\r
-\r
- // private String slcExecutionUuid;\r
- // private String slcExecutionStepUuid;\r
-\r
- private DeployedSystem deployedSystem;\r
- private TestData testData;\r
- private TestDefinition testDefinition;\r
- private TestResult testResult;\r
-\r
- /** Executes the underlying test definition. */\r
- public void run() {\r
- uuid = UUID.randomUUID().toString();\r
- if (testResult != null)\r
- testResult.notifyTestRun(this);\r
-\r
- testDefinition.execute(this);\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public <T extends DeployedSystem> T getDeployedSystem() {\r
- return (T) deployedSystem;\r
- }\r
-\r
- public void setDeployedSystem(DeployedSystem deployedSystem) {\r
- this.deployedSystem = deployedSystem;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public <T extends TestData> T getTestData() {\r
- return (T) testData;\r
- }\r
-\r
- public void setTestData(TestData testData) {\r
- this.testData = testData;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public <T extends TestDefinition> T getTestDefinition() {\r
- return (T) testDefinition;\r
- }\r
-\r
- public void setTestDefinition(TestDefinition testDefinition) {\r
- this.testDefinition = testDefinition;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public <T extends TestResult> T getTestResult() {\r
- return (T) testResult;\r
- }\r
-\r
- public void setTestResult(TestResult testResult) {\r
- this.testResult = testResult;\r
- }\r
-\r
- public String getUuid() {\r
- return uuid;\r
- }\r
-\r
- public void setUuid(String uuid) {\r
- this.uuid = uuid;\r
- }\r
-\r
- // public String getSlcExecutionUuid() {\r
- // return slcExecutionUuid;\r
- // }\r
- //\r
- // public void setSlcExecutionUuid(String slcExecutionUuid) {\r
- // this.slcExecutionUuid = slcExecutionUuid;\r
- // }\r
- //\r
- // public String getSlcExecutionStepUuid() {\r
- // return slcExecutionStepUuid;\r
- // }\r
- //\r
- // public void setSlcExecutionStepUuid(String slcExecutionStepUuid) {\r
- // this.slcExecutionStepUuid = slcExecutionStepUuid;\r
- // }\r
-}\r
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.test;
-
-import org.argeo.slc.SlcException;
-import org.argeo.slc.test.TestStatus;
-
-public abstract class SlcTestUtils {
- public static String statusToString(Integer status) {
- if (status.equals(TestStatus.PASSED)) {
- return TestStatus.STATUSSTR_PASSED;
- } else if (status.equals(TestStatus.FAILED)) {
- return TestStatus.STATUSSTR_FAILED;
- } else if (status.equals(TestStatus.ERROR)) {
- return TestStatus.STATUSSTR_ERROR;
- } else {
- throw new SlcException("Unrecognized status " + status);
- }
- }
-
- public static Integer stringToStatus(String statusStr) {
- if (statusStr.equals(TestStatus.STATUSSTR_PASSED)) {
- return TestStatus.PASSED;
- } else if (statusStr.equals(TestStatus.STATUSSTR_FAILED)) {
- return TestStatus.FAILED;
- } else if (statusStr.equals(TestStatus.STATUSSTR_ERROR)) {
- return TestStatus.ERROR;
- } else {
- throw new SlcException("Unrecognized status string " + statusStr);
- }
- }
-
- private SlcTestUtils() {
-
- }
-
-}
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test;\r
-\r
-import org.argeo.slc.UnsupportedException;\r
-import org.argeo.slc.test.TestData;\r
-import org.argeo.slc.test.TestDataProvider;\r
-\r
-/** Utilities for dealing with test datas. */\r
-public class TestDataUtils {\r
- /** Extracts the test data from the given provider. */\r
- public static <T extends TestData> T getFromProvider(Object obj,\r
- Class<T> clss, String key) {\r
- if (obj instanceof TestDataProvider) {\r
- TestDataProvider testDataProvider = (TestDataProvider) obj;\r
- return testDataProvider.getTestData(clss, key);\r
- } else {\r
- throw new UnsupportedException("test data provider", obj);\r
- }\r
- }\r
-\r
- /**\r
- * Extracts the test data from the given provider using <code>null</code>\r
- * as key.\r
- */\r
- public static <T extends TestData> T getFromProvider(Object obj,\r
- Class<T> clss) {\r
- return getFromProvider(obj, clss, null);\r
- }\r
-\r
- /**\r
- * Returns it self after making the proper checks. Used for test data being\r
- * their own data providers.\r
- */\r
- @SuppressWarnings("unchecked")\r
- public static <T extends TestData> T getItSelf(Class<T> clss,\r
- TestData testDataObject) {\r
- if (clss.isAssignableFrom(testDataObject.getClass())) {\r
- return (T) testDataObject;\r
- } else {\r
- throw new UnsupportedException("test data", testDataObject);\r
- }\r
-\r
- }\r
-\r
- /** Makes sure this is an utility class. */\r
- private TestDataUtils() {\r
-\r
- }\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import java.util.Map;\r
-import java.util.TreeMap;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.core.test.SimpleResultPart;\r
-import org.argeo.slc.test.TestResult;\r
-import org.argeo.slc.test.TestStatus;\r
-import org.argeo.slc.test.context.ContextAware;\r
-import org.argeo.slc.test.context.ParentContextAware;\r
-\r
-/** Utilities for comparing and synchronising contexts. */\r
-public class ContextUtils {\r
- private final static Log log = LogFactory.getLog(ContextUtils.class);\r
-\r
- public static void compareReachedExpected(ContextAware contextAware,\r
- TestResult testResult) {\r
- for (String key : contextAware.getExpectedValues().keySet()) {\r
-\r
- // Compare expected values with reached ones\r
- Object expectedValue = contextAware.getExpectedValues().get(key);\r
-\r
- if (expectedValue.toString().equals(\r
- contextAware.getContextSkipFlag())) {\r
- if (log.isDebugEnabled())\r
- log.debug("Skipped check for key '" + key + "'");\r
- continue;\r
- }\r
-\r
- if (contextAware.getValues().containsKey(key)) {\r
- Object reachedValue = contextAware.getValues().get(key);\r
-\r
- if (expectedValue.equals(contextAware.getContextAnyFlag())) {\r
- testResult.addResultPart(new SimpleResultPart(\r
- TestStatus.PASSED, "Expected any value for key '"\r
- + key + "'"));\r
- } else if (expectedValue.equals(reachedValue)) {\r
- testResult.addResultPart(new SimpleResultPart(\r
- TestStatus.PASSED, "Values matched for key '" + key\r
- + "'"));\r
- } else {\r
- testResult.addResultPart(new SimpleResultPart(\r
- TestStatus.FAILED, "Mismatch for key '" + key\r
- + "': expected '" + expectedValue\r
- + "' but reached '" + reachedValue + "'"));\r
- }\r
- } else {\r
- testResult.addResultPart(new SimpleResultPart(\r
- TestStatus.FAILED, "No value reached for key '" + key\r
- + "'"));\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * Makes sure that all children and sub-children of parent share the same\r
- * maps for values and expected values.\r
- */\r
- public static void synchronize(ParentContextAware parent) {\r
- Map<String, Object> expectedValuesCommon = new TreeMap<String, Object>(\r
- parent.getExpectedValues());\r
- synchronize(parent, expectedValuesCommon);\r
- if (log.isDebugEnabled())\r
- log.debug("Synchronized context " + parent);\r
-\r
- }\r
-\r
- private static void synchronize(ParentContextAware parent,\r
- Map<String, Object> expectedValuesCommon) {\r
- for (ContextAware child : parent.getChildContexts()) {\r
- // Values\r
- putNotContained(parent.getValues(), child.getValues());\r
- child.setValues(parent.getValues());\r
-\r
- // Expected Values\r
- // Expected values reference is not overridden: each child has its\r
- // own expected values map.\r
- overrideContained(expectedValuesCommon, child.getExpectedValues());\r
-\r
- // Creates a new Map in order not to disturb other context using the\r
- // same keys\r
- Map<String, Object> expectedValuesCommonChild = new TreeMap<String, Object>(\r
- expectedValuesCommon);\r
- putNotContained(expectedValuesCommonChild,\r
- child.getExpectedValues());\r
-\r
- if (child instanceof ParentContextAware) {\r
- // Recursive sync\r
- synchronize((ParentContextAware) child,\r
- expectedValuesCommonChild);\r
- }\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Put into common map the values from child map which are not already\r
- * defined in common map.\r
- */\r
- public static void putNotContained(Map<String, Object> commonMap,\r
- Map<String, Object> childMap) {\r
- for (String key : childMap.keySet()) {\r
- if (!commonMap.containsKey(key)) {\r
- commonMap.put(key, childMap.get(key));\r
- }\r
- }\r
- }\r
-\r
- /** Overrides child map values with the values already set in common map */\r
- public static void overrideContained(Map<String, Object> commonMap,\r
- Map<String, Object> childMap) {\r
- for (String key : childMap.keySet()) {\r
- if (commonMap.containsKey(key)) {\r
- childMap.put(key, commonMap.get(key));\r
- }\r
- }\r
- }\r
-\r
- /** Makes sure this cannot be instantiated. */\r
- private ContextUtils() {\r
-\r
- }\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import org.argeo.slc.core.test.TestDataUtils;\r
-import org.argeo.slc.test.TestData;\r
-import org.argeo.slc.test.TestDataProvider;\r
-\r
-public class DefaultContextTestData extends SimpleContextAware implements\r
- TestData, TestDataProvider {\r
-\r
- public <T extends TestData> T getTestData(Class<T> clss, String key) {\r
- return TestDataUtils.getItSelf(clss, this);\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import java.util.Map;\r
-import java.util.TreeMap;\r
-\r
-import org.springframework.beans.factory.InitializingBean;\r
-\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.test.context.ContextAware;\r
-import org.argeo.slc.test.context.ParentContextAware;\r
-\r
-public class SimpleContextAware implements ContextAware, InitializingBean {\r
- private ParentContextAware parentContext;\r
-\r
- private Map<String, Object> values = new TreeMap<String, Object>();\r
- private Map<String, Object> expectedValues = new TreeMap<String, Object>();\r
-\r
- private String contextSkipFlag = DEFAULT_SKIP_FLAG;\r
- private String contextAnyFlag = DEFAULT_ANY_FLAG;\r
-\r
- public Map<String, Object> getValues() {\r
- return values;\r
- }\r
-\r
- public void setValues(Map<String, Object> values) {\r
- this.values = values;\r
- }\r
-\r
- public Map<String, Object> getExpectedValues() {\r
- return expectedValues;\r
- }\r
-\r
- public void setExpectedValues(Map<String, Object> expectedValues) {\r
- this.expectedValues = expectedValues;\r
- }\r
-\r
- /** Used to add this context as a child by setting a property. */\r
- public void setParentContext(ParentContextAware parentContextAware) {\r
- if (parentContext != null)\r
- throw new SlcException("Parent context already set");\r
- this.parentContext = parentContextAware;\r
- this.parentContext.addChildContext(this);\r
- }\r
-\r
- protected ParentContextAware getParentContext() {\r
- return parentContext;\r
- }\r
-\r
- public void afterPropertiesSet() throws Exception {\r
- if (parentContext != null) {\r
- ContextUtils.synchronize(parentContext);\r
- }\r
- }\r
-\r
- public String getContextSkipFlag() {\r
- return contextSkipFlag;\r
- }\r
-\r
- public void setContextSkipFlag(String contextSkipFlag) {\r
- this.contextSkipFlag = contextSkipFlag;\r
- }\r
-\r
- public String getContextAnyFlag() {\r
- return contextAnyFlag;\r
- }\r
-\r
- public void setContextAnyFlag(String contextAnyFlag) {\r
- this.contextAnyFlag = contextAnyFlag;\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import java.util.Collection;\r
-import java.util.List;\r
-import java.util.Vector;\r
-\r
-import org.argeo.slc.test.context.ContextAware;\r
-import org.argeo.slc.test.context.ParentContextAware;\r
-import org.springframework.beans.factory.InitializingBean;\r
-\r
-public class SimpleParentContextAware extends SimpleContextAware implements\r
- ParentContextAware, InitializingBean {\r
- private List<ContextAware> children = new Vector<ContextAware>();\r
-\r
- public Collection<ContextAware> getChildContexts() {\r
- return children;\r
- }\r
-\r
- public void addChildContext(ContextAware contextAware) {\r
- children.add(contextAware);\r
- }\r
-\r
- @Override\r
- public void afterPropertiesSet() throws Exception {\r
- if (getParentContext() != null) {\r
- // If has a parent, sync it.\r
- super.afterPropertiesSet();\r
- } else {\r
- if (children.size() > 0) {\r
- // No need to synchronize if no children\r
- ContextUtils.synchronize(this);\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-<html>\r
-<head></head>\r
-<body>\r
-Context variables to be passed between parts of tests.\r
-</body>\r
-</html>
\ No newline at end of file
+++ /dev/null
-<html>\r
-<head></head>\r
-<body>\r
-SLC Test: test of software systems.\r
-</body>\r
-</html>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright (C) 2007-2012 Argeo GmbH
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
- <bean id="slcDefault.executionResources" parent="slcTemplate.fileResources"
- scope="execution" lazy-init="true">
- <aop:scoped-proxy proxy-target-class="false" />
- <property name="executionContext" ref="executionContext" />
- </bean>
-
- <bean id="slcDefault.writableResource" parent="slcTemplate.writableResource"
- abstract="true">
- <property name="executionResources" ref="slcDefault.executionResources" />
- </bean>
-
- <bean id="slcDefault.osFile" parent="slcTemplate.osFile" abstract="true">
- <property name="executionResources" ref="slcDefault.executionResources" />
- </bean>
-</beans>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright (C) 2007-2012 Argeo GmbH
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--->
-<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under
- the Apache License, Version 2.0 (the "License"); you may not use this file
- except in compliance with the License. You may obtain a copy of the License
- at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
- law or agreed to in writing, software distributed under the License is distributed
- on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- express or implied. See the License for the specific language governing permissions
- and limitations under the License. -->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
- <description>Bare minimal runtime configuration. In general you will
- want to use simple.xml instead.</description>
-
- <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
- <property name="scopes">
- <map>
- <entry key="execution">
- <bean class="org.argeo.slc.core.execution.ExecutionScope" />
- </entry>
- </map>
- </property>
- </bean>
-
-
- <bean id="executionStack" class="org.argeo.slc.core.execution.DefaultExecutionStack"
- scope="execution">
- <aop:scoped-proxy proxy-target-class="false" />
- </bean>
-
- <bean id="instantiationManager" class="org.argeo.slc.core.execution.InstantiationManager" />
-
- <bean class="org.argeo.slc.core.execution.ExecutionParameterPostProcessor">
- <property name="executionContext" ref="executionContext" />
- <property name="instantiationManager" ref="instantiationManager" />
- </bean>
-
- <bean class="org.argeo.slc.core.execution.ExecutionAspect">
- <property name="executionStack" ref="executionStack" />
- <property name="executionContext" ref="executionContext" />
- </bean>
-
- <aop:aspectj-autoproxy />
-
-</beans>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright (C) 2007-2012 Argeo GmbH
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--->
-<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under
- the Apache License, Version 2.0 (the "License"); you may not use this file
- except in compliance with the License. You may obtain a copy of the License
- at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
- law or agreed to in writing, software distributed under the License is distributed
- on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- express or implied. See the License for the specific language governing permissions
- and limitations under the License. -->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
- <description>Default Capabilities</description>
-
- <import resource="runtime.xml" />
-
- <bean id="executionContext" class="org.argeo.slc.core.execution.MapExecutionContext"
- scope="execution">
- <aop:scoped-proxy proxy-target-class="false" />
- </bean>
-
- <bean id="executionFlowDescriptorConverter"
- class="org.argeo.slc.core.execution.DefaultExecutionFlowDescriptorConverter"></bean>
-
- <bean
- class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
- <property name="ignoreUnresolvablePlaceholders" value="true" />
- </bean>
-
- <bean id="parameterRef" class="org.argeo.slc.core.execution.ParameterRef"
- abstract="true">
- <property name="instantiationManager" ref="instantiationManager" />
- </bean>
-</beans>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright (C) 2007-2012 Argeo GmbH
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
-
- <bean id="specAttr.primitive" class="org.argeo.slc.core.execution.PrimitiveSpecAttribute"
- abstract="true" />
- <bean id="specAttr.resource" class="org.argeo.slc.core.execution.ResourceSpecAttribute"
- abstract="true" />
- <bean id="specAttr.ref" class="org.argeo.slc.core.execution.RefSpecAttribute"
- abstract="true" />
-
- <bean id="slcTemplate.simpleFlow" class="org.argeo.slc.core.execution.DefaultExecutionFlow"
- abstract="true" />
- <bean id="slcTemplate.simpleSpec" class="org.argeo.slc.core.execution.DefaultExecutionSpec"
- abstract="true" />
-
-</beans>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright (C) 2007-2012 Argeo GmbH
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--->
-<!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under
- the Apache License, Version 2.0 (the "License"); you may not use this file
- except in compliance with the License. You may obtain a copy of the License
- at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
- law or agreed to in writing, software distributed under the License is distributed
- on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- express or implied. See the License for the specific language governing permissions
- and limitations under the License. -->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
- <description>
- Simple runtime enriched with defaults and templates used
- to simplify XML files. These templates have been deprecated by the
- custom XML namespace and will be removed in SLC 2.x. Use the XML
- namespace instead.
- </description>
-
- <import resource="simple.xml" />
-
- <import resource="specs.xml" />
- <import resource="templates.xml" />
- <import resource="defaults.xml" />
- <import resource="utils.xml" />
- <import resource="tasks/core.xml" />
-
-</beans>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright (C) 2007-2012 Argeo GmbH
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
-
- <bean id="task.echo" class="org.argeo.slc.core.execution.tasks.Echo"
- abstract="true" />
- <bean id="task.systemCall" class="org.argeo.slc.core.execution.tasks.SystemCall"
- abstract="true" />
- <bean id="task.closeTestResult" class="org.argeo.slc.core.execution.tasks.CloseTestResult"
- abstract="true" />
- <bean id="task.slcManager" class="org.argeo.slc.core.execution.tasks.SlcManager"
- abstract="true" />
- <bean id="task.overrideContextAware" class="org.argeo.slc.core.execution.tasks.OverrideContextAware"
- abstract="true" />
- <bean id="task.uploadAttachments" class="org.argeo.slc.core.execution.tasks.UploadAttachments"
- abstract="true" />
-
- <bean id="taskArg.attachment" class="org.argeo.slc.core.attachment.SimpleAttachment"
- abstract="true" />
-</beans>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright (C) 2007-2012 Argeo GmbH
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
-
- <bean id="slcTemplate.fileResources" class="org.argeo.slc.core.execution.FileExecutionResources"
- abstract="true" />
-
- <bean id="slcTemplate.resourcesFactoryBean" parent="slcTemplate.writableResource"
- abstract="true" />
-
- <bean id="slcTemplate.writableResource"
- class="org.argeo.slc.core.execution.ExecutionResourcesFactoryBean"
- abstract="true" />
-
- <bean id="slcTemplate.osFile" class="org.argeo.slc.core.execution.OsFileFactoryBean"
- abstract="true" />
-
-</beans>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright (C) 2007-2012 Argeo GmbH
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
- <bean id="mergedLists" class="org.argeo.slc.core.execution.tasks.MergedLists"
- abstract="true">
- </bean>
-</beans>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns:beans="http://www.springframework.org/schema/beans"
- targetNamespace="http://www.argeo.org/schema/slc-flow"
- elementFormDefault="qualified" attributeFormDefault="unqualified">
-
- <xsd:import namespace="http://www.springframework.org/schema/beans"
- schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" />
-
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- SLC Flow Schema, version 0.12
- Authors: Mathieu Baudier
-
- This simplifies the definition of SLC flows and their integration with
- regular Spring beans.
- ]]></xsd:documentation>
- </xsd:annotation>
-
- <xsd:element name="flow">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Adds an SLC execution flow, using the default implementation.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:complexContent>
- <xsd:extension base="beans:identifiedType">
- <xsd:sequence>
- <xsd:element ref="beans:description" minOccurs="0" />
- <xsd:sequence>
- <xsd:element name="arg" minOccurs="0" maxOccurs="unbounded"
- type="flow:argType">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Parameter for an execution flow which will override at instantiation the
- value of the parameter already defined as default value or in a parent bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:element>
- </xsd:sequence>
- <xsd:sequence>
- <xsd:choice minOccurs="0" maxOccurs="unbounded">
- <xsd:element ref="beans:bean" />
- <xsd:element ref="beans:ref" />
- <xsd:element ref="flow:flow" />
- </xsd:choice>
- <!--
- <xsd:any namespace="##other" processContents="strict"
- minOccurs="0" maxOccurs="unbounded" />
- -->
- </xsd:sequence>
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Name of the flow (alternative to ID).
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="class" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Another implementation of execution flow.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="path" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The hierarchical path under which to register this flow.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="spec" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A reference to the related specification bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="parent" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The parent bean definition (in Spring sense).
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="abstract" type="xsd:boolean"
- default="false">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Whether this flow is abstract (in Spring sense).
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- </xsd:element>
-
- <xsd:element name="spec">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- SLC flow specifications, defining the parameters and variables
- which can be used in related flows, along with their default values and
- various constraints.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:complexContent>
- <xsd:extension base="beans:identifiedType">
- <xsd:sequence>
- <xsd:element ref="beans:description" minOccurs="0" />
- <xsd:choice minOccurs="0" maxOccurs="unbounded">
- <xsd:element name="primitive" type="flow:primitiveSpecAttributeType"
- minOccurs="0" maxOccurs="unbounded">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A primitive specification attribute, that is, a plain standard value
- and not a reference to an object.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:element>
- <xsd:element name="ref" type="flow:refSpecAttributeType"
- minOccurs="0" maxOccurs="unbounded">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A reference specification attribute, that is, a reference to another object.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:element>
- </xsd:choice>
- </xsd:sequence>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- </xsd:element>
-
- <xsd:complexType name="specAttributeType">
- <xsd:choice>
- <xsd:element name="value" minOccurs="0" maxOccurs="1">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The default value of the attribute as an inner bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:choice minOccurs="1" maxOccurs="1">
- <xsd:element ref="beans:bean" />
- <xsd:element ref="beans:ref" />
- <xsd:element ref="beans:list" />
- <xsd:element ref="beans:set" />
- <xsd:element ref="beans:map" />
- <xsd:element ref="beans:props" />
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- <xsd:attribute name="name" use="required" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The name of the attribute, under which in can then be referenced.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="value" use="optional" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The default value of the attribute.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="ref" use="optional" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The default value of the attribute as a reference to another bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="isParameter" use="optional" type="xsd:boolean"
- default="false">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Whether the attribute is a parameter, that is, it has to be set at
- instantiation but can be modified afterwards for objects of scope execution.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="isFrozen" use="optional" type="xsd:boolean"
- default="false">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Whether the attribute is frozen, that is, it cannot be modified at runtime.
- A frozen attribute has to be a parameter.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="isHidden" use="optional" type="xsd:boolean"
- default="false">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Whether the attribute is hidden, that is, it should not be displayed in UIs.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:complexType>
-
- <xsd:complexType name="primitiveSpecAttributeType">
- <xsd:complexContent>
- <xsd:extension base="flow:specAttributeType">
- <xsd:attribute name="type" default="string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The type of the primitive specification attribute.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:simpleType>
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="string" />
- <xsd:enumeration value="integer" />
- <xsd:enumeration value="long" />
- <xsd:enumeration value="float" />
- <xsd:enumeration value="double" />
- <xsd:enumeration value="boolean" />
- </xsd:restriction>
- </xsd:simpleType>
- </xsd:attribute>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
-
- <xsd:complexType name="refSpecAttributeType">
- <xsd:complexContent>
- <xsd:extension base="flow:specAttributeType">
- <xsd:choice>
- <xsd:element name="choices" minOccurs="0" maxOccurs="1">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Possible values to chose from, if ommitted, all the beans in the
- application context which implement the provided targetClass will
- be considered.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:choice>
- <xsd:element name="choice" minOccurs="0" maxOccurs="unbounded"
- type="flow:refChoiceType">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A choice for a reference specification attribute.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- <xsd:attribute name="targetClass" use="required" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The class that has to be implemented by the underlying object.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
-
- <xsd:complexType name="refChoiceType">
- <xsd:attribute name="name" use="required" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The name of the related bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="description" use="optional" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A human readable description of this choice.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:complexType>
-
- <xsd:complexType name="argType">
- <xsd:choice minOccurs="0" maxOccurs="1">
- <xsd:element ref="beans:bean" />
- <xsd:element ref="beans:ref" />
- <xsd:element ref="flow:param" />
- <xsd:element ref="beans:list" />
- <xsd:element ref="beans:set" />
- <xsd:element ref="beans:map" />
- <xsd:element ref="beans:props" />
- </xsd:choice>
- <xsd:attribute name="name" use="required" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The name of the related parameter.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="value" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The plain value of the related parameter.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="ref" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The value of the related parameter as a reference to a bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:complexType>
-
- <xsd:attribute name="as-flow" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- If decorating an executable bean, it will generate an implicit SLC
- execution flow with the provided value as name.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <!--
- <xsd:attribute name="var" type="xsd:boolean"> <xsd:annotation>
- <xsd:documentation><![CDATA[ If true, the decorated bean is set to
- scope execution and proxied. ]]></xsd:documentation> </xsd:annotation>
- </xsd:attribute>
- -->
-
- <xsd:element name="variable">
- <xsd:complexType>
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Marks a bean definition as being variable, i.e. a scoped proxy of scope execution
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:attribute name="proxy-target-class" type="xsd:boolean"
- default="true">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Are class-based (CGLIB) proxies to be created?
- This is the default;
- in order to switch to standard Java
- interface-based proxies, turn this flag to
- "false".
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:complexType>
- </xsd:element>
-
- <xsd:element name="param">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- If within a property tag of a bean, it will set the value of this property
- with a reference to a parameter.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:attribute name="name" type="xsd:string" use="required">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The name of the related parameter.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="instantiationManager" type="xsd:string"
- use="optional" default="instantiationManager">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A reference to the instantiation manager to use instead of the default one
- (expert usage).
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:complexType>
- </xsd:element>
-
-</xsd:schema>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns:beans="http://www.springframework.org/schema/beans"
- targetNamespace="http://www.argeo.org/schema/slc-flow"
- elementFormDefault="qualified" attributeFormDefault="unqualified">
-
- <xsd:import namespace="http://www.springframework.org/schema/beans"
- schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" />
-
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- SLC Flow Schema, version 1.2
- Authors: Mathieu Baudier
-
- This simplifies the definition of SLC flows and their integration with
- regular Spring beans.
- ]]></xsd:documentation>
- </xsd:annotation>
-
- <xsd:element name="flow">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Adds an SLC execution flow, using the default implementation.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:complexContent>
- <xsd:extension base="beans:identifiedType">
- <xsd:sequence>
- <xsd:element ref="beans:description" minOccurs="0" />
- <xsd:sequence>
- <xsd:element name="arg" minOccurs="0" maxOccurs="unbounded"
- type="flow:argType">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Parameter for an execution flow which will override at instantiation the
- value of the parameter already defined as default value or in a parent bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:element>
- </xsd:sequence>
- <xsd:sequence>
- <xsd:choice minOccurs="0" maxOccurs="unbounded">
- <xsd:element ref="beans:bean" />
- <xsd:element ref="beans:ref" />
- <xsd:element ref="flow:flow" />
- <xsd:element ref="flow:spec" />
- </xsd:choice>
- <!-- <xsd:any namespace="##other" processContents="strict" minOccurs="0"
- maxOccurs="unbounded" /> -->
- </xsd:sequence>
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Name of the flow (alternative to ID).
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="class" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Another implementation of execution flow.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="path" type="xsd:string">
- <!-- DEPRECATED: not used anymore -->
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The hierarchical path under which to register this flow.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="spec" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A reference to the related specification bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="parent" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The parent bean definition (in Spring sense).
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="abstract" type="xsd:boolean"
- default="false">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Whether this flow is abstract (in Spring sense).
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- </xsd:element>
-
- <xsd:element name="spec">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- SLC flow specifications, defining the parameters and variables
- which can be used in related flows, along with their default values and
- various constraints.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:complexContent>
- <xsd:extension base="beans:identifiedType">
- <xsd:sequence>
- <xsd:element ref="beans:description" minOccurs="0" />
- <xsd:choice minOccurs="0" maxOccurs="unbounded">
- <xsd:element name="primitive" type="flow:primitiveSpecAttributeType"
- minOccurs="0" maxOccurs="unbounded">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A primitive specification attribute, that is, a plain standard value
- and not a reference to an object.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:element>
- <xsd:element name="ref" type="flow:refSpecAttributeType"
- minOccurs="0" maxOccurs="unbounded">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A reference specification attribute, that is, a reference to another object.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:element>
- </xsd:choice>
- </xsd:sequence>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- </xsd:element>
-
- <xsd:complexType name="specAttributeType">
- <xsd:choice>
- <xsd:element name="value" minOccurs="0" maxOccurs="1">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The default value of the attribute as an inner bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:choice minOccurs="1" maxOccurs="1">
- <xsd:element ref="beans:bean" />
- <xsd:element ref="beans:ref" />
- <xsd:element ref="beans:list" />
- <xsd:element ref="beans:set" />
- <xsd:element ref="beans:map" />
- <xsd:element ref="beans:props" />
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- <xsd:attribute name="name" use="required" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The name of the attribute, under which in can then be referenced.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="value" use="optional" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The default value of the attribute.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="ref" use="optional" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The default value of the attribute as a reference to another bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="isImmutable" use="optional" type="xsd:boolean"
- default="false">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Whether the attribute is a parameter, that is, it has to be set at
- instantiation but can be modified afterwards for objects of scope execution.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="isParameter" use="optional" type="xsd:boolean"
- default="false">
- <!-- DEPRECATED: old name of isImmutable -->
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Whether the attribute is a parameter, that is, it has to be set at
- instantiation but can be modified afterwards for objects of scope execution.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="isConstant" use="optional" type="xsd:boolean"
- default="false">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Whether the attribute is frozen, that is, it cannot be modified at runtime.
- A frozen attribute has to be a parameter.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="isFrozen" use="optional" type="xsd:boolean"
- default="false">
- <!-- DEPRECATED: old name of isConstant -->
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Whether the attribute is frozen, that is, it cannot be modified at runtime.
- A frozen attribute has to be a parameter.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="isHidden" use="optional" type="xsd:boolean"
- default="false">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Whether the attribute is hidden, that is, it should not be displayed in UIs.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:complexType>
-
- <xsd:complexType name="primitiveSpecAttributeType">
- <xsd:complexContent>
- <xsd:extension base="flow:specAttributeType">
- <xsd:attribute name="type" default="string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The type of the primitive specification attribute.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:simpleType>
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="string" />
- <xsd:enumeration value="password" />
- <xsd:enumeration value="integer" />
- <xsd:enumeration value="long" />
- <xsd:enumeration value="float" />
- <xsd:enumeration value="double" />
- <xsd:enumeration value="boolean" />
- </xsd:restriction>
- </xsd:simpleType>
- </xsd:attribute>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
-
- <xsd:complexType name="refSpecAttributeType">
- <xsd:complexContent>
- <xsd:extension base="flow:specAttributeType">
- <xsd:choice>
- <xsd:element name="choices" minOccurs="0" maxOccurs="1">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Possible values to chose from, if ommitted, all the beans in the
- application context which implement the provided targetClass will
- be considered.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:choice>
- <xsd:element name="choice" minOccurs="0" maxOccurs="unbounded"
- type="flow:refChoiceType">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A choice for a reference specification attribute.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- <xsd:attribute name="targetClass" use="required" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The class that has to be implemented by the underlying object.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
-
- <xsd:complexType name="refChoiceType">
- <xsd:attribute name="name" use="required" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The name of the related bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="description" use="optional" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A human readable description of this choice.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:complexType>
-
- <xsd:complexType name="argType">
- <xsd:choice minOccurs="0" maxOccurs="1">
- <xsd:element ref="beans:bean" />
- <xsd:element ref="beans:ref" />
- <xsd:element ref="flow:param" />
- <xsd:element ref="beans:list" />
- <xsd:element ref="beans:set" />
- <xsd:element ref="beans:map" />
- <xsd:element ref="beans:props" />
- </xsd:choice>
- <xsd:attribute name="name" use="required" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The name of the related parameter.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="value" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The plain value of the related parameter.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="ref" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The value of the related parameter as a reference to a bean.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:complexType>
-
- <xsd:attribute name="as-flow" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- If decorating an executable bean, it will generate an implicit SLC
- execution flow with the provided value as name.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <!-- <xsd:attribute name="var" type="xsd:boolean"> <xsd:annotation> <xsd:documentation><![CDATA[
- If true, the decorated bean is set to scope execution and proxied. ]]></xsd:documentation>
- </xsd:annotation> </xsd:attribute> -->
-
- <xsd:element name="variable">
- <xsd:complexType>
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Marks a bean definition as being variable, i.e. a scoped proxy of scope execution
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:attribute name="proxy-target-class" type="xsd:boolean"
- default="true">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- Are class-based (CGLIB) proxies to be created?
- This is the default;
- in order to switch to standard Java
- interface-based proxies, turn this flag to
- "false".
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:complexType>
- </xsd:element>
-
- <xsd:element name="param">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- If within a property tag of a bean, it will set the value of this property
- with a reference to a parameter.
- ]]></xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:attribute name="name" type="xsd:string" use="required">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- The name of the related parameter.
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="instantiationManager" type="xsd:string"
- use="optional" default="instantiationManager">
- <xsd:annotation>
- <xsd:documentation><![CDATA[
- A reference to the instantiation manager to use instead of the default one
- (expert usage).
- ]]></xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- </xsd:complexType>
- </xsd:element>
-
-</xsd:schema>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright (C) 2007-2012 Argeo GmbH
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
- default-lazy-init="true">
-
- <bean name="slcDefault.test.testRun"
- class="org.argeo.slc.core.test.SimpleTestRun"
- scope="prototype">
- </bean>
-
- <bean name="slcDefault.test.uuid" class="java.util.UUID"
- factory-method="randomUUID" scope="prototype">
- </bean>
-
- <bean id="slcDefault.test.basicSimpleTestResult"
- class="org.argeo.slc.core.test.SimpleTestResult"
- abstract="true">
- <property name="uuid">
- <bean factory-bean="slcDefault.test.uuid"
- factory-method="toString">
- </bean>
- </property>
- </bean>
-
-</beans>
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.deploy;
-
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.core.test.context.AbstractInternalSpringTestCase;
-import org.springframework.core.io.Resource;
-
-public class DefaultResourceSetTest extends AbstractInternalSpringTestCase {
- private final static Log log = LogFactory
- .getLog(DefaultResourceSetTest.class);
-
- public void testListResources() {
- DefaultResourceSet rrs = getBean("relativeResourceSet");
- Map<String, Resource> res = rrs.listResources();
- for (String relativePath : res.keySet())
- log.debug(relativePath + "=" + res.get(relativePath));
- assertEquals(2, res.size());
- }
-
- @Override
- protected String getApplicationContextLocation() {
- return inPackage("relativeResourceSet.xml");
- }
-
-}
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution;\r
-\r
-import junit.framework.TestCase;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.core.test.SimpleTestResult;\r
-import org.argeo.slc.execution.ExecutionFlow;\r
-import org.argeo.slc.test.TestResultPart;\r
-import org.argeo.slc.test.TestStatus;\r
-import org.springframework.context.ConfigurableApplicationContext;\r
-import org.springframework.context.support.ClassPathXmlApplicationContext;\r
-\r
-public abstract class AbstractExecutionFlowTestCase extends TestCase {\r
-\r
- protected final Log log = LogFactory.getLog(getClass());\r
-\r
- protected void logException(Throwable ex) {\r
- log.info("Got Exception of class " + ex.getClass().toString()\r
- + " with message '" + ex.getMessage() + "'.");\r
- }\r
-\r
- protected void validateTestResult(SimpleTestResult testResult) {\r
- validateTestResult(testResult, TestStatus.PASSED);\r
- }\r
-\r
- protected void validateTestResult(SimpleTestResult testResult,\r
- int expectedStatus) {\r
- for (TestResultPart part : testResult.getParts()) {\r
- if (part.getStatus() != expectedStatus) {\r
- fail("Error found in TestResult: " + part.getMessage());\r
- }\r
- }\r
- }\r
-\r
- protected ConfigurableApplicationContext createApplicationContext(\r
- String applicationContextSuffix) {\r
- ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext(\r
- inPackage(applicationContextSuffix));\r
- // applicationContext.start();\r
- return applicationContext;\r
- }\r
-\r
- protected void configureAndExecuteSlcFlow(String applicationContextSuffix,\r
- String beanName) {\r
- ConfigurableApplicationContext applicationContext = createApplicationContext(applicationContextSuffix);\r
- ExecutionFlow executionFlow = (ExecutionFlow) applicationContext\r
- .getBean(beanName);\r
- executionFlow.run();\r
- applicationContext.close();\r
- }\r
-\r
- protected String inPackage(String suffix) {\r
- String prefix = getClass().getPackage().getName().replace('.', '/');\r
- return prefix + '/' + suffix;\r
- }\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution;\r
-\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-import org.argeo.slc.core.test.SimpleTestResult;\r
-import org.argeo.slc.execution.ExecutionContext;\r
-import org.argeo.slc.execution.ExecutionFlow;\r
-import org.argeo.slc.test.TestStatus;\r
-import org.springframework.beans.factory.BeanCreationException;\r
-import org.springframework.context.ConfigurableApplicationContext;\r
-\r
-public class BasicExecutionFlowTest extends AbstractExecutionFlowTestCase {\r
- // TO TEST\r
- // - post-processing for @{} replacement in beans with complex properties\r
- // - bean of scope other than execution are not resolved at execution\r
-\r
- // public void testMyTest() throws Exception {\r
- // ConfigurableApplicationContext applicationContext =\r
- // createApplicationContext("test.xml");\r
- // log.info("Start Execution");\r
- // ((ExecutionFlow) applicationContext.getBean("flow1")).execute();\r
- // applicationContext.close();\r
- // }\r
-\r
- public void testSpecOverriding() throws Exception {\r
- ConfigurableApplicationContext applicationContext = createApplicationContext("specOverriding.xml");\r
- ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
- SimpleTestResult res = (SimpleTestResult) applicationContext\r
- .getBean("myTestResult");\r
- validateTestResult(res);\r
- }\r
-\r
- public void testMultipleFlows() throws Exception {\r
- ConfigurableApplicationContext applicationContext = createApplicationContext("multipleFlow.xml");\r
- ((ExecutionFlow) applicationContext.getBean("flow1")).run();\r
- SimpleTestResult res = (SimpleTestResult) applicationContext\r
- .getBean("myTestResult");\r
- validateTestResult(res);\r
- res.getParts().clear();\r
- ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
- validateTestResult(res, TestStatus.FAILED);\r
- applicationContext.close();\r
- }\r
-\r
- /**\r
- * Test placeholder resolution in a context without scope execution or proxy\r
- * and with cascading flows (the flow A contains the flow B)\r
- * \r
- * @throws Exception\r
- */\r
- public void testPlaceHolders() throws Exception {\r
- ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.xml");\r
- ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
- validateTestResult((SimpleTestResult) applicationContext\r
- .getBean("myTestResult"));\r
- applicationContext.close();\r
- }\r
-\r
- /**\r
- * Test placeholder resolution in a context without scope execution or proxy\r
- * and with cascading flows (the flow A contains the flow B) setting\r
- * execution values (should have no effect)\r
- * \r
- * @throws Exception\r
- */\r
- public void testPlaceHoldersWithExecutionValues() throws Exception {\r
- ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.xml");\r
-\r
- ExecutionContext executionContext = (ExecutionContext) applicationContext\r
- .getBean("executionContext");\r
- Map<String, String> executionParameters = new HashMap<String, String>();\r
- executionParameters.put("p1", "e1");\r
- executionParameters.put("p2", "e2");\r
- executionParameters.put("p3", "e3");\r
- executionParameters.put("p4", "e4");\r
- executionParameters.put("p5", "e5");\r
- executionParameters.put("p6", "e6");\r
- executionParameters.put("p7", "e7");\r
- executionParameters.put("p8", "e8");\r
- addVariables(executionContext, executionParameters);\r
-\r
- ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
- validateTestResult((SimpleTestResult) applicationContext\r
- .getBean("myTestResult"));\r
- applicationContext.close();\r
- }\r
-\r
- public void testPlaceHoldersExec() throws Exception {\r
- ConfigurableApplicationContext applicationContext = createApplicationContext("placeHolders.cascading.exec.xml");\r
-\r
- ExecutionContext executionContext = (ExecutionContext) applicationContext\r
- .getBean("executionContext");\r
- Map<String, String> executionParameters = new HashMap<String, String>();\r
- executionParameters.put("p1", "e1");\r
- executionParameters.put("p2", "e2");\r
- executionParameters.put("p3", "e3");\r
- executionParameters.put("p4", "e4");\r
- executionParameters.put("p5", "e5");\r
- executionParameters.put("p6", "e6");\r
- addVariables(executionContext, executionParameters);\r
-\r
- ((ExecutionFlow) applicationContext.getBean("flowA")).run();\r
- validateTestResult((SimpleTestResult) applicationContext\r
- .getBean("myTestResult"));\r
- applicationContext.close();\r
- }\r
-\r
- public void testCanonicFlowParameters() throws Exception {\r
- configureAndExecuteSlcFlow("canonic-001.xml", "canonic.001");\r
- }\r
-\r
- public void testCanonicDefaultValues() throws Exception {\r
- configureAndExecuteSlcFlow("canonic-002.xml", "canonic.002");\r
- }\r
-\r
- public void testCanonicMissingValues() throws Exception {\r
- try {\r
- configureAndExecuteSlcFlow("canonic-003.error.xml", "canonic.003");\r
- fail("Parameter not set - should be rejected.");\r
- } catch (BeanCreationException e) {\r
- // exception expected\r
- logException(e);\r
- }\r
- }\r
-\r
- public void testCanonicUnknownParameter() throws Exception {\r
- try {\r
- configureAndExecuteSlcFlow("canonic-004.error.xml", "canonic.004");\r
- fail("Unknown parameter set - should be rejected.");\r
- } catch (BeanCreationException e) {\r
- // exception expected\r
- logException(e);\r
- }\r
- }\r
-\r
- public void testListSetMap() throws Exception {\r
- ConfigurableApplicationContext applicationContext = createApplicationContext("listSetMap.xml");\r
- ExecutionFlow executionFlow = (ExecutionFlow) applicationContext\r
- .getBean("myFlow");\r
- executionFlow.run();\r
-\r
- validateTestResult((SimpleTestResult) applicationContext\r
- .getBean("myTestResult"));\r
-\r
- // BasicTestData res = (BasicTestData)\r
- // applicationContext.getBean("cascadingComplex.testData");\r
- // log.info("res=" + res.getReached().toString());\r
-\r
- applicationContext.close();\r
- }\r
-\r
- public void testListSetMapMultipleFlows() throws Exception {\r
- ConfigurableApplicationContext applicationContext = createApplicationContext("listSetMapMultipleFlow.xml");\r
- ((ExecutionFlow) applicationContext.getBean("flow1")).run();\r
- SimpleTestResult res = (SimpleTestResult) applicationContext\r
- .getBean("myTestResult");\r
- validateTestResult(res);\r
- res.getParts().clear();\r
- ((ExecutionFlow) applicationContext.getBean("flow2")).run();\r
- validateTestResult(res, TestStatus.FAILED);\r
- applicationContext.close();\r
- }\r
-\r
- protected void addVariables(ExecutionContext executionContext,\r
- Map<String, String> vars) {\r
- for (String key : vars.keySet())\r
- executionContext.setVariable(key, vars.get(key));\r
- }\r
-}\r
+++ /dev/null
-package org.argeo.slc.core.execution;
-
-import java.net.URI;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-public class DefaultAgentCliTest extends TestCase {
- public void testArgsToUris() {
- String[] args = { "org.argeo.slc.demo.minimal", "HelloWorld/WithVar",
- "--testKey", "555" };
- List<URI> uris = DefaultAgentCli.asURIs(args);
- assertEquals(1, uris.size());
- assertEquals(
- "flow:/org.argeo.slc.demo.minimal/HelloWorld/WithVar?testKey=555",
- uris.get(0).toString());
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.InitializingBean;
-
-public class ExceptionIfInitCalledTwice implements Runnable, InitializingBean {
- private final static Log log = LogFactory
- .getLog(ExceptionIfInitCalledTwice.class);
-
- private Boolean calledOnce = false;
-
- public void run() {
- log.info(getClass().getSimpleName() + " ran properly");
- }
-
- public void afterPropertiesSet() throws Exception {
- log.info(getClass().getSimpleName() + " init method called");
-
- if (calledOnce)
- throw new SlcException(getClass().getSimpleName()
- + "init method called twice.");
- else
- calledOnce = true;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-
-public class FileExecutionResourcesSpringTest extends
- AbstractExecutionFlowTestCase {
- private String basePath = FileExecutionResources.DEFAULT_EXECUTION_RESOURCES_TMP_PATH;
-
- public void testSimple() throws Exception {
- File file = getFile("subdir/writeTo");
- try {
- assertFalse(file.exists());
- configureAndExecuteSlcFlow("executionResources.xml",
- "executionResources.simple");
- assertTrue(file.exists());
- } finally {
- file.deleteOnExit();
- }
- }
-
- public void testPlaceholderPass() throws Exception {
- File file = getFile("subdir/60");
- try {
- assertFalse(file.exists());
- configureAndExecuteSlcFlow("executionResources.xml",
- "executionResources.placeholderPass");
- assertTrue(file.exists());
- } finally {
- file.deleteOnExit();
- }
- }
-
- /**
- * Test that it generate the wrong file because of issue when using
- * execution placeholder in contructor-arg
- */
- public void testPlaceholderFail() throws Exception {
- File file = getFile("subdir/@{var}");
- try {
- assertFalse(file.exists());
- configureAndExecuteSlcFlow("executionResources.xml",
- "executionResources.placeholderFail");
- assertTrue(file.exists());
- } finally {
- file.deleteOnExit();
- }
- }
-
- protected File getFile(String relativePath) {
- return new File(basePath + File.separator
- + relativePath.replace('/', File.separatorChar));
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import java.io.File;
-
-import junit.framework.TestCase;
-
-import org.apache.commons.io.FileUtils;
-import org.argeo.slc.execution.ExecutionContext;
-import org.springframework.core.io.Resource;
-
-public class FileExecutionResourcesTest extends TestCase {
- public void testGetWritableFile() throws Exception {
- FileExecutionResources executionResources = new FileExecutionResources();
- ExecutionContext executionContext = new MapExecutionContext();
- executionResources.setExecutionContext(executionContext);
-
- String expected = "TEST";
- String reached = "";
- try {
- // Resource
- Resource resource = executionResources
- .getWritableResource("subdir1/textRes.txt");
- assertTrue(resource.getFile().getParentFile().exists());
- assertFalse(resource.getFile().exists());
- FileUtils.writeStringToFile(resource.getFile(), expected);
- reached = FileUtils.readFileToString(resource.getFile());
- assertEquals(expected, reached);
-
- // File
- File file = executionResources.getFile("subdir2/textFile.txt");
- assertFalse(file.getParentFile().exists());
- assertFalse(file.exists());
- FileUtils.writeStringToFile(file, expected);
- reached = FileUtils.readFileToString(file);
- assertEquals(expected, reached);
- } finally {
- if (executionResources.getBaseDir() != null
- && executionResources.getBaseDir().exists())
- FileUtils.deleteDirectory(executionResources.getBaseDir());
- }
-
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution;
-
-import org.argeo.slc.core.test.SimpleTestResult;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.test.TestStatus;
-import org.springframework.context.ConfigurableApplicationContext;
-
-public class ParameterRefTest extends AbstractExecutionFlowTestCase {
- public void test001() throws Exception {
- ConfigurableApplicationContext applicationContext = createApplicationContext("parameterRef.xml");
- ((ExecutionFlow) applicationContext.getBean("parameterRef.001")).run();
-
- SimpleTestResult res = (SimpleTestResult) applicationContext
- .getBean("parameterRef.testResult");
- assertEquals(res.getParts().get(0).getStatus(), TestStatus.PASSED);
- assertEquals(res.getParts().get(1).getStatus(), TestStatus.FAILED);
-
- applicationContext.close();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.tasks;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.core.execution.AbstractExecutionFlowTestCase;
-
-public class SystemCallTest extends AbstractExecutionFlowTestCase {
- private final static Log log = LogFactory.getLog(SystemCallTest.class);
-
- private final String defFile = "systemCall.xml";
-
- public void testSystemCallSimple() throws Exception {
- if (isOsSupported())
- configureAndExecuteSlcFlow(defFile, "systemCallSimple");
- }
-
- public void testSystemCallList() throws Exception {
- if (isOsSupported())
- configureAndExecuteSlcFlow(defFile, "systemCallList");
- }
-
- public void testSystemCallOsSpecific() throws Exception {
- if (isOsSupported())
- configureAndExecuteSlcFlow(defFile, "systemCallOsSpecific");
- }
-
- public void testSystemCallWithVar() throws Exception {
- if (isOsSupported())
- configureAndExecuteSlcFlow(defFile, "systemCallWithVar");
- }
-
- protected boolean isOsSupported() {
- String osName = System.getProperty("os.name");
- final Boolean ret;
- if (osName.contains("Windows"))
- ret = false;
- else
- ret = true;
-
- if (ret == false)
- log.warn("Skip test because OS '" + osName + "' is not supported.");
- return ret;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.core.execution.xml;
-
-import org.argeo.slc.core.execution.AbstractExecutionFlowTestCase;
-import org.argeo.slc.core.test.SimpleTestResult;
-import org.argeo.slc.execution.ExecutionContext;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.springframework.context.ConfigurableApplicationContext;
-
-public class FlowNamespaceTest extends AbstractExecutionFlowTestCase {
- public void testCanonical() throws Exception {
- ConfigurableApplicationContext applicationContext = createApplicationContext("canonic-ns.xml");
- ((ExecutionFlow) applicationContext.getBean("canonic-ns.001")).run();
- ((ExecutionFlow) applicationContext.getBean("canonic-ns.002")).run();
- }
-
- public void testAdvanced() throws Exception {
- ConfigurableApplicationContext applicationContext = createApplicationContext("advanced.xml");
- ((ExecutionFlow) applicationContext.getBean("flow1")).run();
- ((ExecutionFlow) applicationContext.getBean("flow2")).run();
- ((ExecutionFlow) applicationContext.getBean("flow3")).run();
-
- validateTestResult((SimpleTestResult) applicationContext
- .getBean("testResult"));
- }
-
- public void testAdvancedExecution() throws Exception {
- ConfigurableApplicationContext applicationContext = createApplicationContext("advanced.xml");
-
- ExecutionContext executionContext = (ExecutionContext) applicationContext
- .getBean("executionContext");
- executionContext.setVariable("param2", 4);
-
- ((ExecutionFlow) applicationContext.getBean("flow4")).run();
-
- validateTestResult((SimpleTestResult) applicationContext
- .getBean("testResult"));
- }
-
- // THis tests causes pb when using Spring 3
- public void testContainers() throws Exception {
- ConfigurableApplicationContext applicationContext = createApplicationContext("containers.xml");
- ((ExecutionFlow) applicationContext.getBean("test.list.flow1")).run();
- ((ExecutionFlow) applicationContext.getBean("test.list.flow2")).run();
-
- validateTestResult((SimpleTestResult) applicationContext
- .getBean("testResult"));
- }
-}
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import java.util.Map;\r
-\r
-import junit.framework.TestCase;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.springframework.beans.factory.BeanFactoryUtils;\r
-import org.springframework.beans.factory.ListableBeanFactory;\r
-import org.springframework.context.ConfigurableApplicationContext;\r
-import org.springframework.context.support.ClassPathXmlApplicationContext;\r
-\r
-/** Helper for tests using a Spring application context. */\r
-public abstract class AbstractInternalSpringTestCase extends TestCase {\r
- protected final Log log = LogFactory.getLog(getClass());\r
- private ConfigurableApplicationContext context;\r
-\r
- /**\r
- * Gets (and create if necessary) the application context to use. Default\r
- * implementation uses a class path xml application context and calls\r
- * {@link #getApplicationContextLocation()}.\r
- */\r
- protected ConfigurableApplicationContext getContext() {\r
- if (context == null) {\r
- context = new ClassPathXmlApplicationContext(\r
- getApplicationContextLocation());\r
- }\r
- return context;\r
- }\r
-\r
- /** Returns a bean from the underlying context */\r
- @SuppressWarnings(value = { "unchecked" })\r
- protected <T> T getBean(String beanId) {\r
- return (T) getContext().getBean(beanId);\r
- }\r
-\r
- protected <T> T getBean(Class<? extends T> clss) {\r
- T bean = loadSingleFromContext(getContext(), clss);\r
- if (bean == null) {\r
- throw new SlcException("Cannot retrieve a unique bean of type "\r
- + clss);\r
- } else {\r
- return bean;\r
- }\r
- }\r
-\r
- /**\r
- * Th location of the application to load. The default implementation\r
- * returns <i>applicationContext.xml</i> found in the same package as the\r
- * test.\r
- */\r
- protected String getApplicationContextLocation() {\r
- return inPackage("applicationContext.xml");\r
- }\r
-\r
- /**\r
- * Prefixes the package of the class after converting the '.' to '/' in\r
- * order to have a resource path.\r
- */\r
- protected String inPackage(String suffix) {\r
- String prefix = getClass().getPackage().getName().replace('.', '/');\r
- return prefix + '/' + suffix;\r
- }\r
-\r
- @SuppressWarnings(value = { "unchecked" })\r
- protected <T> T loadSingleFromContext(ListableBeanFactory context,\r
- Class<T> clss) {\r
- Map<String, T> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(\r
- context, clss, false, false);\r
- if (beans.size() == 1) {\r
- return beans.values().iterator().next();\r
- } else if (beans.size() > 1) {\r
- if (log.isDebugEnabled()) {\r
- log\r
- .debug(("Found more that on bean for type " + clss\r
- + ": " + beans.keySet()));\r
- }\r
- return null;\r
- } else {\r
- return null;\r
- }\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.test.context;\r
-\r
-import java.util.List;\r
-\r
-import org.argeo.slc.core.test.SimpleTestResult;\r
-import org.argeo.slc.test.TestResultPart;\r
-import org.argeo.slc.test.TestStatus;\r
-import org.argeo.slc.test.context.ContextAware;\r
-\r
-public class ContextTest extends AbstractInternalSpringTestCase {\r
-\r
- public void testComplexContext() {\r
- SimpleTestResult testResult = new SimpleTestResult();\r
- ContextUtils.compareReachedExpected(\r
- (ContextAware) getBean("context.c1"), testResult);\r
- ContextUtils.compareReachedExpected(\r
- (ContextAware) getBean("context.c2"), testResult);\r
- ContextUtils.compareReachedExpected(\r
- (ContextAware) getBean("context.c3"), testResult);\r
-\r
- List<TestResultPart> parts = testResult.getParts();\r
- assertEquals(6, parts.size());\r
- assertEquals(TestStatus.PASSED, parts.get(0).getStatus());\r
- assertEquals(TestStatus.PASSED, parts.get(1).getStatus());\r
- assertEquals(TestStatus.PASSED, parts.get(2).getStatus());\r
- assertEquals(TestStatus.FAILED, parts.get(3).getStatus());\r
- assertEquals(TestStatus.PASSED, parts.get(4).getStatus());\r
- assertEquals(TestStatus.PASSED, parts.get(5).getStatus());\r
- }\r
-}\r