+++ /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",\
+Import-Package: javax.jcr.nodetype,\
+org.apache.tools.ant.*;resolution:="optional",\
junit.framework;resolution:="optional",\
*
--- /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.ant;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.argeo.slc.core.execution.AbstractExecutionFlowGenerator;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.core.io.Resource;
+
+public class AntFlowGenerator extends AbstractExecutionFlowGenerator {
+ private List<Resource> antFiles = new ArrayList<Resource>();
+
+ protected Map<String, BeanDefinition> createExecutionFlowDefinitions(
+ ConfigurableListableBeanFactory beanFactory) {
+ Map<String, BeanDefinition> definitions = new HashMap<String, BeanDefinition>();
+
+ for (Resource antFile : antFiles) {
+ AntRun antRun = new AntRun();
+ antRun.setBuildFile(antFile);
+
+ List<Runnable> executables = new ArrayList<Runnable>();
+ executables.add(antRun);
+ definitions.put("ant." + antFile.getFilename(),
+ createDefaultFlowDefinition(executables));
+ }
+ return definitions;
+ }
+
+ public void setAntFiles(List<Resource> antFiles) {
+ this.antFiles = antFiles;
+ }
+
+}
--- /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.ant;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.helper.ProjectHelper2;
+import org.argeo.slc.SlcException;
+import org.springframework.core.io.Resource;
+
+public class AntRun implements Runnable {
+ private final static Log log = LogFactory.getLog(AntRun.class);
+
+ private Resource buildFile;
+ private File baseDir;
+
+ private List<String> targets = new ArrayList<String>();
+ private Map<Object, Object> properties = new HashMap<Object, Object>();
+
+ public void run() {
+ Project project = new Project();
+
+ try {
+ String path = buildFile.getURL().getPath();
+ project.setUserProperty("ant.file", path);
+ project.setBaseDir(extractBaseDir(path));
+
+ project.init();
+ ProjectHelper projectHelper = new ProjectHelper2();
+ project.addReference(ProjectHelper.PROJECTHELPER_REFERENCE,
+ projectHelper);
+ projectHelper.parse(project, buildFile.getURL());
+ } catch (Exception e) {
+ throw new SlcException("Could not parse " + buildFile, e);
+ }
+
+ if (properties != null) {
+ for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+ project.setUserProperty(entry.getKey().toString(), entry
+ .getValue().toString());
+ }
+ }
+
+ project.fireBuildStarted();
+ Throwable exception = null;
+ try {
+ project.addBuildListener(new LoggingListener());
+ if (targets.size() == 0) {
+ project.executeTarget(project.getDefaultTarget());
+ } else {
+ project.executeTargets(new Vector<String>(targets));
+ }
+ } catch (Throwable e) {
+ exception = e;
+ throw new SlcException("Could not run Ant script " + buildFile, e);
+ } finally {
+ project.fireBuildFinished(exception);
+ }
+ }
+
+ private File extractBaseDir(String path) {
+ if(this.baseDir!=null)
+ return this.baseDir;
+
+ String baseDir = null;
+ if (path.length() > 1) {
+ int indx = path.lastIndexOf('/', path.length() - 1);
+ if (indx == -1 || indx == 0) {
+ baseDir = "/";
+ } else {
+ baseDir = path.substring(0, indx) + "/";
+ }
+ } else {
+ baseDir = "/";
+ }
+ File file = new File(baseDir);
+ if (file.exists()) {
+ return file;
+ } else {
+ return new File(System.getProperty("user.dir"));
+ }
+ }
+
+ public void setBuildFile(Resource buildFile) {
+ this.buildFile = buildFile;
+ }
+
+ public void setTargets(List<String> targets) {
+ this.targets = targets;
+ }
+
+ public void setProperties(Map<Object, Object> properties) {
+ this.properties = properties;
+ }
+
+ public void setBaseDir(File baseDir) {
+ this.baseDir = baseDir;
+ }
+
+ protected static class LoggingListener implements BuildListener {
+
+ public void buildFinished(BuildEvent event) {
+ if (log.isDebugEnabled())
+ log.debug("Ant build finished: " + event);
+ }
+
+ public void buildStarted(BuildEvent event) {
+ if (log.isDebugEnabled())
+ log.debug("Ant build started: " + event);
+ }
+
+ public void messageLogged(BuildEvent event) {
+ if (event.getPriority() == Project.MSG_DEBUG) {
+ if (log.isTraceEnabled())
+ log.trace(event.getMessage());
+ } else if (event.getPriority() == Project.MSG_VERBOSE) {
+ if (log.isDebugEnabled())
+ log.debug(event.getMessage());
+ } else if (event.getPriority() == Project.MSG_INFO) {
+ log.info(event.getMessage());
+
+ } else if (event.getPriority() == Project.MSG_WARN) {
+ log.warn(event.getMessage());
+
+ } else if (event.getPriority() == Project.MSG_ERR) {
+ log.error(event.getMessage());
+ } else {
+ log.error(event.getMessage());
+ }
+ }
+
+ public void targetFinished(BuildEvent event) {
+ if (log.isTraceEnabled())
+ log.debug("Target finished: " + event.getTarget());
+ }
+
+ public void targetStarted(BuildEvent event) {
+ if (log.isTraceEnabled())
+ log.debug("Target started: " + event.getTarget());
+ }
+
+ public void taskFinished(BuildEvent event) {
+ }
+
+ public void taskStarted(BuildEvent event) {
+ }
+ }
+}
--- /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.jcr;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+
+/**
+ * Writes arbitrary metadata into a child node of a given node (or the node
+ * itself if metadata node name is set to null)
+ */
+public class JcrMetadataWriter implements Runnable {
+ private final static Log log = LogFactory.getLog(JcrMetadataWriter.class);
+
+ private Node baseNode;
+ private String metadataNodeName = SlcNames.SLC_METADATA;
+
+ private Map<String, String> metadata = new HashMap<String, String>();
+
+ public void run() {
+ try {
+ Node metadataNode;
+ if (metadataNodeName != null)
+ metadataNode = baseNode.hasNode(metadataNodeName) ? baseNode
+ .getNode(metadataNodeName) : baseNode
+ .addNode(metadataNodeName);
+ else
+ metadataNode = baseNode;
+
+ for (String key : metadata.keySet())
+ metadataNode.setProperty(key, metadata.get(key));
+
+ baseNode.getSession().save();
+
+ if (log.isDebugEnabled())
+ log.debug("Wrote " + metadata.size() + " metadata entries to "
+ + metadataNode);
+ } catch (RepositoryException e) {
+ throw new SlcException("Cannot write metadata to " + baseNode, e);
+ } finally {
+ JcrUtils.discardUnderlyingSessionQuietly(baseNode);
+ }
+
+ }
+
+ public void setBaseNode(Node baseNode) {
+ this.baseNode = baseNode;
+ }
+
+ public void setMetadataNodeName(String metadataNodeName) {
+ this.metadataNodeName = metadataNodeName;
+ }
+
+ public void setMetadata(Map<String, String> metadata) {
+ this.metadata = metadata;
+ }
+
+}
--- /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.jcr;
+
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.attachment.Attachment;
+import org.argeo.slc.core.attachment.AttachmentsEnabled;
+import org.argeo.slc.test.TestResult;
+import org.argeo.slc.test.TestResultPart;
+import org.argeo.slc.test.TestRun;
+import org.argeo.slc.test.TestStatus;
+
+/**
+ * {@link TestResult} wrapping a JCR node of type
+ * {@link SlcTypes#SLC_TEST_RESULT}.
+ */
+public class JcrTestResult implements TestResult, SlcNames, AttachmentsEnabled {
+ private final static Log log = LogFactory.getLog(JcrTestResult.class);
+
+ /** Should only be set for an already existing result. */
+ private String uuid;
+ private Repository repository;
+ private Session session;
+ /**
+ * For testing purposes, best practice is to not set them explicitely but
+ * via other mechanisms such as JAAS or SPring Security.
+ */
+ private Credentials credentials = null;
+ private String resultType = SlcTypes.SLC_TEST_RESULT;
+
+ /** cached for performance purposes */
+ private String nodeIdentifier = null;
+
+ private Map<String, String> attributes = new HashMap<String, String>();
+
+ public void init() {
+ try {
+ session = repository.login(credentials);
+ if (uuid == null) {
+ // create new result
+ uuid = UUID.randomUUID().toString();
+ String path = SlcJcrUtils.createResultPath(session, uuid);
+ Node resultNode = JcrUtils.mkdirs(session, path, resultType);
+ resultNode.setProperty(SLC_UUID, uuid);
+ for (String attr : attributes.keySet()) {
+ String property = attr;
+ // compatibility with legacy applications
+ if ("testCase".equals(attr))
+ property = SLC_TEST_CASE;
+ else if ("testCaseType".equals(attr))
+ property = SLC_TEST_CASE_TYPE;
+ resultNode.setProperty(property, attributes.get(attr));
+ }
+ session.save();
+ if (log.isDebugEnabled())
+ log.debug("Created test result " + uuid);
+ }
+ } catch (Exception e) {
+ JcrUtils.discardQuietly(session);
+ throw new SlcException("Cannot initialize JCR result", e);
+ }
+ }
+
+ public void destroy() {
+ JcrUtils.logoutQuietly(session);
+ if (log.isTraceEnabled())
+ log.trace("Logged out session for result " + uuid);
+ }
+
+ public Node getNode() {
+ try {
+ Node resultNode;
+ if (nodeIdentifier != null) {
+ return session.getNodeByIdentifier(nodeIdentifier);
+ } else {
+ QueryManager qm = session.getWorkspace().getQueryManager();
+ Query q = qm.createQuery("select * from ["
+ + SlcTypes.SLC_TEST_RESULT + "] where [slc:uuid]='"
+ + uuid + "'", Query.JCR_SQL2);
+ resultNode = JcrUtils.querySingleNode(q);
+ if (resultNode != null)
+ nodeIdentifier = resultNode.getIdentifier();
+ }
+ return resultNode;
+ } catch (Exception e) {
+ throw new SlcException("Cannot get result node", e);
+ }
+ }
+
+ public void notifyTestRun(TestRun testRun) {
+ // TODO store meta data about the test running
+ // if (log.isDebugEnabled())
+ // log.debug("Running test "
+ // + testRun.getTestDefinition().getClass().getName() + "...");
+ }
+
+ public void addResultPart(TestResultPart testResultPart) {
+ Node node = getNode();
+
+ try {
+ // error : revert all unsaved changes on the resultNode to be sure
+ // it is in a consistant state
+ if (testResultPart.getExceptionMessage() != null)
+ JcrUtils.discardQuietly(node.getSession());
+ node.getSession().save();
+
+ // add the new result part, retrieving status information
+ Node resultPartNode = node.addNode(SlcNames.SLC_RESULT_PART,
+ SlcTypes.SLC_CHECK);
+ resultPartNode.setProperty(SLC_SUCCESS, testResultPart.getStatus()
+ .equals(TestStatus.PASSED));
+ if (testResultPart.getMessage() != null)
+ resultPartNode.setProperty(SLC_MESSAGE,
+ testResultPart.getMessage());
+ if (testResultPart.getStatus().equals(TestStatus.ERROR)) {
+ resultPartNode.setProperty(SLC_ERROR_MESSAGE,
+ (testResultPart.getExceptionMessage() == null) ? ""
+ : testResultPart.getExceptionMessage());
+ }
+
+ // helper update aggregate status node
+ Node mainStatus;
+ if (!node.hasNode(SLC_AGGREGATED_STATUS)) {
+
+ mainStatus = node.addNode(SLC_AGGREGATED_STATUS,
+ SlcTypes.SLC_CHECK);
+ mainStatus.setProperty(SLC_SUCCESS,
+ resultPartNode.getProperty(SLC_SUCCESS).getBoolean());
+ if (resultPartNode.hasProperty(SLC_MESSAGE))
+ mainStatus.setProperty(SLC_MESSAGE, resultPartNode
+ .getProperty(SLC_MESSAGE).getString());
+ if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE))
+ mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode
+ .getProperty(SLC_ERROR_MESSAGE).getString());
+ } else {
+ mainStatus = node.getNode(SLC_AGGREGATED_STATUS);
+ if (mainStatus.hasProperty(SLC_ERROR_MESSAGE)) {
+ // main status already in error we do nothing
+ } else if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE)) {
+ // main status was not in error and new result part is in
+ // error; we update main status
+ mainStatus.setProperty(SLC_SUCCESS, false);
+ mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode
+ .getProperty(SLC_ERROR_MESSAGE).getString());
+ if (resultPartNode.hasProperty(SLC_MESSAGE))
+ mainStatus.setProperty(SLC_MESSAGE, resultPartNode
+ .getProperty(SLC_MESSAGE).getString());
+ else
+ // remove old message to remain consistent
+ mainStatus.setProperty(SLC_MESSAGE, "");
+ } else if (!mainStatus.getProperty(SLC_SUCCESS).getBoolean()) {
+ // main status was already failed and new result part is not
+ // in error, we do nothing
+ } else if (!resultPartNode.getProperty(SLC_SUCCESS)
+ .getBoolean()) {
+ // new resultPart that is failed
+ mainStatus.setProperty(SLC_SUCCESS, false);
+ if (resultPartNode.hasProperty(SLC_MESSAGE))
+ mainStatus.setProperty(SLC_MESSAGE, resultPartNode
+ .getProperty(SLC_MESSAGE).getString());
+ else
+ // remove old message to remain consistent
+ mainStatus.setProperty(SLC_MESSAGE, "");
+ } else if (resultPartNode.hasProperty(SLC_MESSAGE)
+ && (!mainStatus.hasProperty(SLC_MESSAGE) || (""
+ .equals(mainStatus.getProperty(SLC_MESSAGE)
+ .getString().trim())))) {
+ mainStatus.setProperty(SLC_MESSAGE, resultPartNode
+ .getProperty(SLC_MESSAGE).getString());
+ }
+ }
+ JcrUtils.updateLastModified(node);
+ node.getSession().save();
+ } catch (Exception e) {
+ JcrUtils.discardUnderlyingSessionQuietly(node);
+ throw new SlcException("Cannot add ResultPart to node " + node, e);
+ }
+ }
+
+ public String getUuid() {
+ Node node = getNode();
+ try {
+ return node.getProperty(SLC_UUID).getString();
+ } catch (Exception e) {
+ throw new SlcException("Cannot get UUID from " + node, e);
+ }
+ }
+
+ /** JCR session is NOT logged out */
+ public void close() {
+ Node node = getNode();
+ try {
+ if (node.hasNode(SLC_COMPLETED))
+ return;
+ node.setProperty(SLC_COMPLETED, new GregorianCalendar());
+ JcrUtils.updateLastModified(node);
+ node.getSession().save();
+ } catch (Exception e) {
+ JcrUtils.discardUnderlyingSessionQuietly(node);
+ throw new SlcException("Cannot get close date from " + node, e);
+ }
+ }
+
+ public Date getCloseDate() {
+ Node node = getNode();
+ try {
+ if (!node.hasNode(SLC_COMPLETED))
+ return null;
+ return node.getProperty(SLC_COMPLETED).getDate().getTime();
+ } catch (Exception e) {
+ throw new SlcException("Cannot get close date from " + node, e);
+ }
+ }
+
+ public Map<String, String> getAttributes() {
+ Node node = getNode();
+ try {
+ Map<String, String> map = new HashMap<String, String>();
+ PropertyIterator pit = node.getProperties();
+ while (pit.hasNext()) {
+ Property p = pit.nextProperty();
+ if (!p.isMultiple())
+ map.put(p.getName(), p.getValue().getString());
+ }
+ return map;
+ } catch (Exception e) {
+ throw new SlcException("Cannot get close date from " + node, e);
+ }
+ }
+
+ public void addAttachment(Attachment attachment) {
+ // TODO implement it
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+ public void setResultType(String resultType) {
+ this.resultType = resultType;
+ }
+
+ public void setAttributes(Map<String, String> attributes) {
+ if (uuid != null)
+ throw new SlcException(
+ "Attributes cannot be set on an already initialized test result."
+ + " Update the related JCR node directly instead.");
+ this.attributes = attributes;
+ }
+
+ public void setCredentials(Credentials credentials) {
+ this.credentials = credentials;
+ }
+}
--- /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.jcr;
+
+/** JCR related constants used across SLC */
+public interface SlcJcrConstants {
+ public final static String PROPERTY_PATH = "argeo.slc.jcr.path";
+
+ public final static String SLC_BASE_PATH = "/" + SlcNames.SLC_SYSTEM;
+ public final static String AGENTS_BASE_PATH = SLC_BASE_PATH + "/"
+ + SlcNames.SLC_AGENTS;
+ public final static String VM_AGENT_FACTORY_PATH = AGENTS_BASE_PATH + "/"
+ + SlcNames.SLC_VM;
+}
--- /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.jcr;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.UserJcrUtils;
+import org.argeo.slc.SlcException;
+
+/**
+ * Utilities around the SLC JCR Result model. Note that it relies on fixed base
+ * paths (convention over configuration) for optimization purposes.
+ */
+public class SlcJcrResultUtils {
+
+ /**
+ * Returns the path to the current slc:result node
+ */
+ public static String getSlcResultsBasePath(Session session) {
+ try {
+ Node userHome = UserJcrUtils.getUserHome(session);
+ if (userHome == null)
+ throw new SlcException("No user home available for "
+ + session.getUserID());
+ return userHome.getPath() + '/' + SlcNames.SLC_SYSTEM + '/'
+ + SlcNames.SLC_RESULTS;
+ } catch (RepositoryException re) {
+ throw new SlcException(
+ "Unexpected error while getting Slc Results Base Path.", re);
+ }
+ }
+
+ /**
+ * Returns the base node to store SlcResults. If it does not exists, it is
+ * created. If a node already exists at the given path with the wrong type,
+ * it throws an exception.
+ *
+ * @param session
+ * @return
+ */
+ public static Node getSlcResultsParentNode(Session session) {
+ try {
+ String absPath = getSlcResultsBasePath(session);
+ if (session.nodeExists(absPath)) {
+ Node currNode = session.getNode(absPath);
+ if (currNode.isNodeType(NodeType.NT_UNSTRUCTURED))
+ return currNode;
+ else
+ throw new SlcException(
+ "A node already exists at this path : " + absPath
+ + " that has the wrong type. ");
+ } else {
+ Node slcResParNode = JcrUtils.mkdirs(session, absPath);
+ slcResParNode.setPrimaryType(NodeType.NT_UNSTRUCTURED);
+ session.save();
+ return slcResParNode;
+ }
+ } catch (RepositoryException re) {
+ throw new SlcException(
+ "Unexpected error while creating slcResult root parent node.",
+ re);
+ }
+ }
+
+ /**
+ * Returns the path to the current Result UI specific node, depending the
+ * current user
+ */
+ public static String getMyResultsBasePath(Session session) {
+ try {
+ Node userHome = UserJcrUtils.getUserHome(session);
+ if (userHome == null)
+ throw new SlcException("No user home available for "
+ + session.getUserID());
+ return userHome.getPath() + '/' + SlcNames.SLC_SYSTEM + '/'
+ + SlcNames.SLC_MY_RESULTS;
+ } catch (RepositoryException re) {
+ throw new SlcException(
+ "Unexpected error while getting Slc Results Base Path.", re);
+ }
+ }
+
+ /**
+ * Creates a new node with type SlcTypes.SLC_MY_RESULT_ROOT_FOLDER at the
+ * given absolute path. If a node already exists at the given path, returns
+ * that node if it has the correct type and throws an exception otherwise.
+ *
+ * @param session
+ * @return
+ */
+ public static Node getMyResultParentNode(Session session) {
+ try {
+ String absPath = getMyResultsBasePath(session);
+ if (session.nodeExists(absPath)) {
+ Node currNode = session.getNode(absPath);
+ if (currNode.isNodeType(SlcTypes.SLC_MY_RESULT_ROOT_FOLDER))
+ return currNode;
+ else
+ throw new SlcException(
+ "A node already exists at this path : " + absPath
+ + " that has the wrong type. ");
+ } else {
+ Node myResParNode = JcrUtils.mkdirs(session, absPath);
+ myResParNode.setPrimaryType(SlcTypes.SLC_MY_RESULT_ROOT_FOLDER);
+ session.save();
+ return myResParNode;
+ }
+ } catch (RepositoryException re) {
+ throw new SlcException(
+ "Unexpected error while creating user MyResult base node.",
+ re);
+ }
+ }
+
+ /**
+ * Creates a new node with type SlcTypes.SLC_RESULT_FOLDER at the given
+ * absolute path. If a node already exists at the given path, returns that
+ * node if it has the correct type and throws an exception otherwise.
+ *
+ * @param session
+ * @param absPath
+ * @return
+ */
+ public static synchronized Node createResultFolderNode(Session session,
+ String absPath) {
+ try {
+ if (session.nodeExists(absPath)) {
+ // Sanity check
+ Node currNode = session.getNode(absPath);
+ if (currNode.isNodeType(SlcTypes.SLC_RESULT_FOLDER))
+ return currNode;
+ else
+ throw new SlcException(
+ "A node already exists at this path : " + absPath
+ + " that has the wrong type. ");
+ }
+ Node rfNode = JcrUtils.mkdirs(session, absPath);
+ rfNode.setPrimaryType(SlcTypes.SLC_RESULT_FOLDER);
+ Node statusNode = rfNode.addNode(SlcNames.SLC_AGGREGATED_STATUS,
+ SlcTypes.SLC_CHECK);
+ statusNode.setProperty(SlcNames.SLC_SUCCESS, true);
+ session.save();
+ return rfNode;
+ } catch (RepositoryException re) {
+ throw new SlcException(
+ "Unexpected error while creating Result Folder node.", re);
+ }
+ }
+}
\ No newline at end of file
--- /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.jcr;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.UserJcrUtils;
+import org.argeo.slc.BasicNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.PrimitiveAccessor;
+import org.argeo.slc.core.execution.PrimitiveUtils;
+import org.argeo.slc.deploy.ModuleDescriptor;
+import org.argeo.slc.test.TestStatus;
+
+/**
+ * Utilities around the SLC JCR model. Note that it relies on fixed base paths
+ * (convention over configuration) for optimization purposes.
+ */
+public class SlcJcrUtils implements SlcNames {
+ public final static Integer AGENT_FACTORY_DEPTH = 3;
+
+ /** Extracts the path of a flow relative to its execution module */
+ public static String flowRelativePath(String fullFlowPath) {
+ String[] tokens = fullFlowPath.split("/");
+ StringBuffer buf = new StringBuffer(fullFlowPath.length());
+ for (int i = AGENT_FACTORY_DEPTH + 3; i < tokens.length; i++) {
+ buf.append('/').append(tokens[i]);
+ }
+ return buf.toString();
+ }
+
+ /** Extracts the path to the related execution module */
+ public static String modulePath(String fullFlowPath) {
+ String[] tokens = fullFlowPath.split("/");
+ StringBuffer buf = new StringBuffer(fullFlowPath.length());
+ for (int i = 0; i < AGENT_FACTORY_DEPTH + 3; i++) {
+ if (!tokens[i].equals(""))
+ buf.append('/').append(tokens[i]);
+ }
+ return buf.toString();
+ }
+
+ /** Extracts the module name from a flow path */
+ public static String moduleName(String fullFlowPath) {
+ String[] tokens = fullFlowPath.split("/");
+ String moduleName = tokens[AGENT_FACTORY_DEPTH + 2];
+ moduleName = moduleName.substring(0, moduleName.indexOf('_'));
+ return moduleName;
+ }
+
+ /** Extracts the module name and version from a flow path */
+ public static NameVersion moduleNameVersion(String fullFlowPath) {
+ String[] tokens = fullFlowPath.split("/");
+ String module = tokens[AGENT_FACTORY_DEPTH + 2];
+ String moduleName = module.substring(0, module.indexOf('_'));
+ String moduleVersion = module.substring(module.indexOf('_') + 1);
+ return new BasicNameVersion(moduleName, moduleVersion);
+ }
+
+ /** Module node name based on module name and version */
+ public static String getModuleNodeName(ModuleDescriptor moduleDescriptor) {
+ return moduleDescriptor.getName() + "_" + moduleDescriptor.getVersion();
+ }
+
+ /** Extracts the agent factory of a flow */
+ public static String flowAgentFactoryPath(String fullFlowPath) {
+ String[] tokens = fullFlowPath.split("/");
+ StringBuffer buf = new StringBuffer(fullFlowPath.length());
+ // first token is always empty
+ for (int i = 1; i < AGENT_FACTORY_DEPTH + 1; i++) {
+ buf.append('/').append(tokens[i]);
+ }
+ return buf.toString();
+ }
+
+ /** Create a new execution process path based on the current time */
+ public static String createExecutionProcessPath(Session session, String uuid) {
+ Calendar now = new GregorianCalendar();
+ return getSlcProcessesBasePath(session) + '/'
+ + JcrUtils.dateAsPath(now, true) + uuid;
+ }
+
+ /** Get the base for the user processi. */
+ public static String getSlcProcessesBasePath(Session session) {
+ try {
+ Node userHome = UserJcrUtils.getUserHome(session);
+ if (userHome == null)
+ throw new SlcException("No user home available for "
+ + session.getUserID());
+ return userHome.getPath() + '/' + SlcNames.SLC_SYSTEM + '/'
+ + SlcNames.SLC_PROCESSES;
+ } catch (RepositoryException re) {
+ throw new SlcException(
+ "Unexpected error while getting Slc Results Base Path.", re);
+ }
+ }
+
+ /**
+ * Create a new execution result path in the user home based on the current
+ * time
+ */
+ public static String createResultPath(Session session, String uuid)
+ throws RepositoryException {
+ Calendar now = new GregorianCalendar();
+ StringBuffer absPath = new StringBuffer(
+ SlcJcrResultUtils.getSlcResultsBasePath(session) + '/');
+ // Remove hours and add title property to the result process path on
+ // request of O. Capillon
+ // return getSlcProcessesBasePath(session) + '/'
+ // + JcrUtils.dateAsPath(now, true) + uuid;
+ String relPath = JcrUtils.dateAsPath(now, false);
+ List<String> names = JcrUtils.tokenize(relPath);
+ for (String name : names) {
+ absPath.append(name + "/");
+ Node node = JcrUtils.mkdirs(session, absPath.toString());
+ try {
+ node.addMixin(NodeType.MIX_TITLE);
+ node.setProperty(Property.JCR_TITLE, name.substring(1));
+ } catch (RepositoryException e) {
+ throw new SlcException(
+ "unable to create execution process path", e);
+ }
+ }
+ return absPath.toString() + uuid;
+ }
+
+ /**
+ * Set the value of the primitive accessor as a JCR property. Does nothing
+ * if the value is null.
+ */
+ public static void setPrimitiveAsProperty(Node node, String propertyName,
+ PrimitiveAccessor primitiveAccessor) {
+ String type = primitiveAccessor.getType();
+ Object value = primitiveAccessor.getValue();
+ setPrimitiveAsProperty(node, propertyName, type, value);
+ }
+
+ /** Map a primitive value to JCR property value. */
+ public static void setPrimitiveAsProperty(Node node, String propertyName,
+ String type, Object value) {
+ if (value == null)
+ return;
+ if (value instanceof CharSequence)
+ value = PrimitiveUtils.convert(type,
+ ((CharSequence) value).toString());
+ if (value instanceof char[])
+ value = new String((char[]) value);
+
+ try {
+ if (type.equals(PrimitiveAccessor.TYPE_STRING))
+ node.setProperty(propertyName, value.toString());
+ else if (type.equals(PrimitiveAccessor.TYPE_PASSWORD))
+ node.setProperty(propertyName, value.toString());
+ else if (type.equals(PrimitiveAccessor.TYPE_INTEGER))
+ node.setProperty(propertyName, (long) ((Integer) value));
+ else if (type.equals(PrimitiveAccessor.TYPE_LONG))
+ node.setProperty(propertyName, ((Long) value));
+ else if (type.equals(PrimitiveAccessor.TYPE_FLOAT))
+ node.setProperty(propertyName, (double) ((Float) value));
+ else if (type.equals(PrimitiveAccessor.TYPE_DOUBLE))
+ node.setProperty(propertyName, ((Double) value));
+ else if (type.equals(PrimitiveAccessor.TYPE_BOOLEAN))
+ node.setProperty(propertyName, ((Boolean) value));
+ else
+ throw new SlcException("Unsupported type " + type);
+ } catch (RepositoryException e) {
+ throw new SlcException("Cannot set primitive of " + type
+ + " as property " + propertyName + " on " + node, e);
+ }
+ }
+
+ /** Aggregates the {@link TestStatus} of this sub-tree. */
+ public static Integer aggregateTestStatus(Node node) {
+ try {
+ Integer status = TestStatus.PASSED;
+ if (node.isNodeType(SlcTypes.SLC_CHECK))
+ if (node.getProperty(SLC_SUCCESS).getBoolean())
+ status = TestStatus.PASSED;
+ else if (node.hasProperty(SLC_ERROR_MESSAGE))
+ status = TestStatus.ERROR;
+ else
+ status = TestStatus.FAILED;
+
+ NodeIterator it = node.getNodes();
+ while (it.hasNext()) {
+ Node curr = it.nextNode();
+
+ // Manually skip aggregated status
+ if (!SlcNames.SLC_AGGREGATED_STATUS.equals(curr.getName())) {
+ Integer childStatus = aggregateTestStatus(curr);
+ if (childStatus > status)
+ status = childStatus;
+ }
+ }
+ return status;
+ } catch (Exception e) {
+ throw new SlcException("Could not aggregate test status from "
+ + node, e);
+ }
+ }
+
+ /**
+ * Aggregates the {@link TestStatus} of this sub-tree.
+ *
+ * @return the same {@link StringBuffer}, for convenience (typically calling
+ * toString() on it)
+ */
+ public static StringBuffer aggregateTestMessages(Node node,
+ StringBuffer messages) {
+ try {
+ if (node.isNodeType(SlcTypes.SLC_CHECK)) {
+ if (node.hasProperty(SLC_MESSAGE)) {
+ if (messages.length() > 0)
+ messages.append('\n');
+ messages.append(node.getProperty(SLC_MESSAGE).getString());
+ }
+ if (node.hasProperty(SLC_ERROR_MESSAGE)) {
+ if (messages.length() > 0)
+ messages.append('\n');
+ messages.append(node.getProperty(SLC_ERROR_MESSAGE)
+ .getString());
+ }
+ }
+ NodeIterator it = node.getNodes();
+ while (it.hasNext()) {
+ Node child = it.nextNode();
+ // Manually skip aggregated status
+ if (!SlcNames.SLC_AGGREGATED_STATUS.equals(child.getName())) {
+ aggregateTestMessages(child, messages);
+ }
+ }
+ return messages;
+ } catch (Exception e) {
+ throw new SlcException("Could not aggregate test messages from "
+ + node, e);
+ }
+ }
+
+ /** Prevents instantiation */
+ private SlcJcrUtils() {
+ }
+}
\ No newline at end of file
--- /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.jcr;
+
+/** JCR names used by SLC */
+public interface SlcNames {
+ public final static String SLC_ = "slc:";
+
+ /*
+ * GENERAL
+ */
+ public final static String SLC_UUID = "slc:uuid";
+ public final static String SLC_STATUS = "slc:status";
+ // generic name for result parts of a given test result (slc:testResult)
+ // note that corresponding nodes can be retrieved using
+ // myTestResultNode.getNodes(SLC_RESULT_PART+"*") method
+ public final static String SLC_RESULT_PART = "slc:resultPart";
+ // Fixed name of the child node of a slc:testResult of type
+ // slc:check that aggregate status of all result parts of a given test
+ // result
+ public final static String SLC_AGGREGATED_STATUS = "slc:aggregatedStatus";
+
+ public final static String SLC_TYPE = "slc:type";
+ public final static String SLC_NAME = "slc:name";
+ public final static String SLC_VERSION = "slc:version";
+ public final static String SLC_CATEGORY = "slc:category";
+ public final static String SLC_VALUE = "slc:value";
+ public final static String SLC_ADDRESS = "slc:address";
+ public final static String SLC_METADATA = "slc:metadata";
+
+ public final static String SLC_TIMESTAMP = "slc:timestamp";
+ public final static String SLC_STARTED = "slc:started";
+ public final static String SLC_COMPLETED = "slc:completed";
+
+ public final static String SLC_VM = "slc:vm";
+ /*
+ * SLC RUNTIME
+ */
+ // execution
+ public final static String SLC_SPEC = "slc:spec";
+ public final static String SLC_EXECUTION_SPECS = "slc:executionSpecs";
+ public final static String SLC_FLOW = "slc:flow";
+ public final static String SLC_LOG = "slc:log";
+ public final static String SLC_AGENTS = "slc:agents";
+
+ // spec attribute
+ public final static String SLC_IS_IMMUTABLE = "slc:isImmutable";
+ public final static String SLC_IS_CONSTANT = "slc:isConstant";
+ public final static String SLC_IS_HIDDEN = "slc:isHidden";
+
+ // base directories
+ public final static String SLC_SYSTEM = "slc:system";
+ public final static String SLC_RESULTS = "slc:results";
+ public final static String SLC_MY_RESULTS = "slc:myResults";
+ public final static String SLC_PROCESSES = "slc:processes";
+
+ // result
+ public final static String SLC_SUCCESS = "slc:success";
+ public final static String SLC_MESSAGE = "slc:message";
+ public final static String SLC_TAG = "slc:tag";
+ public final static String SLC_ERROR_MESSAGE = "slc:errorMessage";
+ public final static String SLC_TEST_CASE = "slc:testCase";
+ public final static String SLC_TEST_CASE_TYPE = "slc:testCaseType";
+
+ // diff result
+ public final static String SLC_SUMMARY = "slc:summary";
+ public final static String SLC_ISSUES = "slc:issues";
+
+ /*
+ * SLC REPO
+ */
+ // shared
+ public final static String SLC_URL = "slc:url";
+ public final static String SLC_OPTIONAL = "slc:optional";
+ public final static String SLC_AS_STRING = "slc:asString";
+
+ // origin
+ public final static String SLC_ORIGIN = "slc:origin";
+ public final static String SLC_PROXY = "slc:proxy";
+
+ // slc:artifact
+ public final static String SLC_ARTIFACT_ID = "slc:artifactId";
+ public final static String SLC_GROUP_ID = "slc:groupId";
+ public final static String SLC_GROUP_BASE_ID = "slc:groupBaseId";
+ public final static String SLC_ARTIFACT_VERSION = "slc:artifactVersion";
+ public final static String SLC_ARTIFACT_EXTENSION = "slc:artifactExtension";
+ public final static String SLC_ARTIFACT_CLASSIFIER = "slc:artifactClassifier";
+
+ // slc:jarArtifact
+ public final static String SLC_MANIFEST = "slc:manifest";
+
+ // shared OSGi
+ public final static String SLC_SYMBOLIC_NAME = "slc:symbolic-name";
+ public final static String SLC_BUNDLE_VERSION = "slc:bundle-version";
+
+ // slc:osgiBaseVersion
+ public final static String SLC_MAJOR = "slc:major";
+ public final static String SLC_MINOR = "slc:minor";
+ public final static String SLC_MICRO = "slc:micro";
+ // slc:osgiVersion
+ public final static String SLC_QUALIFIER = "slc:qualifier";
+
+ // slc:exportedPackage
+ public final static String SLC_USES = "slc:uses";
+
+ // slc:modularDistribution
+ public final static String SLC_MODULES = "slc:modules";
+
+ // RPM
+ // slc:rpm
+ public final static String SLC_RPM_VERSION = "slc:rpmVersion";
+ public final static String SLC_RPM_RELEASE = "slc:rpmRelease";
+ public final static String SLC_RPM_ARCH = "slc:rpmArch";
+ public final static String SLC_RPM_ARCHIVE_SIZE = "slc:rpmArchiveSize";
+}
--- /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.jcr;
+
+/** JCR node types used by SLC */
+public interface SlcTypes {
+
+ public final static String SLC_NAME_VERSION = "slc:nameVersion";
+ public final static String SLC_CATEGORIZED_NAME_VERSION = "slc:categorizedNameVersion";
+
+ public final static String SLC_AGENT_FACTORY = "slc:agentFactory";
+ public final static String SLC_AGENT = "slc:agent";
+ public final static String SLC_MODULE = "slc:module";
+ public final static String SLC_EXECUTION_MODULE = "slc:executionModule";
+ public final static String SLC_EXECUTION_SPEC = "slc:executionSpec";
+ public final static String SLC_EXECUTION_FLOW = "slc:executionFlow";
+ public final static String SLC_PROCESS = "slc:process";
+ public final static String SLC_REALIZED_FLOW = "slc:realizedFlow";
+
+ public final static String SLC_EXECUTION_SPEC_ATTRIBUTE = "slc:executionSpecAttribute";
+ public final static String SLC_PRIMITIVE_SPEC_ATTRIBUTE = "slc:primitiveSpecAttribute";
+ public final static String SLC_REF_SPEC_ATTRIBUTE = "slc:refSpecAttribute";
+
+ public final static String SLC_TEST_RESULT = "slc:testResult";
+ public final static String SLC_CHECK = "slc:check";
+ public final static String SLC_PROPERTY = "slc:property";
+ public final static String SLC_DIFF_RESULT = "slc:diffResult";
+
+ // Node types used for user defined and managed result UI tree
+ public final static String SLC_MY_RESULT_ROOT_FOLDER = "slc:myResultRootFolder";
+ public final static String SLC_RESULT_FOLDER = "slc:resultFolder";
+
+ // Log levels
+ public final static String SLC_LOG_ENTRY = "slc:logEntry";
+ public final static String SLC_LOG_TRACE = "slc:logTrace";
+ public final static String SLC_LOG_DEBUG = "slc:logDebug";
+ public final static String SLC_LOG_INFO = "slc:logInfo";
+ public final static String SLC_LOG_WARNING = "slc:logWarning";
+ public final static String SLC_LOG_ERROR = "slc:logError";
+
+ /*
+ * REPO
+ */
+ public final static String SLC_ARTIFACT = "slc:artifact";
+ public final static String SLC_ARTIFACT_VERSION_BASE = "slc:artifactVersion";
+ public final static String SLC_ARTIFACT_BASE = "slc:artifactBase";
+ public final static String SLC_GROUP_BASE = "slc:groupBase";
+ public final static String SLC_JAR_FILE = "slc:jarFile";
+ public final static String SLC_BUNDLE_ARTIFACT = "slc:bundleArtifact";
+ public final static String SLC_OSGI_VERSION = "slc:osgiVersion";
+ public final static String SLC_JAVA_PACKAGE = "slc:javaPackage";
+ public final static String SLC_EXPORTED_PACKAGE = "slc:exportedPackage";
+ public final static String SLC_IMPORTED_PACKAGE = "slc:importedPackage";
+ public final static String SLC_DYNAMIC_IMPORTED_PACKAGE = "slc:dynamicImportedPackage";
+ public final static String SLC_REQUIRED_BUNDLE = "slc:requiredBundle";
+ public final static String SLC_FRAGMENT_HOST = "slc:fragmentHost";
+
+ // Distribution management
+ // public final static String SLC_CATEGORY = "slc:category";
+ public final static String SLC_MODULAR_DISTRIBUTION_BASE = "slc:modularDistributionBase";
+ public final static String SLC_MODULAR_DISTRIBUTION = "slc:modularDistribution";
+ public final static String SLC_MODULE_COORDINATES = "slc:moduleCoordinates";
+
+ // origin
+ public final static String SLC_KNOWN_ORIGIN = "slc:knownOrigin";
+ public final static String SLC_PROXIED = "slc:proxied";
+
+ // rpm
+ public final static String SLC_RPM = "slc:rpm";
+}
--- /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.jcr.execution;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.UUID;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.DefaultAgent;
+import org.argeo.slc.core.execution.ProcessThread;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.jcr.SlcJcrConstants;
+import org.argeo.slc.jcr.SlcNames;
+import org.argeo.slc.jcr.SlcTypes;
+
+/** SLC VM agent synchronizing with a JCR repository. */
+public class JcrAgent extends DefaultAgent implements SlcNames {
+ // final static String ROLE_REMOTE = "ROLE_REMOTE";
+ final static String NODE_REPO_URI = "argeo.node.repo.uri";
+
+ private Repository repository;
+
+ private String agentNodeName = "default";
+
+ /*
+ * LIFECYCLE
+ */
+ protected String initAgentUuid() {
+ Session session = null;
+ try {
+ session = repository.login();
+
+ String agentFactoryPath = getAgentFactoryPath();
+ Node vmAgentFactoryNode = JcrUtils.mkdirsSafe(session,
+ agentFactoryPath, SlcTypes.SLC_AGENT_FACTORY);
+ if (!vmAgentFactoryNode.hasNode(agentNodeName)) {
+ String uuid = UUID.randomUUID().toString();
+ Node agentNode = vmAgentFactoryNode.addNode(agentNodeName,
+ SlcTypes.SLC_AGENT);
+ agentNode.setProperty(SLC_UUID, uuid);
+ }
+ session.save();
+ return vmAgentFactoryNode.getNode(agentNodeName)
+ .getProperty(SLC_UUID).getString();
+ } catch (RepositoryException e) {
+ JcrUtils.discardQuietly(session);
+ throw new SlcException("Cannot find JCR agent UUID", e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+ }
+
+ @Override
+ public void destroy() {
+ super.destroy();
+ }
+
+ /*
+ * SLC AGENT
+ */
+ @Override
+ protected ProcessThread createProcessThread(
+ ThreadGroup processesThreadGroup,
+ ExecutionModulesManager modulesManager, ExecutionProcess process) {
+ if (process instanceof JcrExecutionProcess)
+ return new JcrProcessThread(processesThreadGroup, modulesManager,
+ (JcrExecutionProcess) process);
+ else
+ return super.createProcessThread(processesThreadGroup,
+ modulesManager, process);
+ }
+
+ /*
+ * UTILITIES
+ */
+ public String getNodePath() {
+ return getAgentFactoryPath() + '/' + getAgentNodeName();
+ }
+
+ public String getAgentFactoryPath() {
+ try {
+ Boolean isRemote = System.getProperty(NODE_REPO_URI) != null;
+ String agentFactoryPath;
+ if (isRemote) {
+ InetAddress localhost = InetAddress.getLocalHost();
+ agentFactoryPath = SlcJcrConstants.AGENTS_BASE_PATH + "/"
+ + localhost.getCanonicalHostName();
+
+ if (agentFactoryPath
+ .equals(SlcJcrConstants.VM_AGENT_FACTORY_PATH))
+ throw new SlcException("Unsupported hostname "
+ + localhost.getCanonicalHostName());
+ } else {// local
+ agentFactoryPath = SlcJcrConstants.VM_AGENT_FACTORY_PATH;
+ }
+ return agentFactoryPath;
+ } catch (UnknownHostException e) {
+ throw new SlcException("Cannot find agent factory base path", e);
+ }
+ }
+
+ /*
+ * BEAN
+ */
+ public String getAgentNodeName() {
+ return agentNodeName;
+ }
+
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+ public void setAgentNodeName(String agentNodeName) {
+ this.agentNodeName = agentNodeName;
+ }
+}
--- /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.jcr.execution;
+
+import javax.jcr.Session;
+
+import org.argeo.slc.core.attachment.Attachment;
+import org.argeo.slc.core.attachment.AttachmentUploader;
+import org.springframework.core.io.Resource;
+
+/** JCR based attachment uploader */
+public class JcrAttachmentUploader implements AttachmentUploader {
+ private Session session;
+
+ public void upload(Attachment attachment, Resource resource) {
+ session.toString();
+ // not yet implemented, need to review the interface
+ }
+
+ public void setSession(Session session) {
+ this.session = session;
+ }
+
+}
--- /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.jcr.execution;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
+import org.argeo.slc.core.execution.PrimitiveValue;
+import org.argeo.slc.core.execution.RefSpecAttribute;
+import org.argeo.slc.core.execution.RefValueChoice;
+import org.argeo.slc.deploy.ModuleDescriptor;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
+import org.argeo.slc.execution.ExecutionModulesListener;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.argeo.slc.jcr.SlcJcrUtils;
+import org.argeo.slc.jcr.SlcNames;
+import org.argeo.slc.jcr.SlcTypes;
+
+/**
+ * Synchronizes the local execution runtime with a JCR repository. For the time
+ * being the state is completely reset from one start to another.
+ */
+public class JcrExecutionModulesListener implements ExecutionModulesListener,
+ SlcNames {
+ private final static String SLC_EXECUTION_MODULES_PROPERTY = "slc.executionModules";
+
+ private final static Log log = LogFactory
+ .getLog(JcrExecutionModulesListener.class);
+ private JcrAgent agent;
+
+ private ExecutionModulesManager modulesManager;
+
+ private Repository repository;
+ /**
+ * We don't use a thread bound session because many different threads will
+ * call this critical component and we don't want to login each time. We
+ * therefore rather protect access to this session via synchronized.
+ */
+ private Session session;
+
+ /*
+ * LIFECYCLE
+ */
+ public void init() {
+ try {
+ session = repository.login();
+ clearAgent();
+ if (modulesManager != null) {
+ Node agentNode = session.getNode(agent.getNodePath());
+
+ List<ModuleDescriptor> moduleDescriptors = modulesManager
+ .listModules();
+
+ // scan SLC-ExecutionModule metadata
+ for (ModuleDescriptor md : moduleDescriptors) {
+ if (md.getMetadata().containsKey(
+ ExecutionModuleDescriptor.SLC_EXECUTION_MODULE)) {
+ String moduleNodeName = SlcJcrUtils
+ .getModuleNodeName(md);
+ Node moduleNode = agentNode.hasNode(moduleNodeName) ? agentNode
+ .getNode(moduleNodeName) : agentNode
+ .addNode(moduleNodeName);
+ moduleNode.addMixin(SlcTypes.SLC_EXECUTION_MODULE);
+ moduleNode.setProperty(SLC_NAME, md.getName());
+ moduleNode.setProperty(SLC_VERSION, md.getVersion());
+ moduleNode.setProperty(Property.JCR_TITLE,
+ md.getTitle());
+ moduleNode.setProperty(Property.JCR_DESCRIPTION,
+ md.getDescription());
+ moduleNode.setProperty(SLC_STARTED, md.getStarted());
+ }
+ }
+
+ // scan execution modules property
+ String executionModules = System
+ .getProperty(SLC_EXECUTION_MODULES_PROPERTY);
+ if (executionModules != null) {
+ for (String executionModule : executionModules.split(",")) {
+ allModules: for (ModuleDescriptor md : moduleDescriptors) {
+ String moduleNodeName = SlcJcrUtils
+ .getModuleNodeName(md);
+ if (md.getName().equals(executionModule)) {
+ Node moduleNode = agentNode
+ .hasNode(moduleNodeName) ? agentNode
+ .getNode(moduleNodeName) : agentNode
+ .addNode(moduleNodeName);
+ moduleNode
+ .addMixin(SlcTypes.SLC_EXECUTION_MODULE);
+ moduleNode.setProperty(SLC_NAME, md.getName());
+ moduleNode.setProperty(SLC_VERSION,
+ md.getVersion());
+ moduleNode.setProperty(Property.JCR_TITLE,
+ md.getTitle());
+ moduleNode.setProperty(
+ Property.JCR_DESCRIPTION,
+ md.getDescription());
+ moduleNode.setProperty(SLC_STARTED,
+ md.getStarted());
+ break allModules;
+ }
+ }
+ }
+
+ // save if needed
+ if (session.hasPendingChanges())
+ session.save();
+ }
+ }
+ } catch (RepositoryException e) {
+ JcrUtils.discardQuietly(session);
+ JcrUtils.logoutQuietly(session);
+ throw new SlcException("Cannot initialize modules", e);
+ }
+ }
+
+ public void destroy() {
+ clearAgent();
+ JcrUtils.logoutQuietly(session);
+ }
+
+ protected synchronized void clearAgent() {
+ try {
+ Node agentNode = session.getNode(agent.getNodePath());
+ for (NodeIterator nit = agentNode.getNodes(); nit.hasNext();)
+ nit.nextNode().remove();
+ session.save();
+ } catch (RepositoryException e) {
+ JcrUtils.discardQuietly(session);
+ throw new SlcException("Cannot clear agent " + agent, e);
+ }
+ }
+
+ /*
+ * EXECUTION MODULES LISTENER
+ */
+
+ public synchronized void executionModuleAdded(
+ ModuleDescriptor moduleDescriptor) {
+ syncExecutionModule(moduleDescriptor);
+ }
+
+ protected void syncExecutionModule(ModuleDescriptor moduleDescriptor) {
+ try {
+ Node agentNode = session.getNode(agent.getNodePath());
+ String moduleNodeName = SlcJcrUtils
+ .getModuleNodeName(moduleDescriptor);
+ Node moduleNode = agentNode.hasNode(moduleNodeName) ? agentNode
+ .getNode(moduleNodeName) : agentNode
+ .addNode(moduleNodeName);
+ moduleNode.addMixin(SlcTypes.SLC_EXECUTION_MODULE);
+ moduleNode.setProperty(SLC_NAME, moduleDescriptor.getName());
+ moduleNode.setProperty(SLC_VERSION, moduleDescriptor.getVersion());
+ moduleNode.setProperty(Property.JCR_TITLE,
+ moduleDescriptor.getTitle());
+ moduleNode.setProperty(Property.JCR_DESCRIPTION,
+ moduleDescriptor.getDescription());
+ moduleNode.setProperty(SLC_STARTED, moduleDescriptor.getStarted());
+ session.save();
+ } catch (RepositoryException e) {
+ JcrUtils.discardQuietly(session);
+ throw new SlcException("Cannot sync module " + moduleDescriptor, e);
+ }
+ }
+
+ public synchronized void executionModuleRemoved(
+ ModuleDescriptor moduleDescriptor) {
+ try {
+ String moduleName = SlcJcrUtils.getModuleNodeName(moduleDescriptor);
+ Node agentNode = session.getNode(agent.getNodePath());
+ if (agentNode.hasNode(moduleName)) {
+ Node moduleNode = agentNode.getNode(moduleName);
+ for (NodeIterator nit = moduleNode.getNodes(); nit.hasNext();) {
+ nit.nextNode().remove();
+ }
+ moduleNode.setProperty(SLC_STARTED, false);
+ }
+ session.save();
+ } catch (RepositoryException e) {
+ JcrUtils.discardQuietly(session);
+ throw new SlcException("Cannot remove module " + moduleDescriptor,
+ e);
+ }
+ }
+
+ public synchronized void executionFlowAdded(ModuleDescriptor module,
+ ExecutionFlowDescriptor efd) {
+ try {
+ Node agentNode = session.getNode(agent.getNodePath());
+ Node moduleNode = agentNode.getNode(SlcJcrUtils
+ .getModuleNodeName(module));
+ String relativePath = getExecutionFlowRelativePath(efd);
+ @SuppressWarnings("unused")
+ Node flowNode = null;
+ if (!moduleNode.hasNode(relativePath)) {
+ flowNode = createExecutionFlowNode(moduleNode, relativePath,
+ efd);
+ session.save();
+ } else {
+ flowNode = moduleNode.getNode(relativePath);
+ }
+
+ if (log.isTraceEnabled())
+ log.trace("Flow " + efd + " added to JCR");
+ } catch (RepositoryException e) {
+ JcrUtils.discardQuietly(session);
+ throw new SlcException("Cannot add flow " + efd + " from module "
+ + module, e);
+ }
+
+ }
+
+ protected Node createExecutionFlowNode(Node moduleNode,
+ String relativePath, ExecutionFlowDescriptor efd)
+ throws RepositoryException {
+ Node flowNode = null;
+ List<String> pathTokens = Arrays.asList(relativePath.split("/"));
+
+ Iterator<String> names = pathTokens.iterator();
+ // create intermediary paths
+ Node currNode = moduleNode;
+ while (names.hasNext()) {
+ String name = names.next();
+ if (currNode.hasNode(name))
+ currNode = currNode.getNode(name);
+ else {
+ if (names.hasNext())
+ currNode = currNode.addNode(name);
+ else
+ flowNode = currNode.addNode(name,
+ SlcTypes.SLC_EXECUTION_FLOW);
+ }
+ }
+
+ // name, description
+ flowNode.setProperty(SLC_NAME, efd.getName());
+ String endName = pathTokens.get(pathTokens.size() - 1);
+ flowNode.setProperty(Property.JCR_TITLE, endName);
+ if (efd.getDescription() != null
+ && !efd.getDescription().trim().equals("")) {
+ flowNode.setProperty(Property.JCR_DESCRIPTION, efd.getDescription());
+ } else {
+ flowNode.setProperty(Property.JCR_DESCRIPTION, endName);
+ }
+
+ // execution spec
+ ExecutionSpec executionSpec = efd.getExecutionSpec();
+ String esName = executionSpec.getName();
+ if (esName == null || esName.equals(ExecutionSpec.INTERNAL_NAME)
+ || esName.contains("#")/* automatically generated bean name */) {
+ // internal spec node
+ mapExecutionSpec(flowNode, executionSpec);
+ } else {
+ // reference spec node
+ Node executionSpecsNode = moduleNode.hasNode(SLC_EXECUTION_SPECS) ? moduleNode
+ .getNode(SLC_EXECUTION_SPECS) : moduleNode
+ .addNode(SLC_EXECUTION_SPECS);
+ Node executionSpecNode = executionSpecsNode.addNode(esName,
+ SlcTypes.SLC_EXECUTION_SPEC);
+ executionSpecNode.setProperty(SLC_NAME, esName);
+ executionSpecNode.setProperty(Property.JCR_TITLE, esName);
+ if (executionSpec.getDescription() != null
+ && !executionSpec.getDescription().trim().equals(""))
+ executionSpecNode.setProperty(Property.JCR_DESCRIPTION,
+ executionSpec.getDescription());
+ mapExecutionSpec(executionSpecNode, executionSpec);
+ flowNode.setProperty(SLC_SPEC, executionSpecNode);
+ }
+
+ // flow values
+ for (String attr : efd.getValues().keySet()) {
+ ExecutionSpecAttribute esa = executionSpec.getAttributes()
+ .get(attr);
+ if (esa instanceof PrimitiveSpecAttribute) {
+ PrimitiveSpecAttribute psa = (PrimitiveSpecAttribute) esa;
+ // if spec reference there will be no node at this stage
+ Node valueNode = JcrUtils.getOrAdd(flowNode, attr);
+ valueNode.setProperty(SLC_TYPE, psa.getType());
+ SlcJcrUtils.setPrimitiveAsProperty(valueNode, SLC_VALUE,
+ (PrimitiveValue) efd.getValues().get(attr));
+ }
+ }
+
+ return flowNode;
+ }
+
+ /**
+ * Base can be either an execution spec node, or an execution flow node (in
+ * case the execution spec is internal)
+ */
+ protected void mapExecutionSpec(Node baseNode, ExecutionSpec executionSpec)
+ throws RepositoryException {
+ for (String attrName : executionSpec.getAttributes().keySet()) {
+ ExecutionSpecAttribute esa = executionSpec.getAttributes().get(
+ attrName);
+ Node attrNode = baseNode.addNode(attrName);
+ // booleans
+ attrNode.addMixin(SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE);
+ attrNode.setProperty(SLC_IS_IMMUTABLE, esa.getIsImmutable());
+ attrNode.setProperty(SLC_IS_CONSTANT, esa.getIsConstant());
+ attrNode.setProperty(SLC_IS_HIDDEN, esa.getIsHidden());
+
+ if (esa instanceof PrimitiveSpecAttribute) {
+ attrNode.addMixin(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE);
+ PrimitiveSpecAttribute psa = (PrimitiveSpecAttribute) esa;
+ SlcJcrUtils.setPrimitiveAsProperty(attrNode, SLC_VALUE, psa);
+ attrNode.setProperty(SLC_TYPE, psa.getType());
+ } else if (esa instanceof RefSpecAttribute) {
+ attrNode.addMixin(SlcTypes.SLC_REF_SPEC_ATTRIBUTE);
+ RefSpecAttribute rsa = (RefSpecAttribute) esa;
+ attrNode.setProperty(SLC_TYPE, rsa.getTargetClassName());
+ Object value = rsa.getValue();
+ if (rsa.getChoices() != null) {
+ Integer index = null;
+ int count = 0;
+ for (RefValueChoice choice : rsa.getChoices()) {
+ String name = choice.getName();
+ if (value != null && name.equals(value.toString()))
+ index = count;
+ Node choiceNode = attrNode.addNode(choice.getName());
+ choiceNode.addMixin(NodeType.MIX_TITLE);
+ choiceNode.setProperty(Property.JCR_TITLE,
+ choice.getName());
+ if (choice.getDescription() != null
+ && !choice.getDescription().trim().equals(""))
+ choiceNode.setProperty(Property.JCR_DESCRIPTION,
+ choice.getDescription());
+ count++;
+ }
+
+ if (index != null)
+ attrNode.setProperty(SLC_VALUE, index);
+ }
+ }
+ }
+ }
+
+ public synchronized void executionFlowRemoved(ModuleDescriptor module,
+ ExecutionFlowDescriptor executionFlow) {
+ try {
+ Node agentNode = session.getNode(agent.getNodePath());
+ Node moduleNode = agentNode.getNode(SlcJcrUtils
+ .getModuleNodeName(module));
+ String relativePath = getExecutionFlowRelativePath(executionFlow);
+ if (moduleNode.hasNode(relativePath))
+ moduleNode.getNode(relativePath).remove();
+ agentNode.getSession().save();
+ } catch (RepositoryException e) {
+ throw new SlcException("Cannot remove flow " + executionFlow
+ + " from module " + module, e);
+ }
+ }
+
+ /*
+ * UTILITIES
+ */
+ /** @return the relative path, never starts with '/' */
+ @SuppressWarnings("deprecation")
+ protected String getExecutionFlowRelativePath(
+ ExecutionFlowDescriptor executionFlow) {
+ String relativePath = executionFlow.getPath() == null ? executionFlow
+ .getName() : executionFlow.getPath() + '/'
+ + executionFlow.getName();
+ // we assume that it is more than one char long
+ if (relativePath.charAt(0) == '/')
+ relativePath = relativePath.substring(1);
+ // FIXME quick hack to avoid duplicate '/'
+ relativePath = relativePath.replaceAll("//", "/");
+ return relativePath;
+ }
+
+ /*
+ * BEAN
+ */
+ public void setAgent(JcrAgent agent) {
+ this.agent = agent;
+ }
+
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+ public void setModulesManager(ExecutionModulesManager modulesManager) {
+ this.modulesManager = modulesManager;
+ }
+
+}
--- /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.jcr.execution;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.ProcessThread;
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.ExecutionStep;
+import org.argeo.slc.execution.RealizedFlow;
+import org.argeo.slc.jcr.SlcJcrUtils;
+import org.argeo.slc.jcr.SlcNames;
+import org.argeo.slc.jcr.SlcTypes;
+
+/** Execution process implementation based on a JCR node. */
+public class JcrExecutionProcess implements ExecutionProcess, SlcNames {
+ private final static Log log = LogFactory.getLog(JcrExecutionProcess.class);
+ private final Node node;
+
+ private Long nextLogLine = 1l;
+
+ public JcrExecutionProcess(Node node) {
+ this.node = node;
+ }
+
+ public synchronized String getUuid() {
+ try {
+ return node.getProperty(SLC_UUID).getString();
+ } catch (RepositoryException e) {
+ throw new SlcException("Cannot get uuid for " + node, e);
+ }
+ }
+
+ public synchronized String getStatus() {
+ try {
+ return node.getProperty(SLC_STATUS).getString();
+ } catch (RepositoryException e) {
+ log.error("Cannot get status: " + e);
+ // we should re-throw exception because this information can
+ // probably used for monitoring in case there are already unexpected
+ // exceptions
+ return UNKOWN;
+ }
+ }
+
+ public synchronized void setStatus(String status) {
+ try {
+ node.setProperty(SLC_STATUS, status);
+ // last modified properties needs to be manually updated
+ // see https://issues.apache.org/jira/browse/JCR-2233
+ JcrUtils.updateLastModified(node);
+ node.getSession().save();
+ } catch (RepositoryException e) {
+ JcrUtils.discardUnderlyingSessionQuietly(node);
+ // we should re-throw exception because this information can
+ // probably used for monitoring in case there are already unexpected
+ // exceptions
+ log.error("Cannot set status " + status + ": " + e);
+ }
+ }
+
+ /**
+ * Synchronized in order to make sure that there is no concurrent
+ * modification of {@link #nextLogLine}.
+ */
+ public synchronized void addSteps(List<ExecutionStep> steps) {
+ try {
+ steps: for (ExecutionStep step : steps) {
+ String type;
+ if (step.getType().equals(ExecutionStep.TRACE))
+ type = SlcTypes.SLC_LOG_TRACE;
+ else if (step.getType().equals(ExecutionStep.DEBUG))
+ type = SlcTypes.SLC_LOG_DEBUG;
+ else if (step.getType().equals(ExecutionStep.INFO))
+ type = SlcTypes.SLC_LOG_INFO;
+ else if (step.getType().equals(ExecutionStep.WARNING))
+ type = SlcTypes.SLC_LOG_WARNING;
+ else if (step.getType().equals(ExecutionStep.ERROR))
+ type = SlcTypes.SLC_LOG_ERROR;
+ else
+ // skip
+ continue steps;
+
+ String relPath = SLC_LOG + '/'
+ + step.getThread().replace('/', '_') + '/'
+ + step.getLocation().replace('.', '/');
+ String path = node.getPath() + '/' + relPath;
+ // clean special character
+ // TODO factorize in JcrUtils
+ path = path.replace('@', '_');
+
+ Node location = JcrUtils.mkdirs(node.getSession(), path);
+ Node logEntry = location.addNode(Long.toString(nextLogLine),
+ type);
+ logEntry.setProperty(SLC_MESSAGE, step.getLog());
+ Calendar calendar = new GregorianCalendar();
+ calendar.setTime(step.getTimestamp());
+ logEntry.setProperty(SLC_TIMESTAMP, calendar);
+
+ // System.out.println("Logged " + logEntry.getPath());
+
+ nextLogLine++;
+ }
+
+ // last modified properties needs to be manually updated
+ // see https://issues.apache.org/jira/browse/JCR-2233
+ JcrUtils.updateLastModified(node);
+
+ node.getSession().save();
+ } catch (Exception e) {
+ JcrUtils.discardUnderlyingSessionQuietly(node);
+ e.printStackTrace();
+ }
+ }
+
+ // public Node getNode() {
+ // return node;
+ // }
+
+ public List<RealizedFlow> getRealizedFlows() {
+ try {
+ List<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();
+ Node rootRealizedFlowNode = node.getNode(SLC_FLOW);
+ // we just manage one level for the time being
+ NodeIterator nit = rootRealizedFlowNode.getNodes(SLC_FLOW);
+ while (nit.hasNext()) {
+ Node realizedFlowNode = nit.nextNode();
+
+ if (realizedFlowNode.hasNode(SLC_ADDRESS)) {
+ String flowPath = realizedFlowNode.getNode(SLC_ADDRESS)
+ .getProperty(Property.JCR_PATH).getString();
+ NameVersion moduleNameVersion = SlcJcrUtils
+ .moduleNameVersion(flowPath);
+ ((ProcessThread) Thread.currentThread())
+ .getExecutionModulesManager().start(
+ moduleNameVersion);
+ }
+
+ RealizedFlow realizedFlow = new JcrRealizedFlow(
+ realizedFlowNode);
+ if (realizedFlow != null)
+ realizedFlows.add(realizedFlow);
+ }
+ return realizedFlows;
+ } catch (RepositoryException e) {
+ throw new SlcException("Cannot get realized flows", e);
+ }
+ }
+
+ public String getNodePath() {
+ try {
+ return node.getPath();
+ } catch (RepositoryException e) {
+ throw new SlcException("Cannot get process node path for " + node,
+ e);
+ }
+ }
+
+ public Repository getRepository() {
+ try {
+ return node.getSession().getRepository();
+ } catch (RepositoryException e) {
+ throw new SlcException("Cannot get process JCR repository for "
+ + node, e);
+ }
+ }
+}
--- /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.jcr.execution;
+
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.core.execution.ProcessThread;
+import org.argeo.slc.execution.ExecutionModulesManager;
+import org.argeo.slc.execution.ExecutionProcess;
+import org.argeo.slc.execution.RealizedFlow;
+import org.argeo.slc.jcr.SlcNames;
+
+/** Where the actual execution takes place */
+public class JcrProcessThread extends ProcessThread implements SlcNames {
+
+ public JcrProcessThread(ThreadGroup processesThreadGroup,
+ ExecutionModulesManager executionModulesManager,
+ JcrExecutionProcess process) {
+ super(processesThreadGroup, executionModulesManager, process);
+ }
+
+ /** Overridden in order to set progress status on realized flow nodes. */
+ @Override
+ protected void process() throws InterruptedException {
+ Session session = null;
+ if (getProcess() instanceof JcrExecutionProcess)
+ try {
+ session = ((JcrExecutionProcess) getProcess()).getRepository()
+ .login();
+
+ List<RealizedFlow> realizedFlows = getProcess()
+ .getRealizedFlows();
+ for (RealizedFlow realizedFlow : realizedFlows) {
+ Node realizedFlowNode = session
+ .getNode(((JcrRealizedFlow) realizedFlow).getPath());
+ setFlowStatus(realizedFlowNode, ExecutionProcess.RUNNING);
+
+ try {
+ //
+ // EXECUTE THE FLOW
+ //
+ execute(realizedFlow, true);
+
+ setFlowStatus(realizedFlowNode,
+ ExecutionProcess.COMPLETED);
+ } catch (RepositoryException e) {
+ throw e;
+ } catch (InterruptedException e) {
+ setFlowStatus(realizedFlowNode, ExecutionProcess.KILLED);
+ throw e;
+ } catch (RuntimeException e) {
+ setFlowStatus(realizedFlowNode, ExecutionProcess.ERROR);
+ throw e;
+ }
+ }
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot process "
+ + getJcrExecutionProcess().getNodePath(), e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+ else
+ super.process();
+ }
+
+ protected void setFlowStatus(Node realizedFlowNode, String status)
+ throws RepositoryException {
+ realizedFlowNode.setProperty(SLC_STATUS, status);
+ realizedFlowNode.getSession().save();
+ }
+
+ protected JcrExecutionProcess getJcrExecutionProcess() {
+ return (JcrExecutionProcess) getProcess();
+ }
+}
--- /dev/null
+package org.argeo.slc.jcr.execution;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.DefaultExecutionSpec;
+import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
+import org.argeo.slc.core.execution.PrimitiveUtils;
+import org.argeo.slc.core.execution.RefSpecAttribute;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.argeo.slc.execution.RealizedFlow;
+import org.argeo.slc.jcr.SlcJcrUtils;
+import org.argeo.slc.jcr.SlcNames;
+import org.argeo.slc.jcr.SlcTypes;
+
+public class JcrRealizedFlow extends RealizedFlow implements SlcNames {
+ private static final long serialVersionUID = -3709453850260712001L;
+ private String path;
+
+ public JcrRealizedFlow(Node node) {
+ try {
+ this.path = node.getPath();
+ loadFromNode(node);
+ } catch (RepositoryException e) {
+ throw new SlcException("Cannot initialize from " + node, e);
+ }
+ }
+
+ protected void loadFromNode(Node realizedFlowNode)
+ throws RepositoryException {
+ if (realizedFlowNode.hasNode(SLC_ADDRESS)) {
+ String flowPath = realizedFlowNode.getNode(SLC_ADDRESS)
+ .getProperty(Property.JCR_PATH).getString();
+ // TODO: convert to local path if remote
+ // FIXME start related module
+ Node flowNode = realizedFlowNode.getSession().getNode(flowPath);
+ String flowName = flowNode.getProperty(SLC_NAME).getString();
+ String description = null;
+ if (flowNode.hasProperty(Property.JCR_DESCRIPTION))
+ description = flowNode.getProperty(Property.JCR_DESCRIPTION)
+ .getString();
+
+ Node executionModuleNode = flowNode.getSession().getNode(
+ SlcJcrUtils.modulePath(flowPath));
+ String executionModuleName = executionModuleNode.getProperty(
+ SLC_NAME).getString();
+ String executionModuleVersion = executionModuleNode.getProperty(
+ SLC_VERSION).getString();
+
+ RealizedFlow realizedFlow = this;
+ realizedFlow.setModuleName(executionModuleName);
+ realizedFlow.setModuleVersion(executionModuleVersion);
+
+ // retrieve execution spec
+ DefaultExecutionSpec executionSpec = new DefaultExecutionSpec();
+ Map<String, ExecutionSpecAttribute> attrs = readExecutionSpecAttributes(realizedFlowNode);
+ executionSpec.setAttributes(attrs);
+
+ // set execution spec name
+ if (flowNode.hasProperty(SlcNames.SLC_SPEC)) {
+ Node executionSpecNode = flowNode.getProperty(SLC_SPEC)
+ .getNode();
+ executionSpec.setBeanName(executionSpecNode.getProperty(
+ SLC_NAME).getString());
+ }
+
+ // explicitly retrieve values
+ Map<String, Object> values = new HashMap<String, Object>();
+ for (String attrName : attrs.keySet()) {
+ ExecutionSpecAttribute attr = attrs.get(attrName);
+ Object value = attr.getValue();
+ values.put(attrName, value);
+ }
+
+ ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(flowName,
+ description, values, executionSpec);
+ realizedFlow.setFlowDescriptor(efd);
+ } else {
+ throw new SlcException("Unsupported realized flow "
+ + realizedFlowNode);
+ }
+ }
+
+ protected Map<String, ExecutionSpecAttribute> readExecutionSpecAttributes(
+ Node node) {
+ try {
+ Map<String, ExecutionSpecAttribute> attrs = new HashMap<String, ExecutionSpecAttribute>();
+ for (NodeIterator nit = node.getNodes(); nit.hasNext();) {
+ Node specAttrNode = nit.nextNode();
+ if (specAttrNode
+ .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) {
+ String type = specAttrNode.getProperty(SLC_TYPE)
+ .getString();
+ Object value = null;
+ if (specAttrNode.hasProperty(SLC_VALUE)) {
+ String valueStr = specAttrNode.getProperty(SLC_VALUE)
+ .getString();
+ value = PrimitiveUtils.convert(type, valueStr);
+ }
+ PrimitiveSpecAttribute specAttr = new PrimitiveSpecAttribute(
+ type, value);
+ attrs.put(specAttrNode.getName(), specAttr);
+ } else if (specAttrNode
+ .isNodeType(SlcTypes.SLC_REF_SPEC_ATTRIBUTE)) {
+ if (!specAttrNode.hasProperty(SLC_VALUE)) {
+ continue;
+ }
+ Integer value = (int) specAttrNode.getProperty(SLC_VALUE)
+ .getLong();
+ RefSpecAttribute specAttr = new RefSpecAttribute();
+ NodeIterator children = specAttrNode.getNodes();
+ int index = 0;
+ String id = null;
+ while (children.hasNext()) {
+ Node child = children.nextNode();
+ if (index == value)
+ id = child.getName();
+ index++;
+ }
+ specAttr.setValue(id);
+ attrs.put(specAttrNode.getName(), specAttr);
+ }
+ // throw new SlcException("Unsupported spec attribute "
+ // + specAttrNode);
+ }
+ return attrs;
+ } catch (RepositoryException e) {
+ throw new SlcException("Cannot read spec attributes from " + node,
+ e);
+ }
+ }
+
+ public String getPath() {
+ return path;
+ }
+}
--- /dev/null
+<slc = 'http://www.argeo.org/ns/slc'>
+
+// COMMON
+[slc:nameVersion] > nt:base
+mixin
+- slc:name (STRING) m
+- slc:version (STRING) m
+
+[slc:categorizedNameVersion] > slc:nameVersion
+mixin
+// define as mandatory?
+- slc:category (STRING)
+
+// AGENT
+[slc:agentFactory] > nt:unstructured, mix:title
++ * (slc:agent)
+
+[slc:agent] > nt:unstructured, mix:title
++ * (slc:module)
+
+[slc:module] > slc:nameVersion, mix:title
+mixin
+
+[slc:activableModule] > slc:module
+mixin
+
+[slc:executionModule] > slc:activableModule
+mixin
+
+[slc:executionSpec] > nt:unstructured, mix:referenceable, mix:title
+- slc:name (STRING) m
++ * (slc:executionSpecAttribute) *
+
+[slc:executionSpecAttribute] > nt:base
+mixin abstract
+- slc:isImmutable (BOOLEAN)
+- slc:isConstant (BOOLEAN)
+- slc:isHidden (BOOLEAN)
+
+[slc:primitiveSpecAttribute] > slc:executionSpecAttribute
+mixin
+- slc:type (STRING)
+- slc:value (UNDEFINED)
+
+[slc:refSpecAttribute] > slc:executionSpecAttribute
+orderable
+mixin
+// typically a class name
+- slc:type (STRING)
+- slc:value (UNDEFINED)
++ * (mix:title)
+
+[slc:executionFlow] > nt:unstructured, mix:title
+- slc:name (STRING) ! m
+// if the execution spec is a referenceable node
+- slc:spec (REFERENCE)
+// if the execution spec is internal (without name)
++ * (slc:executionSpecAttribute) *
+
+// PROCESS
+[slc:process] > nt:unstructured, mix:created, mix:lastModified
+orderable
+- slc:uuid (STRING) ! m
+- slc:status (STRING) m
++ slc:flow (slc:realizedFlow)
++ slc:log
+
+// The first part of the relative path is the thread name, rest is location
+[slc:logEntry] > nt:unstructured
+abstract
+- slc:message (STRING) !
+- slc:timestamp (STRING)
+
+// Log levels are set via types.
+// Querying one level also queries the higher levels thanks to the inheritance
+// e.g. 'select * from [slc:logWarn]' also returns errors
+[slc:logTrace] > slc:logEntry
+
+[slc:logDebug] > slc:logTrace
+
+[slc:logInfo] > slc:logDebug
+
+[slc:logWarning] > slc:logInfo
+
+[slc:logError] > slc:logWarning
+
+[slc:realizedFlow] > nt:base
+orderable
+mixin
+// the name of the flow
+// - slc:flow (STRING)
+// the name of the execution spec
+// - slc:spec (STRING)
+- slc:started (DATE)
+- slc:completed (DATE)
+//- slc:status (STRING)
++ slc:address (nt:address)
++ slc:flow (slc:realizedFlow) *
+// the realized execution spec attributes
++ * (slc:executionSpecAttribute) *
+
+// RESULT
+[slc:testResult] > nt:unstructured, mix:created, mix:lastModified
+- slc:uuid (STRING) ! m
+- slc:testCase (STRING)
+- slc:completed (DATE)
+// Helper to keep a centralize place to have testResultStatus
+// when adding more than one result part to a given testResult
++ slc:aggregatedStatus (slc:check)
+// DEPRECATED - FOR COMPATIBILITY - DO NOT USE
++ slc:testStatus (slc:check)
+
+[slc:diffResult] > slc:testResult
++ slc:summary
++ slc:issues
+
+[slc:resultFolder] > nt:unstructured
++ slc:folderStatus (slc:check)
++ * (slc:resultFolder) *
++ * (slc:testResult) *
+
+// base node for user defined and managed result tree
+// simplify UI management
+[slc:myResultRootFolder] > nt:unstructured
++ * (slc:resultFolder) *
++ * (slc:testResult) *
+
+[slc:check] > nt:unstructured
+// true for PASSED, false for FAILED or ERROR
+- slc:success (BOOLEAN) ! m
+- slc:message (STRING)
+// ERROR if set, the check could not be performed because of an unexpected exception
+- slc:errorMessage (STRING)
+// to ease transition with legacy approach
++ * (slc:property) *
+
+[slc:property] > nt:unstructured
+- slc:name (STRING) ! m
+- slc:value (STRING) m
--- /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.osgi;
+
+/** <b>Experimental</b> A structured set of OSGi bundles. */
+public interface BundleRegister {
+ /**
+ * @param pkg
+ * the Java package
+ * @param version
+ * the version, can be only major.minor or null
+ * @return the bundle providing this package or null if none was found
+ */
+ public String bundleProvidingPackage(String pkg, String version);
+}
--- /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.osgi;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEvent;
+import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextListener;
+import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextClosedEvent;
+import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextFailedEvent;
+import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextRefreshedEvent;
+import org.eclipse.gemini.blueprint.util.OsgiBundleUtils;
+import org.eclipse.gemini.blueprint.util.OsgiFilterUtils;
+import org.springframework.util.Assert;
+
+/** Wraps low-level access to a {@link BundleContext} */
+public class BundlesManager implements BundleContextAware, FrameworkListener,
+ InitializingBean, DisposableBean, OsgiBundleApplicationContextListener {
+ private final static Log log = LogFactory.getLog(BundlesManager.class);
+
+ private BundleContext bundleContext;
+
+ private Long defaultTimeout = 60 * 1000l;
+ private Long pollingPeriod = 200l;
+
+ // Refresh sync objects
+ private final Object refreshedPackageSem = new Object();
+ private Boolean packagesRefreshed = false;
+
+ public BundlesManager() {
+ }
+
+ public BundlesManager(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ /**
+ * Stop the module, update it, refresh it and restart it. All synchronously.
+ */
+ public void upgradeSynchronous(OsgiBundle osgiBundle) {
+ try {
+ Bundle bundle = findRelatedBundle(osgiBundle);
+
+ long begin = System.currentTimeMillis();
+
+ long bStop = begin;
+ stopSynchronous(bundle);
+
+ long bUpdate = System.currentTimeMillis();
+ updateSynchronous(bundle);
+
+ // Refresh in case there are fragments
+ long bRefresh = System.currentTimeMillis();
+ refreshSynchronous(bundle);
+
+ long bStart = System.currentTimeMillis();
+ startSynchronous(bundle);
+
+ long aStart = System.currentTimeMillis();
+ if (log.isTraceEnabled()) {
+ log.debug("OSGi upgrade performed in " + (aStart - begin)
+ + "ms for bundle " + osgiBundle);
+ log.debug(" stop \t: " + (bUpdate - bStop) + "ms");
+ log.debug(" update\t: " + (bRefresh - bUpdate) + "ms");
+ log.debug(" refresh\t: " + (bStart - bRefresh) + "ms");
+ log.debug(" start\t: " + (aStart - bStart) + "ms");
+ log.debug(" TOTAL\t: " + (aStart - begin) + "ms");
+ }
+
+ long bAppContext = System.currentTimeMillis();
+ String filter = "(Bundle-SymbolicName=" + bundle.getSymbolicName()
+ + ")";
+ // Wait for application context to be ready
+ // TODO: use service tracker
+ ServiceReference[] srs = getServiceRefSynchronous(
+ ApplicationContext.class.getName(), filter);
+ ServiceReference sr = srs[0];
+ long aAppContext = System.currentTimeMillis();
+ long end = aAppContext;
+
+ if (log.isTraceEnabled()) {
+ log.debug("Application context refresh performed in "
+ + (aAppContext - bAppContext) + "ms for bundle "
+ + osgiBundle);
+ }
+
+ if (log.isDebugEnabled())
+ log.debug("Bundle '" + bundle.getSymbolicName()
+ + "' upgraded and ready " + " (upgrade performed in "
+ + (end - begin) + "ms).");
+
+ if (log.isTraceEnabled()) {
+ ApplicationContext applicationContext = (ApplicationContext) bundleContext
+ .getService(sr);
+ int beanDefCount = applicationContext.getBeanDefinitionCount();
+ log.debug(" " + beanDefCount + " beans in app context of "
+ + bundle.getSymbolicName()
+ + ", average init time per bean=" + (end - begin)
+ / beanDefCount + "ms");
+ }
+
+ bundleContext.ungetService(sr);
+
+ } catch (Exception e) {
+ throw new SlcException("Cannot update bundle " + osgiBundle, e);
+ }
+ }
+
+ /** Updates bundle synchronously. */
+ protected void updateSynchronous(Bundle bundle) throws BundleException {
+ bundle.update();
+ boolean waiting = true;
+
+ long begin = System.currentTimeMillis();
+ do {
+ int state = bundle.getState();
+ if (state == Bundle.INSTALLED || state == Bundle.ACTIVE
+ || state == Bundle.RESOLVED)
+ waiting = false;
+
+ sleepWhenPolling();
+ checkTimeout(begin, "Update of bundle " + bundle.getSymbolicName()
+ + " timed out. Bundle state = " + bundle.getState());
+ } while (waiting);
+
+ if (log.isTraceEnabled())
+ log.debug("Bundle " + bundle.getSymbolicName() + " updated.");
+ }
+
+ /** Starts bundle synchronously. Does nothing if already started. */
+ protected void startSynchronous(Bundle bundle) throws BundleException {
+ int originalState = bundle.getState();
+ if (originalState == Bundle.ACTIVE)
+ return;
+
+ bundle.start();
+ boolean waiting = true;
+
+ long begin = System.currentTimeMillis();
+ do {
+ if (bundle.getState() == Bundle.ACTIVE)
+ waiting = false;
+
+ sleepWhenPolling();
+ checkTimeout(begin, "Start of bundle " + bundle.getSymbolicName()
+ + " timed out. Bundle state = " + bundle.getState());
+ } while (waiting);
+
+ if (log.isTraceEnabled())
+ log.debug("Bundle " + bundle.getSymbolicName() + " started.");
+ }
+
+ /** Stops bundle synchronously. Does nothing if already started. */
+ protected void stopSynchronous(Bundle bundle) throws BundleException {
+ int originalState = bundle.getState();
+ if (originalState != Bundle.ACTIVE)
+ return;
+
+ bundle.stop();
+ boolean waiting = true;
+
+ long begin = System.currentTimeMillis();
+ do {
+ if (bundle.getState() != Bundle.ACTIVE
+ && bundle.getState() != Bundle.STOPPING)
+ waiting = false;
+
+ sleepWhenPolling();
+ checkTimeout(begin, "Stop of bundle " + bundle.getSymbolicName()
+ + " timed out. Bundle state = " + bundle.getState());
+ } while (waiting);
+
+ if (log.isTraceEnabled())
+ log.debug("Bundle " + bundle.getSymbolicName() + " stopped.");
+ }
+
+ /** Refresh bundle synchronously. Does nothing if already started. */
+ protected void refreshSynchronous(Bundle bundle) throws BundleException {
+ ServiceReference packageAdminRef = bundleContext
+ .getServiceReference(PackageAdmin.class.getName());
+ PackageAdmin packageAdmin = (PackageAdmin) bundleContext
+ .getService(packageAdminRef);
+ Bundle[] bundles = { bundle };
+
+ long begin = System.currentTimeMillis();
+ synchronized (refreshedPackageSem) {
+ packagesRefreshed = false;
+ packageAdmin.refreshPackages(bundles);
+ try {
+ refreshedPackageSem.wait(defaultTimeout);
+ } catch (InterruptedException e) {
+ // silent
+ }
+ if (!packagesRefreshed) {
+ long now = System.currentTimeMillis();
+ throw new SlcException("Packages not refreshed after "
+ + (now - begin) + "ms");
+ } else {
+ packagesRefreshed = false;
+ }
+ }
+
+ if (log.isTraceEnabled())
+ log.debug("Bundle " + bundle.getSymbolicName() + " refreshed.");
+ }
+
+ public void frameworkEvent(FrameworkEvent event) {
+ if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
+ synchronized (refreshedPackageSem) {
+ packagesRefreshed = true;
+ refreshedPackageSem.notifyAll();
+ }
+ }
+ }
+
+ public ServiceReference[] getServiceRefSynchronous(String clss,
+ String filter) throws InvalidSyntaxException {
+ if (log.isTraceEnabled())
+ log.debug("Filter: '" + filter + "'");
+ ServiceReference[] sfs = null;
+ boolean waiting = true;
+ long begin = System.currentTimeMillis();
+ do {
+ sfs = bundleContext.getServiceReferences(clss, filter);
+
+ if (sfs != null)
+ waiting = false;
+
+ sleepWhenPolling();
+ checkTimeout(begin, "Search of services " + clss + " with filter "
+ + filter + " timed out.");
+ } while (waiting);
+
+ return sfs;
+ }
+
+ protected void checkTimeout(long begin, String msg) {
+ long now = System.currentTimeMillis();
+ if (now - begin > defaultTimeout)
+ throw new SlcException(msg + " (timeout after " + (now - begin)
+ + "ms)");
+
+ }
+
+ protected void sleepWhenPolling() {
+ try {
+ Thread.sleep(pollingPeriod);
+ } catch (InterruptedException e) {
+ throw new SlcException("Polling interrupted");
+ }
+ }
+
+ /** Creates and open a new service tracker. */
+ public ServiceTracker newTracker(Class<?> clss) {
+ ServiceTracker st = new ServiceTracker(bundleContext, clss.getName(),
+ null);
+ st.open();
+ return st;
+ }
+
+ @SuppressWarnings(value = { "unchecked" })
+ public <T> T getSingleService(Class<T> clss, String filter,
+ Boolean synchronous) {
+ if (filter != null)
+ Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter");
+ ServiceReference[] sfs;
+ try {
+ if (synchronous)
+ sfs = getServiceRefSynchronous(clss.getName(), filter);
+ else
+ sfs = bundleContext
+ .getServiceReferences(clss.getName(), filter);
+ } catch (InvalidSyntaxException e) {
+ throw new SlcException("Cannot retrieve service reference for "
+ + filter, e);
+ }
+
+ if (sfs == null || sfs.length == 0)
+ return null;
+ else if (sfs.length > 1)
+ throw new SlcException("More than one execution flow found for "
+ + filter);
+ return (T) bundleContext.getService(sfs[0]);
+ }
+
+ public <T> T getSingleServiceStrict(Class<T> clss, String filter,
+ Boolean synchronous) {
+ T service = getSingleService(clss, filter, synchronous);
+ if (service == null)
+ throw new SlcException("No execution flow found for " + filter);
+ else
+ return service;
+ }
+
+ public OsgiBundle findRelatedBundle(String moduleName, String moduleVersion) {
+ OsgiBundle osgiBundle = new OsgiBundle(moduleName, moduleVersion);
+ if (osgiBundle.getVersion() == null) {
+ Bundle bundle = findRelatedBundle(osgiBundle);
+ osgiBundle = new OsgiBundle(bundle);
+ }
+ return osgiBundle;
+ }
+
+ /**
+ * @param osgiBundle
+ * cannot be null
+ * @return the related bundle or null if not found
+ * @throws SlcException
+ * if osgiBundle argument is null
+ */
+ public Bundle findRelatedBundle(OsgiBundle osgiBundle) {
+ if (osgiBundle == null)
+ throw new SlcException("OSGi bundle cannot be null");
+
+ Bundle bundle = null;
+ if (osgiBundle.getInternalBundleId() != null) {
+ bundle = bundleContext.getBundle(osgiBundle.getInternalBundleId());
+ Assert.isTrue(
+ osgiBundle.getName().equals(bundle.getSymbolicName()),
+ "symbolic name consistent");
+ if (osgiBundle.getVersion() != null)
+ Assert.isTrue(
+ osgiBundle.getVersion().equals(
+ bundle.getHeaders().get(
+ Constants.BUNDLE_VERSION)),
+ "version consistent");
+ } else if (osgiBundle.getVersion() == null
+ || osgiBundle.getVersion().equals("0.0.0")) {
+ bundle = OsgiBundleUtils.findBundleBySymbolicName(bundleContext,
+ osgiBundle.getName());
+ } else {// scan all bundles
+ bundles: for (Bundle b : bundleContext.getBundles()) {
+ if (b.getSymbolicName() == null) {
+ log.warn("Bundle " + b + " has no symbolic name defined.");
+ continue bundles;
+ }
+
+ if (b.getSymbolicName().equals(osgiBundle.getName())) {
+ if (osgiBundle.getVersion() == null) {
+ bundle = b;
+ break bundles;
+ }
+
+ if (b.getHeaders().get(Constants.BUNDLE_VERSION)
+ .equals(osgiBundle.getVersion())) {
+ bundle = b;
+ osgiBundle.setInternalBundleId(b.getBundleId());
+ break bundles;
+ }
+ }
+ }
+ }
+ return bundle;
+ }
+
+ /** Find a single bundle based on a symbolic name pattern. */
+ public OsgiBundle findFromPattern(String pattern) {
+ OsgiBundle osgiBundle = null;
+ for (Bundle b : bundleContext.getBundles()) {
+ if (b.getSymbolicName().contains(pattern)) {
+ osgiBundle = new OsgiBundle(b);
+ break;
+ }
+ }
+ return osgiBundle;
+ }
+
+ public OsgiBundle getBundle(Long bundleId) {
+ Bundle bundle = bundleContext.getBundle(bundleId);
+ return new OsgiBundle(bundle);
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ bundleContext.addFrameworkListener(this);
+ }
+
+ public void destroy() throws Exception {
+ bundleContext.removeFrameworkListener(this);
+ }
+
+ public void setDefaultTimeout(Long defaultTimeout) {
+ this.defaultTimeout = defaultTimeout;
+ }
+
+ /**
+ * Use with caution since it may interfer with some cached information
+ * within this object
+ */
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public void setPollingPeriod(Long pollingPeriod) {
+ this.pollingPeriod = pollingPeriod;
+ }
+
+ public void onOsgiApplicationEvent(OsgiBundleApplicationContextEvent event) {
+ if (event instanceof OsgiBundleContextRefreshedEvent) {
+ log.debug("App context refreshed: " + event);
+ } else if (event instanceof OsgiBundleContextFailedEvent) {
+ log.debug("App context failed: " + event);
+ }
+ if (event instanceof OsgiBundleContextClosedEvent) {
+ log.debug("App context closed: " + event);
+ }
+
+ }
+
+}
--- /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.osgi;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.Constants;
+
+/** <b>Experimental</b> */
+public class FileSystemBundleRegister implements BundleRegister {
+ private final static Log log = LogFactory
+ .getLog(FileSystemBundleRegister.class);
+ private Properties packagesBundles = null;
+
+ public String bundleProvidingPackage(String pkg, String version) {
+ if (packagesBundles == null)
+ return null;
+ return packagesBundles.getProperty(pkg);
+ }
+
+ protected void scan(File baseDirectory) {
+ long begin = System.currentTimeMillis();
+ int bundleCount = 0;
+ int packageCount = 0;
+
+ packagesBundles = new Properties();
+
+ File[] files = baseDirectory.listFiles();
+ for (File file : files) {
+ if (file.isDirectory()) {
+
+ } else {
+ try {
+ JarFile jarFile = new JarFile(file);
+ Manifest manifest = jarFile.getManifest();
+ String symbolicName = manifest.getMainAttributes()
+ .getValue(Constants.BUNDLE_SYMBOLICNAME);
+ String exportPackage = manifest.getMainAttributes()
+ .getValue(Constants.EXPORT_PACKAGE);
+
+ // List exported packages
+ Set<String> exportedPackages = exportPackageToPackageNames(exportPackage);
+
+ for (String exportedPackage : exportedPackages) {
+ packagesBundles.put(exportedPackage, symbolicName);
+ packageCount++;
+ if (log.isTraceEnabled())
+ log.trace("Register " + exportedPackage + "="
+ + symbolicName);
+ }
+ bundleCount++;
+ } catch (Exception e) {
+ log.warn("Cannot scan " + file, e);
+ if (log.isTraceEnabled())
+ e.printStackTrace();
+ }
+ }
+ }
+ if (log.isDebugEnabled())
+ log.debug("Scanned " + bundleCount + " bundles with "
+ + packageCount + " packages in "
+ + (System.currentTimeMillis() - begin) + " ms");
+ }
+
+ protected Set<String> exportPackageToPackageNames(String exportPackage) {
+ Set<String> exportedPackages = new HashSet<String>();
+ if (exportPackage == null)
+ return exportedPackages;
+ char[] arr = exportPackage.toCharArray();
+
+ StringBuffer currentPkg = new StringBuffer("");
+ boolean skip = false;
+ boolean inQuote = false;
+ for (char c : arr) {
+ if (c == ' ' || c == '\n') {
+ // ignore
+ } else if (c == ';') {
+ if (!skip)
+ skip = true;
+ } else if (c == ',') {
+ if (skip && !inQuote) {
+ skip = false;
+ // add new package
+ exportedPackages.add(currentPkg.toString());
+ currentPkg = new StringBuffer("");
+ }
+ } else if (c == '\"') {
+ inQuote = inQuote ? false : true;
+ } else {
+ if (!skip)
+ currentPkg.append(c);
+ }
+ }
+
+ return exportedPackages;
+ }
+
+ public static void main(String[] args) {
+ FileSystemBundleRegister fsbr = new FileSystemBundleRegister();
+ fsbr.scan(new File(
+ "/home/mbaudier/dev/src/slc/dist/org.argeo.slc.sdk/target/lib"));
+
+ }
+}
--- /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.osgi;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.core.Ordered;
+
+/** Publishes beans of the application context as OSGi services. */
+@SuppressWarnings(value = { "unchecked", "rawtypes" })
+public class MultipleServiceExporterPostProcessor implements
+ ApplicationListener, Ordered {
+ private final static Log log = LogFactory
+ .getLog(MultipleServiceExporterPostProcessor.class);
+
+ private List<Class> interfaces = new ArrayList<Class>();
+
+ private int order = Ordered.LOWEST_PRECEDENCE;
+
+ private BundleContext bundleContext = null;
+
+ // private Class osgiServiceFactoryClass = OsgiServiceFactoryBean.class;
+ // private Boolean useServiceProviderContextClassLoader = false;
+
+ public void onApplicationEvent(ApplicationEvent event) {
+ Map<String, Object> beans = new HashMap<String, Object>();
+ if (event instanceof ContextRefreshedEvent) {
+ if (bundleContext != null) {
+ for (Class clss : interfaces) {
+ ApplicationContext ac = ((ContextRefreshedEvent) event)
+ .getApplicationContext();
+ beans.putAll(ac.getBeansOfType(clss, false, false));
+ }
+
+ int count = 0;
+ for (String beanName : beans.keySet()) {
+ Object bean = beans.get(beanName);
+ List<String> classes = new ArrayList<String>();
+ for (Class clss : interfaces) {
+ if (clss.isAssignableFrom(bean.getClass())) {
+ classes.add(clss.getName());
+ }
+ }
+ Properties props = new Properties();
+ Bundle bundle = bundleContext.getBundle();
+ props.put(Constants.BUNDLE_SYMBOLICNAME,
+ bundle.getSymbolicName());
+ props.put(Constants.BUNDLE_VERSION, bundle.getVersion());
+ // retrocompatibility with pre-1.0:
+ props.put("org.eclipse.gemini.blueprint.bean.name", beanName);
+ bundleContext.registerService(
+ classes.toArray(new String[classes.size()]), bean,
+ new Hashtable(props));
+ count++;
+ }
+ if (log.isTraceEnabled())
+ log.trace("Published " + count + " " + interfaces
+ + " as OSGi services from bundle "
+ + bundleContext.getBundle().getSymbolicName() + " "
+ + bundleContext.getBundle().getVersion());
+ // note: the services will be automatically unregistered when
+ // the bundle will be stopped
+ }
+ }
+ }
+
+ // public void postProcessBeanFactory(
+ // ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ // if (!(beanFactory instanceof BeanDefinitionRegistry)) {
+ // throw new SlcException("Can only work on "
+ // + BeanDefinitionRegistry.class);
+ // }
+ //
+ // long begin = System.currentTimeMillis();
+ //
+ // // Merge all beans implementing these interfaces
+ // Set<String> beanNames = new HashSet<String>();
+ // for (Class clss : interfaces) {
+ // String[] strs = beanFactory.getBeanNamesForType(clss, true, false);
+ // beanNames.addAll(Arrays.asList(strs));
+ // }
+ //
+ // // Register service factory beans for them
+ // for (String beanName : beanNames) {
+ // MutablePropertyValues mpv = new MutablePropertyValues();
+ // mpv.addPropertyValue("interfaces", interfaces.toArray());
+ // mpv.addPropertyValue("targetBeanName", beanName);
+ // if (useServiceProviderContextClassLoader)
+ // mpv.addPropertyValue("contextClassLoader",
+ // ExportContextClassLoader.SERVICE_PROVIDER);
+ // RootBeanDefinition bd = new RootBeanDefinition(
+ // osgiServiceFactoryClass, mpv);
+ //
+ // String exporterBeanName = "osgiService." + beanName;
+ // if (log.isTraceEnabled())
+ // log.debug("Registering OSGi service exporter "
+ // + exporterBeanName);
+ // ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(
+ // exporterBeanName, bd);
+ // }
+ //
+ // long end = System.currentTimeMillis();
+ // if (log.isTraceEnabled())
+ // log.debug("Multiple services exported in " + (end - begin)
+ // + " ms in bundle.");
+ //
+ // }
+
+ public void setInterfaces(List<Class> interfaces) {
+ this.interfaces = interfaces;
+ }
+
+ // public void setOsgiServiceFactoryClass(Class osgiServiceFactoryClass) {
+ // this.osgiServiceFactoryClass = osgiServiceFactoryClass;
+ // }
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int order) {
+ this.order = order;
+ }
+
+ // public void setUseServiceProviderContextClassLoader(
+ // Boolean useServiceProviderContextClassLoader) {
+ // this.useServiceProviderContextClassLoader =
+ // useServiceProviderContextClassLoader;
+ // }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+}
--- /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.osgi;
+
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.core.build.ResourceDistribution;
+import org.argeo.slc.deploy.DeploymentData;
+import org.argeo.slc.deploy.Module;
+import org.argeo.slc.deploy.ModuleDescriptor;
+import org.argeo.slc.deploy.TargetData;
+import org.argeo.slc.execution.RealizedFlow;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.springframework.core.io.Resource;
+
+/** A deployed OSGi bundle. */
+public class OsgiBundle extends DefaultNameVersion implements Module {
+ private ResourceDistribution distribution;
+
+ private Long internalBundleId;
+
+ private String title;
+ private String description;
+
+ public OsgiBundle() {
+
+ }
+
+ public OsgiBundle(String name, String version) {
+ super(name, version);
+ }
+
+ public OsgiBundle(NameVersion nameVersion) {
+ super(nameVersion);
+ }
+
+ public OsgiBundle(Bundle bundle) {
+ super(bundle.getSymbolicName(), getVersionSafe(bundle));
+ internalBundleId = bundle.getBundleId();
+ }
+
+ /**
+ * Initialize from a {@link RealizedFlow}.
+ *
+ * @deprecated introduce an unnecessary dependency. TODO: create a separate
+ * helper.
+ */
+ public OsgiBundle(RealizedFlow realizedFlow) {
+ super(realizedFlow.getModuleName(), realizedFlow.getModuleVersion());
+ }
+
+ /** Utility to avoid NPE. */
+ private static String getVersionSafe(Bundle bundle) {
+ Object versionObj = bundle.getHeaders().get(Constants.BUNDLE_VERSION);
+ if (versionObj != null)
+ return versionObj.toString();
+ else
+ return null;
+ }
+
+ /** Unique deployed system id. TODO: use internal bundle id when available? */
+ public String getDeployedSystemId() {
+ return getName() + ":" + getVersion();
+ }
+
+ /**
+ * OSGi bundle are self-contained and do not require additional deployment
+ * data.
+ *
+ * @return always null
+ */
+ public DeploymentData getDeploymentData() {
+ return null;
+ }
+
+ /** The related distribution. */
+ public Distribution getDistribution() {
+ return distribution;
+ }
+
+ /**
+ * The related distribution, a jar file with OSGi metadata referenced by a
+ * {@link Resource}.
+ */
+ public ResourceDistribution getResourceDistribution() {
+ return distribution;
+ }
+
+ /** TODO: reference the {@link OsgiRuntime} as target data? */
+ public TargetData getTargetData() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setResourceDistribution(ResourceDistribution distribution) {
+ this.distribution = distribution;
+ }
+
+ /**
+ * Bundle ID used by the OSGi runtime. To be used for optimization when
+ * looking in the bundle context. Can therefore be null.
+ */
+ public Long getInternalBundleId() {
+ return internalBundleId;
+ }
+
+ /** Only package access for the time being. e.g. from {@link BundlesManager} */
+ void setInternalBundleId(Long internalBundleId) {
+ this.internalBundleId = internalBundleId;
+ }
+
+ /** Value of the <code>Bundle-Name</code> directive. */
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String label) {
+ this.title = label;
+ }
+
+ /** Value of the <code>Bundle-Description</code> directive. */
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public ModuleDescriptor getModuleDescriptor() {
+ ModuleDescriptor moduleDescriptor = new ModuleDescriptor();
+ moduleDescriptor.setName(getName());
+ moduleDescriptor.setVersion(getVersion());
+ moduleDescriptor.setDescription(description);
+ moduleDescriptor.setTitle(title);
+ return moduleDescriptor;
+ }
+}
--- /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.osgi;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.core.execution.AbstractSpringExecutionModule;
+import org.argeo.slc.execution.ExecutionContext;
+
+@Deprecated
+public class OsgiExecutionModule extends AbstractSpringExecutionModule {
+ private final static Log log = LogFactory.getLog(OsgiExecutionModule.class);
+
+ public OsgiExecutionModule() {
+ log.error("######## ERROR - DEPRECATED APPROACH USED ########");
+ log.error(OsgiExecutionModule.class.getName() + " is deprecated. ");
+ log
+ .error("It will be removed in the next release. Remove its bean definition.");
+ log
+ .error("And replace: <service interface=\"org.argeo.slc.execution.ExecutionModule\" ref=\"executionModule\" />");
+ log
+ .error("by: <beans:import resource=\"classpath:org/argeo/slc/osgi/execution/spring.xml\" /> ");
+ log.error("in osgi.xml.\n\n");
+ }
+
+ public void setExecutionContext(ExecutionContext executionContext) {
+ // do nothing, just for compatibility
+ }
+
+ /*
+ * private BundleContext bundleContext;
+ *
+ * @Override public void execute(ExecutionFlowDescriptor
+ * executionFlowDescriptor) { if (descriptorConverter != null)
+ * executionContext.addVariables(descriptorConverter
+ * .convertValues(executionFlowDescriptor));
+ *
+ * ExecutionFlow flow = findExecutionFlow(getName(), getVersion(),
+ * executionFlowDescriptor.getName()); flow.run(); }
+ *
+ * @Override protected Map<String, ExecutionFlow> listFlows() { String
+ * filter = "(org.argeo.slc.execution.module.name=" + getName() + ")";
+ * ServiceReference[] sfs; try { sfs =
+ * bundleContext.getServiceReferences(ExecutionFlow.class .getName(),
+ * filter); } catch (InvalidSyntaxException e) { throw new SlcException(
+ * "Cannot retrieve service reference for flow " + filter, e); }
+ *
+ * Map<String, ExecutionFlow> flows = new HashMap<String, ExecutionFlow>();
+ * for (ServiceReference sf : sfs) { ExecutionFlow flow = (ExecutionFlow)
+ * bundleContext.getService(sf); flows.put(flow.getName(), flow); } return
+ * flows; }
+ *
+ * public String getName() { return
+ * bundleContext.getBundle().getSymbolicName(); }
+ *
+ * public String getVersion() { return
+ * bundleContext.getBundle().getHeaders().get("Bundle-Version") .toString();
+ * }
+ *
+ * public void setBundleContext(BundleContext bundleContext) {
+ * this.bundleContext = bundleContext; }
+ *
+ * protected ExecutionFlow findExecutionFlow(String moduleName, String
+ * moduleVersion, String flowName) { String filter =
+ * "(&(org.argeo.slc.execution.module.name=" + moduleName +
+ * ")(org.argeo.slc.execution.flow.name=" + flowName + "))";
+ * log.debug("OSGi filter: " + filter);
+ *
+ * Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter");
+ * ServiceReference[] sfs; try { sfs =
+ * bundleContext.getServiceReferences(ExecutionFlow.class .getName(),
+ * filter); } catch (InvalidSyntaxException e) { throw new
+ * SlcException("Cannot retrieve service reference for " + filter, e); }
+ *
+ * if (sfs == null || sfs.length == 0) throw new
+ * SlcException("No execution flow found for " + filter); else if
+ * (sfs.length > 1) throw new
+ * SlcException("More than one execution flow found for " + filter); return
+ * (ExecutionFlow) bundleContext.getService(sfs[0]); }
+ */
+
+}
--- /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.osgi;
+
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.StandardMBean;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.AbstractExecutionModulesManager;
+import org.argeo.slc.core.execution.DefaultExecutionFlowDescriptorConverter;
+import org.argeo.slc.deploy.Module;
+import org.argeo.slc.deploy.ModuleDescriptor;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
+import org.argeo.slc.execution.ExecutionModulesListener;
+import org.argeo.slc.execution.RealizedFlow;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Constants;
+import org.osgi.framework.launch.Framework;
+import org.springframework.context.ApplicationContext;
+import org.eclipse.gemini.blueprint.service.importer.OsgiServiceLifecycleListener;
+
+/** Execution modules manager implementation based on an OSGi runtime. */
+public class OsgiExecutionModulesManager extends
+ AbstractExecutionModulesManager implements
+ OsgiServiceLifecycleListener, BundleListener {
+
+ private final static Log log = LogFactory
+ .getLog(OsgiExecutionModulesManager.class);
+
+ private BundlesManager bundlesManager;
+ private Map<OsgiBundle, ExecutionContext> executionContexts = new HashMap<OsgiBundle, ExecutionContext>();
+ private Map<OsgiBundle, ExecutionFlowDescriptorConverter> executionFlowDescriptorConverters = new HashMap<OsgiBundle, ExecutionFlowDescriptorConverter>();
+ private Map<OsgiBundle, Set<ExecutionFlow>> executionFlows = new HashMap<OsgiBundle, Set<ExecutionFlow>>();
+ private ExecutionFlowDescriptorConverter defaultDescriptorConverter = new DefaultExecutionFlowDescriptorConverter();
+
+ private List<ExecutionModulesListener> executionModulesListeners = new ArrayList<ExecutionModulesListener>();
+
+ private Boolean registerFlowsToJmx = false;
+
+ public void init() throws Exception {
+ bundlesManager.getBundleContext().addBundleListener(this);
+
+ final String module = System.getProperty(UNIQUE_LAUNCH_MODULE_PROPERTY);
+ final String flow = System.getProperty(UNIQUE_LAUNCH_FLOW_PROPERTY);
+ if (module != null) {
+ // launch a flow and stops
+ new Thread("Unique Flow") {
+ @Override
+ public void run() {
+ executeFlowAndExit(module, null, flow);
+ }
+ }.start();
+ }
+ }
+
+ public void destroy() {
+ bundlesManager.getBundleContext().removeBundleListener(this);
+ }
+
+ /** Executes a single flow and <b>stops the JVM</b> */
+ protected void executeFlowAndExit(final String module,
+ final String version, final String flow) {
+ if (log.isDebugEnabled())
+ log.debug("Launch unique flow " + flow + " from module " + module);
+ try {
+ OsgiBundle osgiBundle = bundlesManager.findFromPattern(module);
+ if (osgiBundle == null)
+ throw new SlcException("No OSGi bundle found for " + module);
+ // Bundle moduleBundle =
+ // bundlesManager.findRelatedBundle(osgiBundle);
+ start(osgiBundle);
+
+ RealizedFlow lastLaunch = findRealizedFlow(module, flow);
+ if (lastLaunch == null)
+ throw new SlcException("Cannot find launch for " + module + " "
+ + flow);
+ execute(lastLaunch);
+ } catch (Exception e) {
+ log.error(
+ "Error in unique flow " + flow + " from module " + module,
+ e);
+ } finally {
+ if (log.isDebugEnabled())
+ log.debug("Shutdown OSGi runtime...");
+ Framework framework = (Framework) bundlesManager.getBundleContext()
+ .getBundle(0);
+ try {
+ // shutdown framework
+ framework.stop();
+ // wait 1 min for shutdown
+ framework.waitForStop(60 * 1000);
+ // close VM
+ System.exit(0);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+ }
+
+ // public void startExectionModule(String moduleName, String moduleVersion)
+ // {
+ // try {
+ // ServiceReference[] sr = bundlesManager.getServiceRefSynchronous(
+ // ApplicationContext.class.getName(),
+ // "org.springframework.context.service.name=" + moduleName);
+ // // bundlesManager.startSynchronous(moduleBundle);
+ // if (sr == null || sr.length == 0)
+ // throw new SlcException(
+ // "Cannot find execution module application context "
+ // + moduleName);
+ // } catch (InvalidSyntaxException e) {
+ // throw new SlcException("Cannot start exeuction module "
+ // + moduleName, e);
+ // }
+ // }
+
+ public synchronized ExecutionModuleDescriptor getExecutionModuleDescriptor(
+ String moduleName, String version) {
+ ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
+ OsgiBundle osgiBundle = null;
+ DefaultNameVersion nameVersion = new DefaultNameVersion(moduleName,
+ version);
+ bundles: for (Iterator<OsgiBundle> iterator = executionContexts
+ .keySet().iterator(); iterator.hasNext();) {
+ OsgiBundle ob = iterator.next();
+ if (nameVersion.getVersion() != null) {
+ if (ob.equals(nameVersion)) {
+ osgiBundle = ob;
+ break bundles;
+ }
+ } else {
+ if (ob.getName().equals(nameVersion.getName())) {
+ osgiBundle = ob;
+ break bundles;
+ }
+ }
+ }
+ if (osgiBundle == null)
+ throw new SlcException("No execution module registered for "
+ + nameVersion);
+ md.setName(osgiBundle.getName());
+ md.setVersion(osgiBundle.getVersion());
+ md.setTitle(osgiBundle.getTitle());
+ md.setDescription(osgiBundle.getDescription());
+
+ ExecutionFlowDescriptorConverter executionFlowDescriptorConverter = getExecutionFlowDescriptorConverter(
+ moduleName, version);
+ if (executionFlowDescriptorConverter == null)
+ throw new SlcException("No flow converter found.");
+ executionFlowDescriptorConverter.addFlowsToDescriptor(md,
+ listFlows(moduleName, version));
+ return md;
+ }
+
+ public synchronized List<ExecutionModuleDescriptor> listExecutionModules() {
+ List<ExecutionModuleDescriptor> descriptors = new ArrayList<ExecutionModuleDescriptor>();
+
+ for (Iterator<OsgiBundle> iterator = executionContexts.keySet()
+ .iterator(); iterator.hasNext();) {
+ OsgiBundle osgiBundle = iterator.next();
+ ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
+ setMetadataFromBundle(md,
+ bundlesManager.findRelatedBundle(osgiBundle));
+ descriptors.add(md);
+ }
+ return descriptors;
+ }
+
+ protected synchronized Map<String, ExecutionFlow> listFlows(
+ String moduleName, String moduleVersion) {
+
+ Map<String, ExecutionFlow> flows = new HashMap<String, ExecutionFlow>();
+ OsgiBundle key = bundlesManager.findRelatedBundle(moduleName,
+ moduleVersion);
+ if (!executionFlows.containsKey(key))
+ return flows;
+ Set<ExecutionFlow> flowsT = executionFlows.get(key);
+ for (ExecutionFlow flow : flowsT)
+ flows.put(flow.getName(), flow);
+ return flows;
+ }
+
+ protected ExecutionFlow findExecutionFlow(String moduleName,
+ String moduleVersion, String flowName) {
+ String filter = moduleVersion == null || moduleVersion.equals("0.0.0") ? "(&(Bundle-SymbolicName="
+ + moduleName
+ + ")(org.eclipse.gemini.blueprint.bean.name="
+ + flowName + "))"
+ : "(&(Bundle-SymbolicName=" + moduleName + ")(Bundle-Version="
+ + moduleVersion
+ + ")(org.eclipse.gemini.blueprint.bean.name=" + flowName
+ + "))";
+ return bundlesManager.getSingleServiceStrict(ExecutionFlow.class,
+ filter, true);
+ }
+
+ protected ExecutionContext findExecutionContext(String moduleName,
+ String moduleVersion) {
+ String filter = moduleFilter(moduleName, moduleVersion);
+ return bundlesManager.getSingleServiceStrict(ExecutionContext.class,
+ filter, true);
+ }
+
+ protected ExecutionFlowDescriptorConverter findExecutionFlowDescriptorConverter(
+ String moduleName, String moduleVersion) {
+ String filter = moduleFilter(moduleName, moduleVersion);
+ return bundlesManager.getSingleService(
+ ExecutionFlowDescriptorConverter.class, filter, false);
+ }
+
+ /** Only based on symbolic name if version is null or "0.0.0" */
+ protected String moduleFilter(String moduleName, String moduleVersion) {
+ return moduleVersion == null || moduleVersion.equals("0.0.0") ? "(Bundle-SymbolicName="
+ + moduleName + ")"
+ : "(&(Bundle-SymbolicName=" + moduleName + ")(Bundle-Version="
+ + moduleVersion + "))";
+
+ }
+
+ /**
+ * Builds a minimal realized flow, based on the provided information
+ * (typically from the command line).
+ *
+ * @param module
+ * a bundle id, or a pattern contained in a bundle symbolic name
+ * @param module
+ * the execution flow name
+ * @return a minimal realized flow, to be used in an execution
+ */
+ public RealizedFlow findRealizedFlow(String module, String executionName) {
+ // First check whether we have a bundleId
+ Long bundleId = null;
+ try {
+ bundleId = Long.parseLong(module);
+ } catch (NumberFormatException e) {
+ // silent
+ }
+
+ // Look for bundle names containing pattern
+ OsgiBundle bundle = null;
+ if (bundleId != null) {
+ bundle = bundlesManager.getBundle(bundleId);
+ } else {
+ bundle = bundlesManager.findFromPattern(module);
+ }
+
+ if (bundle != null) {
+ RealizedFlow launch = new RealizedFlow();
+ launch.setModuleName(bundle.getName());
+ launch.setModuleVersion(bundle.getVersion());
+ ExecutionFlowDescriptor descriptor = new ExecutionFlowDescriptor();
+ descriptor.setName(executionName);
+ launch.setFlowDescriptor(descriptor);
+ return launch;
+ } else {
+ log.warn("Could not find any execution module matching these requirements.");
+ return null;
+ }
+ }
+
+ public void upgrade(NameVersion nameVersion) {
+ OsgiBundle osgiBundle = new OsgiBundle(nameVersion);
+ bundlesManager.upgradeSynchronous(osgiBundle);
+ }
+
+ protected synchronized ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
+ String moduleName, String moduleVersion) {
+ return findExecutionFlowDescriptorConverter(moduleName, moduleVersion);
+ // OsgiBundle osgiBundle = new OsgiBundle(moduleName, moduleVersion);
+ // return getExecutionFlowDescriptorConverter(osgiBundle);
+ }
+
+ protected synchronized ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
+ OsgiBundle osgiBundle) {
+ if (executionFlowDescriptorConverters.containsKey(osgiBundle))
+ return executionFlowDescriptorConverters.get(osgiBundle);
+ else
+ return defaultDescriptorConverter;
+ }
+
+ public ModuleDescriptor getModuleDescriptor(String moduleName,
+ String version) {
+ return getExecutionModuleDescriptor(moduleName, version);
+ }
+
+ public List<ModuleDescriptor> listModules() {
+ Bundle[] bundles = bundlesManager.getBundleContext().getBundles();
+ List<ModuleDescriptor> lst = new ArrayList<ModuleDescriptor>();
+ for (Bundle bundle : bundles) {
+ ModuleDescriptor moduleDescriptor = new ModuleDescriptor();
+ setMetadataFromBundle(moduleDescriptor, bundle);
+ lst.add(moduleDescriptor);
+ }
+ return lst;
+ }
+
+ public void start(NameVersion nameVersion) {
+ try {
+ Bundle bundle = bundlesManager.findRelatedBundle(new OsgiBundle(
+ nameVersion));
+ if (bundle == null)
+ throw new SlcException("Could not find bundle for "
+ + nameVersion);
+
+ bundlesManager.startSynchronous(bundle);
+ if (isSpringInstrumented(bundle)) {
+ // Wait for Spring application context to be ready
+ String filter = "(Bundle-SymbolicName="
+ + bundle.getSymbolicName() + ")";
+ try {
+ bundlesManager.getServiceRefSynchronous(
+ ApplicationContext.class.getName(), filter);
+ } catch (Exception e) {
+ // stop if application context not found
+ bundle.stop();
+ throw e;
+ }
+ }
+ } catch (Exception e) {
+ throw new SlcException("Cannot start " + nameVersion, e);
+ }
+ }
+
+ /** Do it calmly in order to avoid NPE */
+ private Boolean isSpringInstrumented(Bundle bundle) {
+ Dictionary<?, ?> headers = bundle.getHeaders();
+ if (headers != null && headers.get("Spring-Context") != null)
+ return true;
+ Enumeration<?> springEntryPaths = bundle
+ .getEntryPaths("/META-INF/spring");
+ if (springEntryPaths != null && springEntryPaths.hasMoreElements())
+ return true;
+ return false;
+ }
+
+ public void stop(NameVersion nameVersion) {
+ try {
+ Bundle bundle = bundlesManager.findRelatedBundle(new OsgiBundle(
+ nameVersion));
+ bundlesManager.stopSynchronous(bundle);
+ } catch (BundleException e) {
+ throw new SlcException("Cannot stop " + nameVersion, e);
+ }
+ }
+
+ protected void setMetadataFromBundle(ModuleDescriptor md, Bundle bundle) {
+ Bundle bdl = bundle;
+ if (bdl == null) {
+ if (md.getName() == null || md.getVersion() == null)
+ throw new SlcException("Name and version not available.");
+
+ Bundle[] bundles = bundlesManager.getBundleContext().getBundles();
+ for (Bundle b : bundles) {
+ if (b.getSymbolicName().equals(md.getName())
+ && md.getVersion().equals(
+ getHeaderSafe(b, Constants.BUNDLE_VERSION))) {
+ bdl = b;
+ break;
+ }
+ }
+
+ }
+
+ if (bdl == null)
+ throw new SlcException("Cannot find bundle.");
+
+ md.setName(bdl.getSymbolicName());
+ md.setVersion(getHeaderSafe(bdl, Constants.BUNDLE_VERSION));
+ md.setTitle(getHeaderSafe(bdl, Constants.BUNDLE_NAME));
+ md.setDescription(getHeaderSafe(bdl, Constants.BUNDLE_DESCRIPTION));
+
+ // copy manifets header to meta data
+ Dictionary<?, ?> headers = bundle.getHeaders();
+ Enumeration<?> keys = headers.keys();
+ while (keys.hasMoreElements()) {
+ Object key = keys.nextElement();
+ Object value = headers.get(key);
+ if (value != null)
+ md.getMetadata().put(key.toString(), value.toString());
+ }
+
+ // check if started
+ if (bundle.getState() == Bundle.ACTIVE
+ || bundle.getState() == Bundle.STARTING)
+ md.setStarted(true);
+ else
+ md.setStarted(false);
+ }
+
+ private String getHeaderSafe(Bundle bundle, Object key) {
+ Object obj = bundle.getHeaders().get(key);
+ if (obj == null)
+ return null;
+ else
+ return obj.toString();
+ }
+
+ /*
+ * REGISTRATION
+ */
+
+ /** Registers an execution context. */
+ public synchronized void register(ExecutionContext executionContext,
+ Map<String, String> properties) {
+ OsgiBundle osgiBundle = asOsgiBundle(properties);
+ Bundle bundle = bundlesManager.findRelatedBundle(osgiBundle);
+ osgiBundle.setTitle(getHeaderSafe(bundle, Constants.BUNDLE_NAME));
+ osgiBundle.setDescription(getHeaderSafe(bundle,
+ Constants.BUNDLE_DESCRIPTION));
+ executionContexts.put(osgiBundle, executionContext);
+ if (log.isTraceEnabled())
+ log.trace("Registered execution context from " + osgiBundle);
+ // Notify
+ ModuleDescriptor md = osgiBundle.getModuleDescriptor();
+ md.setStarted(true);
+ for (ExecutionModulesListener listener : executionModulesListeners)
+ listener.executionModuleAdded(md);
+ }
+
+ /** Unregisters an execution context. */
+ public synchronized void unregister(ExecutionContext executionContext,
+ Map<String, String> properties) {
+ OsgiBundle osgiBundle = asOsgiBundle(properties);
+ if (executionContexts.containsKey(osgiBundle)) {
+ executionContexts.remove(osgiBundle);
+ if (log.isTraceEnabled())
+ log.trace("Removed execution context from " + osgiBundle);
+ // Notify
+ ModuleDescriptor md = osgiBundle.getModuleDescriptor();
+ md.setStarted(false);
+ for (ExecutionModulesListener listener : executionModulesListeners)
+ listener.executionModuleRemoved(md);
+ }
+ }
+
+ /** Registers an execution flow. */
+ public synchronized void register(ExecutionFlow executionFlow,
+ Map<String, String> properties) {
+ OsgiBundle osgiBundle = asOsgiBundle(properties);
+ if (!executionFlows.containsKey(osgiBundle)) {
+ executionFlows.put(osgiBundle, new HashSet<ExecutionFlow>());
+ }
+ executionFlows.get(osgiBundle).add(executionFlow);
+ if (log.isTraceEnabled())
+ log.trace("Registered " + executionFlow + " from " + osgiBundle);
+
+ // notifications
+ if (registerFlowsToJmx)
+ registerMBean(osgiBundle, executionFlow);
+ ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle);
+ for (ExecutionModulesListener listener : executionModulesListeners)
+ listener.executionFlowAdded(osgiBundle.getModuleDescriptor(),
+ efdc.getExecutionFlowDescriptor(executionFlow));
+ }
+
+ /** Unregisters an execution flow. */
+ public synchronized void unregister(ExecutionFlow executionFlow,
+ Map<String, String> properties) {
+ OsgiBundle osgiBundle = asOsgiBundle(properties);
+ if (executionFlows.containsKey(osgiBundle)) {
+ Set<ExecutionFlow> flows = executionFlows.get(osgiBundle);
+ flows.remove(executionFlow);
+ if (log.isTraceEnabled())
+ log.trace("Removed " + executionFlow + " from " + osgiBundle);
+ if (flows.size() == 0) {
+ executionFlows.remove(osgiBundle);
+ if (log.isTraceEnabled())
+ log.trace("Removed flows set from " + osgiBundle);
+ }
+
+ // notifications
+ if (registerFlowsToJmx)
+ unregisterMBean(osgiBundle, executionFlow);
+ ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle);
+ for (ExecutionModulesListener listener : executionModulesListeners)
+ listener.executionFlowRemoved(osgiBundle.getModuleDescriptor(),
+ efdc.getExecutionFlowDescriptor(executionFlow));
+ }
+ }
+
+ /** Registers an execution module listener. */
+ public synchronized void register(
+ ExecutionModulesListener executionModulesListener,
+ Map<String, String> properties) {
+ // sync with current state
+ for (OsgiBundle osgiBundle : executionContexts.keySet()) {
+ executionModulesListener.executionModuleAdded(osgiBundle
+ .getModuleDescriptor());
+ }
+ for (OsgiBundle osgiBundle : executionFlows.keySet()) {
+ ExecutionFlowDescriptorConverter efdc = getExecutionFlowDescriptorConverter(osgiBundle);
+ for (ExecutionFlow executionFlow : executionFlows.get(osgiBundle))
+ executionModulesListener.executionFlowAdded(
+ osgiBundle.getModuleDescriptor(),
+ efdc.getExecutionFlowDescriptor(executionFlow));
+ }
+ executionModulesListeners.add(executionModulesListener);
+ }
+
+ /** Unregisters an execution module listener. */
+ public synchronized void unregister(
+ ExecutionModulesListener executionModulesListener,
+ Map<String, String> properties) {
+ executionModulesListeners.remove(executionModulesListener);
+ }
+
+ /*
+ * INTERFACE IMPLEMENTATIONS
+ */
+
+ public void bundleChanged(BundleEvent evt) {
+ Bundle bundle = evt.getBundle();
+ if (bundle.getHeaders().get(
+ ExecutionModuleDescriptor.SLC_EXECUTION_MODULE) != null) {
+ OsgiBundle osgiBundle = new OsgiBundle(bundle);
+ if (evt.getType() == BundleEvent.INSTALLED)
+ for (ExecutionModulesListener listener : executionModulesListeners)
+ listener.executionModuleAdded(osgiBundle
+ .getModuleDescriptor());
+ else if (evt.getType() == BundleEvent.UNINSTALLED)
+ for (ExecutionModulesListener listener : executionModulesListeners)
+ listener.executionModuleRemoved(osgiBundle
+ .getModuleDescriptor());
+ }
+
+ }
+
+ @SuppressWarnings({ "rawtypes" })
+ public synchronized void bind(Object service, Map properties)
+ throws Exception {
+ if (service instanceof ExecutionFlowDescriptorConverter) {
+ ExecutionFlowDescriptorConverter executionFlowDescriptorConverter = (ExecutionFlowDescriptorConverter) service;
+ OsgiBundle osgiBundle = asOsgiBundle(properties);
+ executionFlowDescriptorConverters.put(osgiBundle,
+ executionFlowDescriptorConverter);
+ if (log.isTraceEnabled())
+ log.debug("Registered execution flow descriptor converter from "
+ + osgiBundle);
+ } else {
+ // ignore
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ public synchronized void unbind(Object service, Map properties)
+ throws Exception {
+ if (service instanceof ExecutionFlowDescriptorConverter) {
+ OsgiBundle osgiBundle = asOsgiBundle(properties);
+ if (executionFlowDescriptorConverters.containsKey(osgiBundle)) {
+ executionFlowDescriptorConverters.remove(osgiBundle);
+ if (log.isTraceEnabled())
+ log.debug("Removed execution flow descriptor converter from "
+ + osgiBundle);
+ }
+ } else {
+ // ignore
+ }
+ }
+
+ /*
+ * JMX
+ */
+ protected MBeanServer getMBeanServer() {
+ return ManagementFactory.getPlatformMBeanServer();
+ }
+
+ public void registerMBean(Module module, ExecutionFlow executionFlow) {
+ try {
+ StandardMBean mbean = new StandardMBean(executionFlow,
+ ExecutionFlow.class);
+ getMBeanServer().registerMBean(mbean,
+ flowMBeanName(module, executionFlow));
+ } catch (Exception e) {
+ String msg = "Cannot register execution flow " + executionFlow
+ + " as mbean";
+ throw new SlcException(msg, e);
+ }
+ }
+
+ public void unregisterMBean(Module module, ExecutionFlow executionFlow) {
+ try {
+ getMBeanServer().unregisterMBean(
+ flowMBeanName(module, executionFlow));
+ } catch (Exception e) {
+ String msg = "Cannot unregister execution flow " + executionFlow
+ + " as mbean";
+ throw new SlcException(msg, e);
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ protected ObjectName flowMBeanName(Module module,
+ ExecutionFlow executionFlow) {
+ String executionModulesPrefix = "SLCExecutionModules";
+ String path = executionFlow.getPath();
+ String name = executionFlow.getName();
+ if (path == null && name.indexOf('/') >= 0) {
+ path = name.substring(0, name.lastIndexOf('/'));
+ name = name.substring(name.lastIndexOf('/'));
+ }
+
+ StringBuffer buf = new StringBuffer(executionModulesPrefix + ":"
+ + "module=" + module.getName() + " [" + module.getVersion()
+ + "],");
+
+ if (path != null && !path.equals("")) {
+ int depth = 0;
+ for (String token : path.split("/")) {
+ if (!token.equals("")) {
+ buf.append("path").append(depth).append('=');
+ // in order to have directories first
+ buf.append('/');
+ buf.append(token).append(',');
+ depth++;
+ }
+ }
+ }
+ buf.append("name=").append(name);
+ try {
+ return new ObjectName(buf.toString());
+ } catch (Exception e) {
+ throw new SlcException("Cannot generate object name based on "
+ + buf, e);
+ }
+ }
+
+ /*
+ * UTILITIES
+ */
+ @SuppressWarnings("rawtypes")
+ private OsgiBundle asOsgiBundle(Map properties) {
+ String bundleSymbolicName = checkAndGet(Constants.BUNDLE_SYMBOLICNAME,
+ properties);
+ String bundleVersion = checkAndGet(Constants.BUNDLE_VERSION, properties);
+ return new OsgiBundle(bundleSymbolicName, bundleVersion);
+ }
+
+ @SuppressWarnings("rawtypes")
+ private String checkAndGet(Object key, Map properties) {
+ if (!properties.containsKey(key) || properties.get(key) == null)
+ throw new SlcException(key + " not set in " + properties);
+ else
+ return properties.get(key).toString();
+ }
+
+ public void setBundlesManager(BundlesManager bundlesManager) {
+ this.bundlesManager = bundlesManager;
+ }
+
+ public void setDefaultDescriptorConverter(
+ ExecutionFlowDescriptorConverter defaultDescriptorConverter) {
+ this.defaultDescriptorConverter = defaultDescriptorConverter;
+ }
+
+ public void setRegisterFlowsToJmx(Boolean registerFlowsToJmx) {
+ this.registerFlowsToJmx = registerFlowsToJmx;
+ }
+
+}
--- /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.osgi;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.FileExecutionResources;
+import org.osgi.framework.BundleContext;
+import org.springframework.core.io.Resource;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+import org.eclipse.gemini.blueprint.io.OsgiBundleResource;
+
+/** Write access to resources in an OSGi context */
+public class OsgiExecutionResources extends FileExecutionResources implements
+ BundleContextAware {
+ private final static Log log = LogFactory
+ .getLog(OsgiExecutionResources.class);
+
+ private BundleContext bundleContext;
+
+ @Override
+ protected File fileFromResource(Resource resource) {
+ File file = super.fileFromResource(resource);
+ if (file != null)
+ return file;
+
+ if (!(resource instanceof OsgiBundleResource))
+ return null;
+
+ OsgiBundleResource osgiBundleResource = (OsgiBundleResource) resource;
+ try {
+ return osgiBundleResource.getFile();
+ } catch (IOException e) {
+ if (log.isTraceEnabled())
+ log.trace("Resource " + resource
+ + " is not available on the file system: " + e);
+ }
+
+ // TODO: ability to access resources in other bundles
+ String location = bundleContext.getBundle().getLocation();
+ String base = null;
+ if (location.startsWith("reference:file:"))
+ base = location.substring("reference:file:".length());
+ else if (location.startsWith("initial@reference:file:")) {
+ // TODO: Equinox specific?
+ String relPath = location.substring("initial@reference:file:"
+ .length());
+ // if (relPath.startsWith("../"))// relative to the framework jar
+ // relPath = relPath.substring("../".length());
+ // String framework =
+ // System.getProperty("osgi.framework").substring(
+ // "file:".length());
+ // log.debug(framework);
+ String installArea = System.getProperty("osgi.install.area")
+ .substring("file:".length());
+ // log.debug(installArea);
+ base = installArea + '/' + relPath;
+ // int sepIndex = framework.lastIndexOf(File.separatorChar);
+ // framework = framework.substring(0, sepIndex);
+ // base = framework + '/' + relPath;
+ } else {
+ return null;
+ }
+
+ String path = base + '/' + osgiBundleResource.getPathWithinContext();
+ try {
+ file = new File(path).getCanonicalFile();
+ } catch (IOException e) {
+ throw new SlcException("Cannot determine canonical path for "
+ + path, e);
+ }
+
+ if (!file.exists())
+ throw new SlcException(file
+ + " was retrieved in bundle located at '" + location
+ + "' for resource " + resource + " but it does not exist");
+
+ if (log.isTraceEnabled())
+ log.debug("OSGi local resource: " + file + " from " + resource);
+ return file;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+}
--- /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.osgi;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.StreamReadable;
+import org.argeo.slc.UnsupportedException;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.core.build.VersionedResourceDistribution;
+import org.argeo.slc.deploy.DeploymentData;
+import org.argeo.slc.deploy.DynamicRuntime;
+import org.argeo.slc.deploy.TargetData;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+
+public class OsgiRuntime implements BundleContextAware, ResourceLoaderAware,
+ DynamicRuntime<OsgiBundle> {
+ private String uuid = UUID.randomUUID().toString();
+ private BundleContext bundleContext;
+ private ResourceLoader resourceLoader;
+
+ public List<OsgiBundle> listModules() {
+ List<OsgiBundle> modules = new ArrayList<OsgiBundle>();
+ Bundle[] bundles = bundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ OsgiBundle osgiBundle = new OsgiBundle(bundle);
+ modules.add(osgiBundle);
+ String location = bundle.getLocation();
+ if (location != null) {
+ Resource resource = resourceLoader.getResource(location);
+ osgiBundle
+ .setResourceDistribution(new VersionedResourceDistribution(
+ osgiBundle.getName(), osgiBundle.getVersion(),
+ resource));
+ }
+ }
+ return modules;
+ }
+
+ public OsgiBundle installModule(Distribution distribution) {
+ if (!(distribution instanceof StreamReadable))
+ throw new UnsupportedException("distribution", distribution);
+
+ StreamReadable sr = (StreamReadable) distribution;
+ Bundle bundle;
+ try {
+ bundle = bundleContext.installBundle(sr.toString(), sr
+ .getInputStream());
+ } catch (BundleException e) {
+ throw new SlcException(
+ "Cannot install OSGi bundle " + distribution, e);
+ }
+ return new OsgiBundle(bundle);
+ }
+
+ public void updateModule(NameVersion nameVersion) {
+ Bundle bundle = findBundle(nameVersion);
+ try {
+ bundle.update();
+ } catch (BundleException e) {
+ throw new SlcException("Cannot update " + bundle, e);
+ }
+ }
+
+ public void uninstallModule(NameVersion nameVersion) {
+ Bundle bundle = findBundle(nameVersion);
+ try {
+ bundle.uninstall();
+ } catch (BundleException e) {
+ throw new SlcException("Cannot uninstall " + bundle, e);
+ }
+ }
+
+ public void startModule(NameVersion nameVersion) {
+ Bundle bundle = findBundle(nameVersion);
+ try {
+ bundle.start();
+ // TODO: use bundle manager
+ } catch (BundleException e) {
+ throw new SlcException("Cannot uninstall " + bundle, e);
+ }
+ }
+
+ protected Bundle findBundle(NameVersion nameVersion) {
+ Bundle[] bundles = bundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ OsgiBundle osgiBundle = new OsgiBundle(bundle);
+ if (osgiBundle.equals(nameVersion)) {
+ return bundle;
+ }
+ }
+ throw new SlcException("Could not find bundle " + nameVersion);
+ }
+
+ public void shutdown() {
+ // FIXME use framework
+ throw new UnsupportedException();
+ }
+
+ public String getDeployedSystemId() {
+ return uuid;
+ }
+
+ public DeploymentData getDeploymentData() {
+ throw new UnsupportedException();
+ }
+
+ public Distribution getDistribution() {
+ throw new UnsupportedException();
+ }
+
+ public TargetData getTargetData() {
+ throw new UnsupportedException();
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+
+}
--- /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.osgi.build;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.UnsupportedException;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.build.ModularDistribution;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.springframework.beans.factory.InitializingBean;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+
+public abstract class AbstractOsgiModularDistribution implements
+ ModularDistribution, BundleContextAware, InitializingBean {
+ private final static Log log = LogFactory
+ .getLog(AbstractOsgiModularDistribution.class);
+
+ private BundleContext bundleContext;
+ private EclipseUpdateSite eclipseUpdateSite;
+
+ /** Initialized by the object itself. */
+ private SortedMap<NameVersion, Distribution> distributions = new TreeMap<NameVersion, Distribution>();
+
+ protected abstract void fillDistributions(
+ SortedMap<NameVersion, Distribution> distributions)
+ throws Exception;
+
+ public Distribution getModuleDistribution(String moduleName,
+ String moduleVersion) {
+ return distributions.get(new DefaultNameVersion(moduleName,
+ moduleVersion));
+ }
+
+ public String getDistributionId() {
+ return bundleContext.getBundle().getSymbolicName()
+ + "-"
+ + bundleContext.getBundle().getHeaders()
+ .get(Constants.BUNDLE_VERSION);
+ }
+
+ public Set<NameVersion> listModulesNameVersions() {
+ return distributions.keySet();
+ }
+
+ public Iterator<NameVersion> nameVersions() {
+ return distributions.keySet().iterator();
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ fillDistributions(distributions);
+ if (log.isDebugEnabled())
+ log.debug("Distribution " + getName() + ":" + getVersion()
+ + " loaded (" + distributions.size() + " modules)");
+ }
+
+ protected String findVersion(String name) {
+ Set<String> versions = new HashSet<String>();
+ for (NameVersion key : distributions.keySet()) {
+ if (key.getName().equals(name))
+ versions.add(key.getVersion());
+ }
+
+ if (versions.size() == 0)
+ throw new SlcException("Cannot find version for name " + name);
+ else if (versions.size() > 1)
+ throw new SlcException("Found more than one version for name "
+ + name + ": " + versions);
+ else
+ return versions.iterator().next();
+
+ }
+
+ public Object getModulesDescriptor(String descriptorType) {
+ if (descriptorType.equals("eclipse"))
+ return writeEclipseUpdateSite();
+ else
+ throw new UnsupportedException("descriptorType", descriptorType);
+ }
+
+ protected Set<NameVersion> writePlainUrlList() {
+ return distributions.keySet();
+ }
+
+ protected String writeEclipseUpdateSite() {
+ if (eclipseUpdateSite == null)
+ throw new SlcException("No eclipse update site declared.");
+
+ StringBuffer buf = new StringBuffer("");
+ buf.append("<site>");
+
+ List<EclipseUpdateSiteCategory> usedCategories = new ArrayList<EclipseUpdateSiteCategory>();
+ for (EclipseUpdateSiteFeature feature : eclipseUpdateSite.getFeatures()) {
+
+ String featureId = feature.getName();
+ String featureVersion = findVersion(featureId);
+ buf.append("<feature");
+ buf.append(" url=\"features/").append(featureId).append('_')
+ .append(featureVersion).append(".jar\"");
+ buf.append(" id=\"").append(featureId).append("\"");
+ buf.append(" version=\"").append(featureVersion).append("\"");
+ buf.append(">\n");
+
+ for (EclipseUpdateSiteCategory category : feature.getCategories()) {
+ usedCategories.add(category);
+ buf.append(" <category name=\"").append(category.getName())
+ .append("\"/>\n");
+ }
+ buf.append("</feature>\n\n");
+ }
+
+ for (EclipseUpdateSiteCategory category : usedCategories) {
+ buf.append("<category-def");
+ buf.append(" name=\"").append(category.getName()).append("\"");
+ buf.append(" label=\"").append(category.getLabel()).append("\"");
+ buf.append(">\n");
+ buf.append(" <description>").append(category.getDescription())
+ .append("</description>\n");
+ buf.append("</category-def>\n\n");
+ }
+
+ buf.append("</site>");
+ return buf.toString();
+ }
+
+ public String getName() {
+ return bundleContext.getBundle().getSymbolicName();
+ }
+
+ public String getVersion() {
+ return bundleContext.getBundle().getHeaders()
+ .get(Constants.BUNDLE_VERSION).toString();
+ }
+
+ @Override
+ public String toString() {
+ return new DefaultNameVersion(this).toString();
+ }
+
+ public void setEclipseUpdateSite(EclipseUpdateSite eclipseUpdateSite) {
+ this.eclipseUpdateSite = eclipseUpdateSite;
+ }
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+}
--- /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.osgi.build;
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.SortedMap;
+import java.util.StringTokenizer;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.core.build.VersionedResourceDistribution;
+import org.osgi.framework.Constants;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.ResourceLoader;
+
+public class BundleModularDistribution extends AbstractOsgiModularDistribution
+ implements ResourceLoaderAware {
+ private ResourceLoader resourceLoader;
+
+ private String libDirectory = "/lib";
+
+ @SuppressWarnings(value = { "unchecked" })
+ protected void fillDistributions(
+ SortedMap<NameVersion, Distribution> distributions)
+ throws Exception {
+ Enumeration<URL> urls = (Enumeration<URL>) getBundleContext()
+ .getBundle().findEntries(libDirectory, "*.jar", false);
+ while (urls.hasMoreElements()) {
+ URL url = urls.nextElement();
+ JarInputStream in = null;
+ try {
+ in = new JarInputStream(url.openStream());
+ Manifest mf = in.getManifest();
+ String name = mf.getMainAttributes().getValue(
+ Constants.BUNDLE_SYMBOLICNAME);
+ // Skip additional specs such as
+ // ; singleton:=true
+ if (name.indexOf(';') > -1) {
+ name = new StringTokenizer(name, " ;").nextToken();
+ }
+
+ String version = mf.getMainAttributes().getValue(
+ Constants.BUNDLE_VERSION);
+ DefaultNameVersion nameVersion = new DefaultNameVersion(name,
+ version);
+ distributions.put(nameVersion,
+ new VersionedResourceDistribution(name, version,
+ resourceLoader.getResource(url.toString())));
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+ }
+
+ public void setLibDirectory(String libDirectory) {
+ this.libDirectory = libDirectory;
+ }
+
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+
+ /*
+ * @SuppressWarnings(value = { "unchecked" }) protected URL
+ * findModule(String moduleName, String version) { Enumeration<URL> urls =
+ * (Enumeration<URL>) bundleContext.getBundle() .findEntries(libDirectory,
+ * moduleName + "*", false);
+ *
+ * if (!urls.hasMoreElements()) throw new SlcException("Cannot find module "
+ * + moduleName);
+ *
+ * URL url = urls.nextElement();
+ *
+ * // TODO: check version as well if (urls.hasMoreElements()) throw new
+ * SlcException("More than one module with name " + moduleName); return url;
+ * }
+ */
+
+}
--- /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.osgi.build;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EclipseUpdateSite {
+ private List<EclipseUpdateSiteFeature> features = new ArrayList<EclipseUpdateSiteFeature>();
+
+ public List<EclipseUpdateSiteFeature> getFeatures() {
+ return features;
+ }
+
+ public void setFeatures(List<EclipseUpdateSiteFeature> features) {
+ this.features = features;
+ }
+
+}
--- /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.osgi.build;
+
+public class EclipseUpdateSiteCategory {
+ private String name;
+ private String label;
+ private String description;
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
--- /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.osgi.build;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EclipseUpdateSiteFeature {
+ private String name;
+ private List<EclipseUpdateSiteCategory> categories = new ArrayList<EclipseUpdateSiteCategory>();
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<EclipseUpdateSiteCategory> getCategories() {
+ return categories;
+ }
+
+ public void setCategories(List<EclipseUpdateSiteCategory> categories) {
+ this.categories = categories;
+ }
+
+}
--- /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.osgi.build;
+
+import java.net.URL;
+import java.util.SortedMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.core.build.VersionedResourceDistribution;
+import org.argeo.slc.osgi.OsgiBundle;
+import org.osgi.framework.Bundle;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.eclipse.gemini.blueprint.util.OsgiBundleUtils;
+
+public class OsgiRuntimeModularDistribution extends
+ AbstractOsgiModularDistribution implements ResourceLoaderAware {
+ private final static Log log = LogFactory
+ .getLog(OsgiRuntimeModularDistribution.class);
+
+ private ResourceLoader resourceLoader;
+
+ protected void fillDistributions(
+ SortedMap<NameVersion, Distribution> distributions)
+ throws Exception {
+
+ String frameworkUrl = System.getProperty("osgi.framework");
+ String frameworkBaseUrl = null;
+ if (frameworkUrl != null)
+ frameworkBaseUrl = frameworkUrl.substring(0, frameworkUrl
+ .lastIndexOf('/'));
+ bundles: for (Bundle bundle : getBundleContext().getBundles()) {
+ OsgiBundle osgiBundle = new OsgiBundle(bundle);
+
+ String originalLocation = bundle.getLocation();
+
+ if (OsgiBundleUtils.isSystemBundle(bundle)) {
+ continue bundles;
+ }
+
+ String location = originalLocation;
+ if (originalLocation.startsWith("reference:file:"))
+ location = originalLocation.substring("reference:".length());
+
+ if (frameworkBaseUrl != null
+ && originalLocation.startsWith("initial@reference:file:")) {
+ location = frameworkBaseUrl
+ + '/'
+ + originalLocation.substring("initial@reference:file:"
+ .length());
+ }
+
+ try {
+ URL url = new URL(location);
+ Resource res = resourceLoader.getResource(url.toString());
+ distributions.put(osgiBundle,
+ new VersionedResourceDistribution(osgiBundle, res));
+
+ if (log.isTraceEnabled())
+ log.debug("Added url " + url + " from original location "
+ + originalLocation);
+ } catch (Exception e) {
+ log.warn("Cannot interpret location " + location
+ + " of bundle " + bundle + ": " + e);
+ }
+ }
+ }
+
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+}
--- /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.osgi.deploy;
+
+import org.argeo.slc.core.deploy.DefaultResourceSet;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.springframework.core.io.ResourceLoader;
+import org.eclipse.gemini.blueprint.context.BundleContextAware;
+import org.eclipse.gemini.blueprint.io.OsgiBundleResourceLoader;
+import org.eclipse.gemini.blueprint.io.OsgiBundleResourcePatternResolver;
+import org.eclipse.gemini.blueprint.util.OsgiBundleUtils;
+
+/**
+ * Retrieves ressources from an OSGi bundle either the active one or another one
+ * referenced by its symbolic name.
+ */
+public class OsgiResourceSet extends DefaultResourceSet implements
+ BundleContextAware {
+ private BundleContext bundleContext;
+ private Bundle bundle = null;
+ private String bundleSymbolicName = null;
+
+ private OsgiBundleResourceLoader osgiBundleResourceLoader = null;
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ osgiBundleResourceLoader = new OsgiBundleResourceLoader(getBundle());
+ if (getResourcePatternResolver() == null)
+ setResourcePatternResolver(new OsgiBundleResourcePatternResolver(
+ osgiBundleResourceLoader));
+ super.afterPropertiesSet();
+ }
+
+ public Bundle getBundle() {
+ if (bundle != null)
+ return bundle;
+ else if (bundleSymbolicName != null)// do not cache
+ return OsgiBundleUtils.findBundleBySymbolicName(bundleContext,
+ bundleSymbolicName);
+ else
+ // containing bundle
+ return bundleContext.getBundle();
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ @Override
+ public ResourceLoader getResourceLoaderToUse() {
+ return osgiBundleResourceLoader;
+ }
+
+ public void setBundle(Bundle bundle) {
+ this.bundle = bundle;
+ }
+
+ public void setBundleSymbolicName(String bundleSymbolicName) {
+ this.bundleSymbolicName = bundleSymbolicName;
+ }
+
+}
--- /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:osgi="http://www.springframework.org/schema/osgi"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"
+ xsi:schemaLocation="http://www.springframework.org/schema/osgi
+ http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+ <osgi:service interface="org.argeo.slc.execution.ExecutionContext"
+ ref="executionContext" />
+ <osgi:service
+ interface="org.argeo.slc.execution.ExecutionFlowDescriptorConverter"
+ ref="executionFlowDescriptorConverter" />
+
+ <osgi:reference id="callbackHandler"
+ interface="javax.security.auth.callback.CallbackHandler" cardinality="0..1" />
+
+ <bean class="org.argeo.slc.osgi.MultipleServiceExporterPostProcessor">
+ <property name="interfaces">
+ <list>
+ <value><![CDATA[org.argeo.slc.execution.ExecutionFlow]]></value>
+ </list>
+ </property>
+ <property name="bundleContext" ref="bundleContext" />
+ </bean>
+
+ <bean id="osgiExecutionResources" class="org.argeo.slc.osgi.OsgiExecutionResources">
+ <property name="executionContext" ref="executionContext" />
+ </bean>
+</beans>
\ No newline at end of file