View Javadoc
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.List;
19  
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  import org.argeo.slc.core.execution.DefaultExecutionSpec;
23  import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
24  import org.argeo.slc.core.execution.RefSpecAttribute;
25  import org.argeo.slc.core.execution.RefValueChoice;
26  import org.springframework.beans.factory.config.BeanDefinition;
27  import org.springframework.beans.factory.support.BeanDefinitionBuilder;
28  import org.springframework.beans.factory.support.ManagedList;
29  import org.springframework.beans.factory.support.ManagedMap;
30  import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
31  import org.springframework.beans.factory.xml.ParserContext;
32  import org.springframework.util.StringUtils;
33  import org.springframework.util.xml.DomUtils;
34  import org.w3c.dom.Element;
35  
36  /** Interprets the <flow:spec> tag */
37  public class SpecBeanDefinitionParser extends
38  		AbstractSingleBeanDefinitionParser {
39  	private Log log = LogFactory.getLog(SpecBeanDefinitionParser.class);
40  
41  	@Override
42  	protected void doParse(Element element, ParserContext parserContext,
43  			BeanDefinitionBuilder builder) {
44  		builder.getBeanDefinition().setDescription(
45  				DomUtils.getChildElementValueByTagName(element, "description"));
46  
47  		ManagedMap<String, BeanDefinition> attributes = new ManagedMap<String, BeanDefinition>();
48  
49  		// Primitives
50  		for (Element child : (List<Element>) DomUtils
51  				.getChildElementsByTagName(element, "primitive")) {
52  			BeanDefinitionBuilder childBuilder = BeanDefinitionBuilder
53  					.genericBeanDefinition(PrimitiveSpecAttribute.class);
54  			addCommonProperties(child, parserContext, childBuilder);
55  
56  			String type = child.getAttribute("type");
57  			if (StringUtils.hasText(type))
58  				childBuilder.addPropertyValue("type", type);
59  
60  			putInAttributes(attributes, child,
61  					childBuilder.getBeanDefinition(), "primitive");
62  		}
63  
64  		// Refs
65  		for (Element refAttrElem : (List<Element>) DomUtils
66  				.getChildElementsByTagName(element, "ref")) {
67  			BeanDefinitionBuilder refAttrBuilder = BeanDefinitionBuilder
68  					.genericBeanDefinition(RefSpecAttribute.class);
69  			addCommonProperties(refAttrElem, parserContext, refAttrBuilder);
70  
71  			String targetClassName = refAttrElem.getAttribute("targetClass");
72  			if (StringUtils.hasText(targetClassName))
73  				refAttrBuilder.addPropertyValue("targetClass", targetClassName);
74  
75  			// Choices
76  			Element choicesElem = DomUtils.getChildElementByTagName(
77  					refAttrElem, "choices");
78  			if (choicesElem != null) {
79  				List<Element> choices = DomUtils.getChildElementsByTagName(
80  						choicesElem, "choice");
81  				ManagedList<BeanDefinition> choiceBeans = new ManagedList<BeanDefinition>(
82  						choices.size());
83  				for (Element choiceElem : choices) {
84  					BeanDefinitionBuilder choiceBuilder = BeanDefinitionBuilder
85  							.genericBeanDefinition(RefValueChoice.class);
86  					choiceBuilder.addPropertyValue("name",
87  							choiceElem.getAttribute("name"));
88  					String desc = choiceElem.getAttribute("description");
89  					if (StringUtils.hasText(desc))
90  						choiceBuilder.addPropertyValue("description", desc);
91  
92  					choiceBeans.add(choiceBuilder.getBeanDefinition());
93  				}
94  				refAttrBuilder.addPropertyValue("choices", choiceBeans);
95  			}
96  
97  			putInAttributes(attributes, refAttrElem,
98  					refAttrBuilder.getBeanDefinition(), "ref");
99  		}
100 
101 		builder.addPropertyValue("attributes", attributes);
102 	}
103 
104 	protected void addCommonProperties(Element element,
105 			ParserContext parserContext, BeanDefinitionBuilder specAttr) {
106 		addBooleanProperty("isImmutable", specAttr, element);
107 		addBooleanProperty("isConstant", specAttr, element);
108 		addBooleanProperty("isHidden", specAttr, element);
109 		addBooleanProperty("isParameter", specAttr, element);
110 		addBooleanProperty("isFrozen", specAttr, element);
111 
112 		Object value = NamespaceUtils.parseValue(element, parserContext,
113 				specAttr.getBeanDefinition(), "value");
114 		if (value != null)
115 			specAttr.addPropertyValue("value", value);
116 
117 	}
118 
119 	protected void putInAttributes(
120 			ManagedMap<String, BeanDefinition> attributes, Element child,
121 			BeanDefinition beanDefinition, String nature) {
122 		String name = child.getAttribute("name");
123 		attributes.put(name, beanDefinition);
124 		if (log.isTraceEnabled())
125 			log.debug("Added " + nature + " attribute " + name);
126 
127 	}
128 
129 	private void addBooleanProperty(String name,
130 			BeanDefinitionBuilder specAttr, Element element) {
131 		String bool = element.getAttribute(name);
132 		if (StringUtils.hasText(bool))
133 			specAttr.addPropertyValue(name, Boolean.parseBoolean(bool));
134 
135 	}
136 
137 	@Override
138 	protected Class<DefaultExecutionSpec> getBeanClass(Element element) {
139 		return DefaultExecutionSpec.class;
140 	}
141 
142 	protected boolean shouldGenerateIdAsFallback() {
143 		return false;
144 	}
145 
146 }