]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/xml/FlowBeanDefinitionParser.java
Remove unnecessary check causing failures
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / execution / xml / FlowBeanDefinitionParser.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.slc.core.execution.xml;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.argeo.slc.SlcException;
24 import org.argeo.slc.core.execution.DefaultExecutionFlow;
25 import org.argeo.slc.execution.ExecutionFlow;
26 import org.springframework.beans.factory.BeanDefinitionStoreException;
27 import org.springframework.beans.factory.config.RuntimeBeanReference;
28 import org.springframework.beans.factory.support.AbstractBeanDefinition;
29 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
30 import org.springframework.beans.factory.support.ManagedList;
31 import org.springframework.beans.factory.support.ManagedMap;
32 import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
33 import org.springframework.beans.factory.xml.ParserContext;
34 import org.springframework.util.StringUtils;
35 import org.springframework.util.xml.DomUtils;
36 import org.w3c.dom.Element;
37 import org.w3c.dom.Node;
38 import org.w3c.dom.NodeList;
39
40 /** Interprets the <flow:flow> tag */
41 public class FlowBeanDefinitionParser extends
42 AbstractSingleBeanDefinitionParser {
43 private Log log = LogFactory.getLog(FlowBeanDefinitionParser.class);
44
45 /** Whether the user has already be warned on path attribute usage. */
46 private Boolean warnedAboutPathAttribute = false;
47
48 @SuppressWarnings("unchecked")
49 @Override
50 protected void doParse(Element element, ParserContext parserContext,
51 BeanDefinitionBuilder builder) {
52 String path = element.getAttribute("path");
53 if (StringUtils.hasText(path)) {
54 builder.addPropertyValue("path", path);
55
56 // warns user only once
57 if (!warnedAboutPathAttribute)
58 log.warn("The path=\"\" attribute is deprecated"
59 + " and will be removed in a later release."
60 + " Use <flow:flow name=\"/my/path/flowName\">.");
61 warnedAboutPathAttribute = true;
62 }
63
64 String spec = element.getAttribute("spec");
65 if (StringUtils.hasText(spec))
66 builder.getBeanDefinition().getConstructorArgumentValues()
67 .addGenericArgumentValue(new RuntimeBeanReference(spec));
68
69 String abstrac = element.getAttribute("abstract");
70 if (StringUtils.hasText(abstrac))
71 builder.setAbstract(Boolean.parseBoolean(abstrac));
72
73 String parent = element.getAttribute("parent");
74 if (StringUtils.hasText(parent))
75 builder.setParentName(parent);
76
77 builder.getBeanDefinition().setDescription(
78 DomUtils.getChildElementValueByTagName(element, "description"));
79
80 List<Element> argsElems = new ArrayList<Element>();
81 List<Element> execElems = new ArrayList<Element>();
82 List<Element> specElems = new ArrayList<Element>();
83 NodeList nodeList = element.getChildNodes();
84 for (int i = 0; i < nodeList.getLength(); i++) {
85 Node node = nodeList.item(i);
86 if (node instanceof Element) {
87 if (DomUtils.nodeNameEquals(node, "arg"))
88 argsElems.add((Element) node);
89 else if (DomUtils.nodeNameEquals(node, "spec"))
90 specElems.add((Element) node);
91 else if (!DomUtils.nodeNameEquals(node, "description"))
92 execElems.add((Element) node);
93 }
94 }
95
96 // Arguments
97 if (argsElems.size() != 0) {
98 ManagedMap args = new ManagedMap(argsElems.size());
99 for (Element argElem : argsElems) {
100 Object value = NamespaceUtils.parseValue(argElem,
101 parserContext, builder.getBeanDefinition(), null);
102 if (value != null)
103 args.put(argElem.getAttribute("name"), value);
104 else
105 throw new SlcException("No value defined.");
106 }
107 builder.getBeanDefinition().getConstructorArgumentValues()
108 .addGenericArgumentValue(args);
109 }
110
111 // Execution specs
112 if (StringUtils.hasText(spec) && specElems.size() != 0)
113 throw new SlcException("A flow cannot have multiple specs");
114 if (specElems.size() == 1) {
115 Object specObj = NamespaceUtils.parseBeanOrReference(
116 specElems.get(0), parserContext,
117 builder.getBeanDefinition());
118 builder.getBeanDefinition().getConstructorArgumentValues()
119 .addGenericArgumentValue(specObj);
120 } else if (specElems.size() > 1)
121 throw new SlcException("A flow cannot have multiple specs");
122
123 // Executables
124 if (execElems.size() != 0) {
125 ManagedList executables = new ManagedList(execElems.size());
126 for (Element child : execElems) {
127 // child validity check is performed in xsd
128 executables.add(NamespaceUtils.parseBeanOrReference(child,
129 parserContext, builder.getBeanDefinition()));
130 }
131 if (executables.size() > 0)
132 builder.addPropertyValue("executables", executables);
133 }
134 }
135
136 @SuppressWarnings("unchecked")
137 @Override
138 protected Class<? extends ExecutionFlow> getBeanClass(Element element) {
139 String clss = element.getAttribute("class");
140 if (StringUtils.hasText(clss))
141 // TODO: check that it actually works
142 try {
143 return (Class<? extends ExecutionFlow>) getClass()
144 .getClassLoader().loadClass(clss);
145 } catch (ClassNotFoundException e) {
146 try {
147 return (Class<? extends ExecutionFlow>) Thread
148 .currentThread().getContextClassLoader()
149 .loadClass(clss);
150 } catch (ClassNotFoundException e1) {
151 throw new SlcException("Cannot load class " + clss, e);
152 }
153 }
154 else
155 return DefaultExecutionFlow.class;
156 }
157
158 // parse nested bean definition
159 // private Object parseBeanReference(Element element,
160 // ParserContext parserContext, BeanDefinitionBuilder builder) {
161 // return parserContext.getDelegate().parsePropertySubElement(element,
162 // builder.getBeanDefinition());
163 // }
164
165 @Override
166 protected String resolveId(Element element,
167 AbstractBeanDefinition definition, ParserContext parserContext)
168 throws BeanDefinitionStoreException {
169 String name = element.getAttribute("name");
170 if (StringUtils.hasText(name)) {
171 return name;
172 } else {
173 return super.resolveId(element, definition, parserContext);
174 }
175 }
176
177 protected boolean shouldGenerateIdAsFallback() {
178 return true;
179 }
180
181 }