import java.util.ArrayList;
import java.util.List;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.argeo.slc.SlcException;
import org.argeo.slc.core.execution.DefaultExecutionFlow;
import org.argeo.slc.execution.ExecutionFlow;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+/** Interprets the <flow:flow> tag */
public class FlowBeanDefinitionParser extends
AbstractSingleBeanDefinitionParser {
- // private Log log = LogFactory.getLog(FlowBeanDefinitionParser.class);
+ private Log log = LogFactory.getLog(FlowBeanDefinitionParser.class);
@SuppressWarnings("unchecked")
@Override
BeanDefinitionBuilder builder) {
String path = element.getAttribute("path");
if (StringUtils.hasText(path))
- builder.addPropertyValue("path", path);
+ log.warn("The 'path' attribute is not used anymore to build flows");
String spec = element.getAttribute("spec");
if (StringUtils.hasText(spec))
builder.getBeanDefinition().setDescription(
DomUtils.getChildElementValueByTagName(element, "description"));
- List<Element> execElems = new ArrayList<Element>();
List<Element> argsElems = new ArrayList<Element>();
+ List<Element> execElems = new ArrayList<Element>();
+ List<Element> specElems = new ArrayList<Element>();
NodeList nodeList = element.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node instanceof Element) {
if (DomUtils.nodeNameEquals(node, "arg"))
argsElems.add((Element) node);
+ else if (DomUtils.nodeNameEquals(node, "spec"))
+ specElems.add((Element) node);
else if (!DomUtils.nodeNameEquals(node, "description"))
execElems.add((Element) node);
}
.addGenericArgumentValue(args);
}
+ // Execution specs
+ if (StringUtils.hasText(spec) && specElems.size() != 0)
+ throw new SlcException("A flow cannot have multiple specs");
+ if (specElems.size() == 1) {
+ Object specObj = NamespaceUtils.parseBeanOrReference(
+ specElems.get(0), parserContext,
+ builder.getBeanDefinition());
+ builder.getBeanDefinition().getConstructorArgumentValues()
+ .addGenericArgumentValue(specObj);
+ } else if (specElems.size() > 1)
+ throw new SlcException("A flow cannot have multiple specs");
+
// Executables
if (execElems.size() != 0) {
ManagedList executables = new ManagedList(execElems.size());
} catch (ClassNotFoundException e) {
try {
return (Class<? extends ExecutionFlow>) Thread
- .currentThread().getContextClassLoader().loadClass(
- clss);
+ .currentThread().getContextClassLoader()
+ .loadClass(clss);
} catch (ClassNotFoundException e1) {
throw new SlcException("Cannot load class " + clss, e);
}
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
+/** Interprets the <flow:spec> tag */
public class SpecBeanDefinitionParser extends
AbstractSingleBeanDefinitionParser {
private Log log = LogFactory.getLog(SpecBeanDefinitionParser.class);
@Override
protected void doParse(Element element, ParserContext parserContext,
BeanDefinitionBuilder builder) {
- builder.getBeanDefinition().setDescription(DomUtils.getChildElementValueByTagName(element,
- "description"));
-
+ builder.getBeanDefinition().setDescription(
+ DomUtils.getChildElementValueByTagName(element, "description"));
+
ManagedMap attributes = new ManagedMap();
// Primitives
for (Element choiceElem : choices) {
BeanDefinitionBuilder choiceBuilder = BeanDefinitionBuilder
.genericBeanDefinition(RefValueChoice.class);
- choiceBuilder.addPropertyValue("name", choiceElem
- .getAttribute("name"));
+ choiceBuilder.addPropertyValue("name",
+ choiceElem.getAttribute("name"));
String desc = choiceElem.getAttribute("description");
if (StringUtils.hasText(desc))
choiceBuilder.addPropertyValue("description", desc);
refAttrBuilder.addPropertyValue("choices", choiceBeans);
}
- putInAttributes(attributes, refAttrElem, refAttrBuilder
- .getBeanDefinition(), "ref");
+ putInAttributes(attributes, refAttrElem,
+ refAttrBuilder.getBeanDefinition(), "ref");
}
builder.addPropertyValue("attributes", attributes);
protected void addCommonProperties(Element element,
ParserContext parserContext, BeanDefinitionBuilder specAttr) {
+ addBooleanProperty("isImmutable", specAttr, element);
+ addBooleanProperty("isConstant", specAttr, element);
+ addBooleanProperty("isHidden", specAttr, element);
addBooleanProperty("isParameter", specAttr, element);
addBooleanProperty("isFrozen", specAttr, element);
- addBooleanProperty("isHidden", specAttr, element);
Object value = NamespaceUtils.parseValue(element, parserContext,
specAttr.getBeanDefinition(), "value");
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns:beans="http://www.springframework.org/schema/beans"
+ targetNamespace="http://www.argeo.org/schema/slc-flow"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+ <xsd:import namespace="http://www.springframework.org/schema/beans"
+ schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" />
+
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ SLC Flow Schema, version 1.2
+ Authors: Mathieu Baudier
+
+ This simplifies the definition of SLC flows and their integration with
+ regular Spring beans.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:element name="flow">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Adds an SLC execution flow, using the default implementation.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="beans:identifiedType">
+ <xsd:sequence>
+ <xsd:element ref="beans:description" minOccurs="0" />
+ <xsd:sequence>
+ <xsd:element name="arg" minOccurs="0" maxOccurs="unbounded"
+ type="flow:argType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Parameter for an execution flow which will override at instantiation the
+ value of the parameter already defined as default value or in a parent bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:sequence>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element ref="beans:bean" />
+ <xsd:element ref="beans:ref" />
+ <xsd:element ref="flow:flow" />
+ <xsd:element ref="flow:spec" />
+ </xsd:choice>
+ <!-- <xsd:any namespace="##other" processContents="strict" minOccurs="0"
+ maxOccurs="unbounded" /> -->
+ </xsd:sequence>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Name of the flow (alternative to ID).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="class" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Another implementation of execution flow.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="path" type="xsd:string">
+ <!-- DEPRECATED: not used anymore -->
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The hierarchical path under which to register this flow.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="spec" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference to the related specification bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="parent" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The parent bean definition (in Spring sense).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="abstract" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether this flow is abstract (in Spring sense).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="spec">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ SLC flow specifications, defining the parameters and variables
+ which can be used in related flows, along with their default values and
+ various constraints.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="beans:identifiedType">
+ <xsd:sequence>
+ <xsd:element ref="beans:description" minOccurs="0" />
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="primitive" type="flow:primitiveSpecAttributeType"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A primitive specification attribute, that is, a plain standard value
+ and not a reference to an object.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="ref" type="flow:refSpecAttributeType"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference specification attribute, that is, a reference to another object.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="specAttributeType">
+ <xsd:choice>
+ <xsd:element name="value" minOccurs="0" maxOccurs="1">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The default value of the attribute as an inner bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:choice minOccurs="1" maxOccurs="1">
+ <xsd:element ref="beans:bean" />
+ <xsd:element ref="beans:ref" />
+ <xsd:element ref="beans:list" />
+ <xsd:element ref="beans:set" />
+ <xsd:element ref="beans:map" />
+ <xsd:element ref="beans:props" />
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ <xsd:attribute name="name" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the attribute, under which in can then be referenced.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="value" use="optional" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The default value of the attribute.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="ref" use="optional" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The default value of the attribute as a reference to another bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isImmutable" use="optional" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is a parameter, that is, it has to be set at
+ instantiation but can be modified afterwards for objects of scope execution.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isParameter" use="optional" type="xsd:boolean"
+ default="false">
+ <!-- DEPRECATED: old name of isImmutable -->
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is a parameter, that is, it has to be set at
+ instantiation but can be modified afterwards for objects of scope execution.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isConstant" use="optional" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is frozen, that is, it cannot be modified at runtime.
+ A frozen attribute has to be a parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isFrozen" use="optional" type="xsd:boolean"
+ default="false">
+ <!-- DEPRECATED: old name of isConstant -->
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is frozen, that is, it cannot be modified at runtime.
+ A frozen attribute has to be a parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="isHidden" use="optional" type="xsd:boolean"
+ default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Whether the attribute is hidden, that is, it should not be displayed in UIs.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="primitiveSpecAttributeType">
+ <xsd:complexContent>
+ <xsd:extension base="flow:specAttributeType">
+ <xsd:attribute name="type" default="string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The type of the primitive specification attribute.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="string" />
+ <xsd:enumeration value="integer" />
+ <xsd:enumeration value="long" />
+ <xsd:enumeration value="float" />
+ <xsd:enumeration value="double" />
+ <xsd:enumeration value="boolean" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="refSpecAttributeType">
+ <xsd:complexContent>
+ <xsd:extension base="flow:specAttributeType">
+ <xsd:choice>
+ <xsd:element name="choices" minOccurs="0" maxOccurs="1">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Possible values to chose from, if ommitted, all the beans in the
+ application context which implement the provided targetClass will
+ be considered.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element name="choice" minOccurs="0" maxOccurs="unbounded"
+ type="flow:refChoiceType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A choice for a reference specification attribute.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ <xsd:attribute name="targetClass" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The class that has to be implemented by the underlying object.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="refChoiceType">
+ <xsd:attribute name="name" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the related bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="description" use="optional" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A human readable description of this choice.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="argType">
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element ref="beans:bean" />
+ <xsd:element ref="beans:ref" />
+ <xsd:element ref="flow:param" />
+ <xsd:element ref="beans:list" />
+ <xsd:element ref="beans:set" />
+ <xsd:element ref="beans:map" />
+ <xsd:element ref="beans:props" />
+ </xsd:choice>
+ <xsd:attribute name="name" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the related parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="value" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The plain value of the related parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="ref" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The value of the related parameter as a reference to a bean.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:attribute name="as-flow" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ If decorating an executable bean, it will generate an implicit SLC
+ execution flow with the provided value as name.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <!-- <xsd:attribute name="var" type="xsd:boolean"> <xsd:annotation> <xsd:documentation><![CDATA[
+ If true, the decorated bean is set to scope execution and proxied. ]]></xsd:documentation>
+ </xsd:annotation> </xsd:attribute> -->
+
+ <xsd:element name="variable">
+ <xsd:complexType>
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Marks a bean definition as being variable, i.e. a scoped proxy of scope execution
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="proxy-target-class" type="xsd:boolean"
+ default="true">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Are class-based (CGLIB) proxies to be created?
+ This is the default;
+ in order to switch to standard Java
+ interface-based proxies, turn this flag to
+ "false".
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="param">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ If within a property tag of a bean, it will set the value of this property
+ with a reference to a parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:attribute name="name" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the related parameter.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="instantiationManager" type="xsd:string"
+ use="optional" default="instantiationManager">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference to the instantiation manager to use instead of the default one
+ (expert usage).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+</xsd:schema>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-\r
- Copyright (C) 2007-2012 Mathieu Baudier\r
-\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF 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
+<!-- Copyright (C) 2007-2012 Mathieu Baudier Licensed under the Apache License, \r
+ Version 2.0 (the "License"); you may not use this file except in compliance \r
+ with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 \r
+ Unless required by applicable law or agreed to in writing, software distributed \r
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES \r
+ OR CONDITIONS OF ANY KIND, either express or implied. See the License for \r
+ the specific language governing permissions and limitations under the License. -->\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" 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/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
+ http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-1.2.xsd">\r
\r
<bean id="hostManager" class="org.argeo.slc.lib.linux.RedhatHostManager">\r
<property name="sshTarget" ref="sshTarget" />\r
<property name="host" ref="host" />\r
</bean>\r
\r
+ <!-- Execution Flows -->\r
<bean flow:as-flow="deployConfig" class="org.argeo.slc.core.execution.tasks.MethodCall"\r
p:target-ref="hostManager" p:method="deployConfig" />\r
\r
<bean flow:as-flow="system/security/firewall" p:script="osgibundle:/scripts/firewall.sh"\r
p:sshTarget-ref="sshTarget" class="org.argeo.slc.jsch.RemoteExec" />\r
\r
+ <flow:spec id="authconfig.spec">\r
+ <flow:primitive name="ldapserver" />\r
+ <flow:primitive name="ldapbasedn" />\r
+ </flow:spec>\r
+\r
+ <flow:flow spec="">\r
+ <bean flow:as-flow="system/security/authconfig" p:sshTarget-ref="sshTarget"\r
+ class="org.argeo.slc.jsch.RemoteExec">\r
+ <property name="systemCall">\r
+ <bean class="org.argeo.slc.core.execution.tasks.SystemCall">\r
+ <property name="command">\r
+ <list>\r
+ <value>authconfig</value>\r
+ <value>--enableldap</value>\r
+ <value>--enableldapauth</value>\r
+ <value>--enablecache</value>\r
+ <value>--enablemkhomedir</value>\r
+ <value>--ldapserver=@{ldapserver}</value>\r
+ <value>--ldapbasedn=@{ldapbasedn}</value>\r
+ <value>--passalgo=sha256</value>\r
+ <value>--updateall</value>\r
+ </list>\r
+ </property>\r
+ </bean>\r
+ </property>\r
+ </bean>\r
+ </flow:flow>\r
+\r
</beans>
\ No newline at end of file