1 package org
.argeo
.slc
.core
.execution
.xml
;
3 import java
.util
.ArrayList
;
6 import org
.apache
.commons
.logging
.Log
;
7 import org
.apache
.commons
.logging
.LogFactory
;
8 import org
.argeo
.slc
.SlcException
;
9 import org
.argeo
.slc
.core
.execution
.DefaultExecutionFlow
;
10 import org
.argeo
.slc
.execution
.ExecutionFlow
;
11 import org
.springframework
.beans
.factory
.BeanDefinitionStoreException
;
12 import org
.springframework
.beans
.factory
.config
.RuntimeBeanReference
;
13 import org
.springframework
.beans
.factory
.support
.AbstractBeanDefinition
;
14 import org
.springframework
.beans
.factory
.support
.BeanDefinitionBuilder
;
15 import org
.springframework
.beans
.factory
.support
.ManagedList
;
16 import org
.springframework
.beans
.factory
.support
.ManagedMap
;
17 import org
.springframework
.beans
.factory
.xml
.AbstractSingleBeanDefinitionParser
;
18 import org
.springframework
.beans
.factory
.xml
.ParserContext
;
19 import org
.springframework
.util
.StringUtils
;
20 import org
.springframework
.util
.xml
.DomUtils
;
21 import org
.w3c
.dom
.Element
;
22 import org
.w3c
.dom
.Node
;
23 import org
.w3c
.dom
.NodeList
;
25 /** Interprets the <flow:flow> tag */
26 public class FlowBeanDefinitionParser
extends
27 AbstractSingleBeanDefinitionParser
{
28 private Log log
= LogFactory
.getLog(FlowBeanDefinitionParser
.class);
30 /** Whether the user has already be warned on path attribute usage. */
31 private Boolean warnedAboutPathAttribute
= false;
34 protected void doParse(Element element
, ParserContext parserContext
,
35 BeanDefinitionBuilder builder
) {
36 String path
= element
.getAttribute("path");
37 if (StringUtils
.hasText(path
)) {
38 builder
.addPropertyValue("path", path
);
40 // warns user only once
41 if (!warnedAboutPathAttribute
)
42 log
.warn("The path=\"\" attribute is deprecated"
43 + " and will be removed in a later release."
44 + " Use <flow:flow name=\"/my/path/flowName\">.");
45 warnedAboutPathAttribute
= true;
48 String spec
= element
.getAttribute("spec");
49 if (StringUtils
.hasText(spec
))
50 builder
.getBeanDefinition().getConstructorArgumentValues()
51 .addGenericArgumentValue(new RuntimeBeanReference(spec
));
53 String abstrac
= element
.getAttribute("abstract");
54 if (StringUtils
.hasText(abstrac
))
55 builder
.setAbstract(Boolean
.parseBoolean(abstrac
));
57 String parent
= element
.getAttribute("parent");
58 if (StringUtils
.hasText(parent
))
59 builder
.setParentName(parent
);
61 builder
.getBeanDefinition().setDescription(
62 DomUtils
.getChildElementValueByTagName(element
, "description"));
64 List
<Element
> argsElems
= new ArrayList
<Element
>();
65 List
<Element
> execElems
= new ArrayList
<Element
>();
66 List
<Element
> specElems
= new ArrayList
<Element
>();
67 NodeList nodeList
= element
.getChildNodes();
68 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
69 Node node
= nodeList
.item(i
);
70 if (node
instanceof Element
) {
71 if (DomUtils
.nodeNameEquals(node
, "arg"))
72 argsElems
.add((Element
) node
);
73 else if (DomUtils
.nodeNameEquals(node
, "spec"))
74 specElems
.add((Element
) node
);
75 else if (!DomUtils
.nodeNameEquals(node
, "description"))
76 execElems
.add((Element
) node
);
81 if (argsElems
.size() != 0) {
82 ManagedMap
<String
, Object
> args
= new ManagedMap
<String
, Object
>(
84 for (Element argElem
: argsElems
) {
85 Object value
= NamespaceUtils
.parseValue(argElem
,
86 parserContext
, builder
.getBeanDefinition(), null);
88 args
.put(argElem
.getAttribute("name"), value
);
90 throw new SlcException("No value defined.");
92 builder
.getBeanDefinition().getConstructorArgumentValues()
93 .addGenericArgumentValue(args
);
97 if (StringUtils
.hasText(spec
) && specElems
.size() != 0)
98 throw new SlcException("A flow cannot have multiple specs");
99 if (specElems
.size() == 1) {
100 Object specObj
= NamespaceUtils
.parseBeanOrReference(
101 specElems
.get(0), parserContext
,
102 builder
.getBeanDefinition());
103 builder
.getBeanDefinition().getConstructorArgumentValues()
104 .addGenericArgumentValue(specObj
);
105 } else if (specElems
.size() > 1)
106 throw new SlcException("A flow cannot have multiple specs");
109 if (execElems
.size() != 0) {
110 ManagedList
<Object
> executables
= new ManagedList
<Object
>(
112 for (Element child
: execElems
) {
113 // child validity check is performed in xsd
114 executables
.add(NamespaceUtils
.parseBeanOrReference(child
,
115 parserContext
, builder
.getBeanDefinition()));
117 if (executables
.size() > 0)
118 builder
.addPropertyValue("executables", executables
);
122 @SuppressWarnings("unchecked")
124 protected Class
<?
extends ExecutionFlow
> getBeanClass(Element element
) {
125 String clss
= element
.getAttribute("class");
126 if (StringUtils
.hasText(clss
))
127 // TODO: check that it actually works
129 return (Class
<?
extends ExecutionFlow
>) getClass()
130 .getClassLoader().loadClass(clss
);
131 } catch (ClassNotFoundException e
) {
133 return (Class
<?
extends ExecutionFlow
>) Thread
134 .currentThread().getContextClassLoader()
136 } catch (ClassNotFoundException e1
) {
137 throw new SlcException("Cannot load class " + clss
, e
);
141 return DefaultExecutionFlow
.class;
144 // parse nested bean definition
145 // private Object parseBeanReference(Element element,
146 // ParserContext parserContext, BeanDefinitionBuilder builder) {
147 // return parserContext.getDelegate().parsePropertySubElement(element,
148 // builder.getBeanDefinition());
152 protected String
resolveId(Element element
,
153 AbstractBeanDefinition definition
, ParserContext parserContext
)
154 throws BeanDefinitionStoreException
{
155 String name
= element
.getAttribute("name");
156 if (StringUtils
.hasText(name
)) {
159 return super.resolveId(element
, definition
, parserContext
);
163 protected boolean shouldGenerateIdAsFallback() {