EMMA Coverage Report (generated Thu Jan 24 13:37:04 CST 2013)
[all classes][org.springframework.batch.core.configuration.xml]

COVERAGE SUMMARY FOR SOURCE FILE [AbstractStepParser.java]

nameclass, %method, %block, %line, %
AbstractStepParser.java100% (1/1)100% (6/6)95%  (444/466)95%  (113.8/120)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AbstractStepParser100% (1/1)100% (6/6)95%  (444/466)95%  (113.8/120)
parseJob (Element, Element, AbstractBeanDefinition, ParserContext, boolean): ... 100% (1/1)90%  (54/60)87%  (13/15)
parsePartition (Element, Element, AbstractBeanDefinition, ParserContext, bool... 100% (1/1)92%  (141/153)90%  (35/39)
parseStep (Element, ParserContext, String): AbstractBeanDefinition 100% (1/1)98%  (201/205)100% (52.8/53)
<static initializer> 100% (1/1)100% (6/6)100% (1/1)
AbstractStepParser (): void 100% (1/1)100% (3/3)100% (1/1)
parseFlow (Element, Element, AbstractBeanDefinition, ParserContext, boolean):... 100% (1/1)100% (39/39)100% (11/11)

1/*
2 * Copyright 2006-2009 the original author or authors.
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 */
16package org.springframework.batch.core.configuration.xml;
17 
18import org.springframework.batch.core.listener.StepListenerMetaData;
19import org.springframework.beans.MutablePropertyValues;
20import org.springframework.beans.factory.config.BeanDefinition;
21import org.springframework.beans.factory.config.BeanDefinitionHolder;
22import org.springframework.beans.factory.config.RuntimeBeanReference;
23import org.springframework.beans.factory.config.TypedStringValue;
24import org.springframework.beans.factory.support.AbstractBeanDefinition;
25import org.springframework.beans.factory.support.BeanDefinitionBuilder;
26import org.springframework.beans.factory.support.GenericBeanDefinition;
27import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
28import org.springframework.beans.factory.xml.ParserContext;
29import org.springframework.util.StringUtils;
30import org.springframework.util.xml.DomUtils;
31import org.w3c.dom.Element;
32import org.w3c.dom.Node;
33import org.w3c.dom.NodeList;
34 
35/**
36 * Internal parser for the &lt;step/&gt; elements inside a job. A step element
37 * references a bean definition for a
38 * {@link org.springframework.batch.core.Step} and goes on to (optionally) list
39 * a set of transitions from that step to others with &lt;next on="pattern"
40 * to="stepName"/&gt;. Used by the {@link JobParser}.
41 *
42 * @author Dave Syer
43 * @author Thomas Risberg
44 * @author Josh Long
45 * @see JobParser
46 * @since 2.0
47 */
48public abstract class AbstractStepParser {
49 
50        protected static final String ID_ATTR = "id";
51 
52        private static final String PARENT_ATTR = "parent";
53 
54        private static final String REF_ATTR = "ref";
55 
56        private static final String TASKLET_ELE = "tasklet";
57 
58        private static final String PARTITION_ELE = "partition";
59 
60        private static final String JOB_ELE = "job";
61 
62        private static final String JOB_PARAMS_EXTRACTOR_ATTR = "job-parameters-extractor";
63 
64        private static final String JOB_LAUNCHER_ATTR = "job-launcher";
65 
66        private static final String STEP_ATTR = "step";
67 
68        private static final String STEP_ELE = STEP_ATTR;
69 
70        private static final String PARTITIONER_ATTR = "partitioner";
71 
72        private static final String AGGREGATOR_ATTR = "aggregator";
73 
74        private static final String HANDLER_ATTR = "handler";
75 
76        private static final String HANDLER_ELE = "handler";
77 
78        private static final String TASK_EXECUTOR_ATTR = "task-executor";
79 
80        private static final String GRID_SIZE_ATTR = "grid-size";
81 
82        private static final String FLOW_ELE = "flow";
83 
84        private static final String JOB_REPO_ATTR = "job-repository";
85 
86        private static final StepListenerParser stepListenerParser = new StepListenerParser(StepListenerMetaData.stepExecutionListenerMetaData());
87 
88        /**
89         * @param stepElement   The &lt;step/&gt; element
90         * @param parserContext
91         * @param jobFactoryRef the reference to the {@link JobParserJobFactoryBean}
92         *                      from the enclosing tag. Use 'null' if unknown.
93         */
94        protected AbstractBeanDefinition parseStep(Element stepElement, ParserContext parserContext, String jobFactoryRef) {
95 
96                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
97                AbstractBeanDefinition bd = builder.getRawBeanDefinition();
98 
99                // look at all nested elements
100                NodeList children = stepElement.getChildNodes();
101                
102                for (int i = 0; i < children.getLength(); i++) {
103                        Node nd = children.item(i);
104 
105                        if (nd instanceof Element) {
106                                Element nestedElement = (Element) nd;
107                                String name = nestedElement.getLocalName();
108 
109                                if (TASKLET_ELE.equals(name)) {
110                                        boolean stepUnderspecified = CoreNamespaceUtils.isUnderspecified(stepElement);
111                                        new TaskletParser().parseTasklet(stepElement, nestedElement, bd, parserContext, stepUnderspecified);
112                                }
113                                else if (FLOW_ELE.equals(name)) {
114                                        boolean stepUnderspecified = CoreNamespaceUtils.isUnderspecified(stepElement);
115                                        parseFlow(stepElement, nestedElement, bd, parserContext, stepUnderspecified);
116                                }
117                                else if (PARTITION_ELE.equals(name)) {
118                                        boolean stepUnderspecified = CoreNamespaceUtils.isUnderspecified(stepElement);
119                                        parsePartition(stepElement, nestedElement, bd, parserContext, stepUnderspecified, jobFactoryRef);
120                                }
121                                else if (JOB_ELE.equals(name)) {
122                                        boolean stepUnderspecified = CoreNamespaceUtils.isUnderspecified(stepElement);
123                                        parseJob(stepElement, nestedElement, bd, parserContext, stepUnderspecified);
124                                }
125                                else if ("description".equals(name)) {
126                                        bd.setDescription(nestedElement.getTextContent());
127                                }
128 
129                                // nested bean reference/declaration
130                                else {
131                                        String ns = nestedElement.getNamespaceURI();
132                                        Object value = null;
133                                        boolean skip = false;
134 
135                                        // Spring NS
136                                        if ((ns == null && name.equals(BeanDefinitionParserDelegate.BEAN_ELEMENT))
137                                                        || ns.equals(BeanDefinitionParserDelegate.BEANS_NAMESPACE_URI)) {
138                                                BeanDefinitionHolder holder = parserContext.getDelegate().parseBeanDefinitionElement(nestedElement);
139                                                value = parserContext.getDelegate().decorateBeanDefinitionIfRequired(nestedElement, holder);
140                                        }
141                                        // Spring Batch transitions
142                                        else if (ns.equals("http://www.springframework.org/schema/batch")) {
143                                                // don't parse
144                                                skip = true;
145                                        }
146                                        // Custom NS
147                                        else {
148                                                value = parserContext.getDelegate().parseCustomElement(nestedElement);
149                                        }
150                                        
151                                        if (!skip) {
152                                                bd.setBeanClass(StepParserStepFactoryBean.class);
153                                                bd.setAttribute("isNamespaceStep", true);
154                                                builder.addPropertyValue("tasklet", value);
155                                        }
156                                }
157                        }
158                }
159 
160                String parentRef = stepElement.getAttribute(PARENT_ATTR);
161                if (StringUtils.hasText(parentRef)) {
162                        bd.setParentName(parentRef);
163                }
164 
165                String isAbstract = stepElement.getAttribute("abstract");
166                if (StringUtils.hasText(isAbstract)) {
167                        bd.setAbstract(Boolean.valueOf(isAbstract));
168                }
169 
170                String jobRepositoryRef = stepElement.getAttribute(JOB_REPO_ATTR);
171                if (StringUtils.hasText(jobRepositoryRef)) {
172                        builder.addPropertyReference("jobRepository", jobRepositoryRef);
173                }
174 
175                if (StringUtils.hasText(jobFactoryRef)) {
176                        bd.setAttribute("jobParserJobFactoryBeanRef", jobFactoryRef);
177                }
178 
179                stepListenerParser.handleListenersElement(stepElement, bd, parserContext);
180                return bd;
181        }
182 
183        private void parsePartition(Element stepElement, Element partitionElement, AbstractBeanDefinition bd, ParserContext parserContext, boolean stepUnderspecified, String jobFactoryRef ) {
184 
185                bd.setBeanClass(StepParserStepFactoryBean.class);
186                bd.setAttribute("isNamespaceStep", true);
187                String stepRef = partitionElement.getAttribute(STEP_ATTR);
188                String partitionerRef = partitionElement.getAttribute(PARTITIONER_ATTR);
189                String aggregatorRef = partitionElement.getAttribute(AGGREGATOR_ATTR);
190                String handlerRef = partitionElement.getAttribute(HANDLER_ATTR);
191 
192                if (!StringUtils.hasText(partitionerRef)) {
193                        parserContext.getReaderContext().error("You must specify a partitioner", partitionElement);
194                        return;
195                }
196 
197                MutablePropertyValues propertyValues = bd.getPropertyValues();
198 
199                propertyValues.addPropertyValue("partitioner", new RuntimeBeanReference(partitionerRef));
200                if (StringUtils.hasText(aggregatorRef)) {
201                        propertyValues.addPropertyValue("stepExecutionAggregator", new RuntimeBeanReference(aggregatorRef));                        
202                }
203 
204                boolean customHandler = false;
205                if (!StringUtils.hasText(handlerRef)) {
206                        Element handlerElement = DomUtils.getChildElementByTagName(partitionElement, HANDLER_ELE);
207                        if (handlerElement != null) {
208                                String taskExecutorRef = handlerElement.getAttribute(TASK_EXECUTOR_ATTR);
209                                if (StringUtils.hasText(taskExecutorRef)) {
210                                        propertyValues.addPropertyValue("taskExecutor", new RuntimeBeanReference(taskExecutorRef));
211                                }
212                                String gridSize = handlerElement.getAttribute(GRID_SIZE_ATTR);
213                                if (StringUtils.hasText(gridSize)) {
214                                        propertyValues.addPropertyValue("gridSize", new TypedStringValue(gridSize));
215                                }
216                        }
217                } else {
218                        customHandler = true;
219                        BeanDefinition partitionHandler = BeanDefinitionBuilder.genericBeanDefinition().getRawBeanDefinition();
220                        partitionHandler.setParentName(handlerRef);
221                        propertyValues.addPropertyValue("partitionHandler", partitionHandler);
222                }
223 
224                Element inlineStepElement = DomUtils.getChildElementByTagName(partitionElement, STEP_ELE);
225                if (inlineStepElement == null && !StringUtils.hasText(stepRef) && !customHandler) {
226                        parserContext.getReaderContext().error("You must specify a step", partitionElement);
227                        return;
228                }
229 
230                if (StringUtils.hasText(stepRef)) {
231                        propertyValues.addPropertyValue("step", new RuntimeBeanReference(stepRef));
232                } else if( inlineStepElement!=null) {
233                        AbstractBeanDefinition stepDefinition = parseStep(inlineStepElement, parserContext, jobFactoryRef);
234                        stepDefinition.getPropertyValues().addPropertyValue("name", stepElement.getAttribute(ID_ATTR));
235                        propertyValues.addPropertyValue("step", stepDefinition );
236                }
237 
238        }
239 
240        private void parseJob(Element stepElement, Element jobElement, AbstractBeanDefinition bd, ParserContext parserContext, boolean stepUnderspecified) {
241 
242                bd.setBeanClass(StepParserStepFactoryBean.class);
243                bd.setAttribute("isNamespaceStep", true);
244                String jobRef = jobElement.getAttribute(REF_ATTR);
245 
246                if (!StringUtils.hasText(jobRef)) {
247                        parserContext.getReaderContext().error("You must specify a job", jobElement);
248                        return;
249                }
250 
251                MutablePropertyValues propertyValues = bd.getPropertyValues();
252                propertyValues.addPropertyValue("job", new RuntimeBeanReference(jobRef));
253 
254                String jobParametersExtractor = jobElement.getAttribute(JOB_PARAMS_EXTRACTOR_ATTR);
255                String jobLauncher = jobElement.getAttribute(JOB_LAUNCHER_ATTR);
256 
257                if (StringUtils.hasText(jobParametersExtractor)) {
258                        propertyValues.addPropertyValue("jobParametersExtractor", new RuntimeBeanReference(jobParametersExtractor));
259                }
260                if (StringUtils.hasText(jobLauncher)) {
261                        propertyValues.addPropertyValue("jobLauncher", new RuntimeBeanReference(jobLauncher));
262                }
263 
264        }
265 
266 
267        private void parseFlow(Element stepElement, Element flowElement, AbstractBeanDefinition bd,
268                               ParserContext parserContext, boolean stepUnderspecified) {
269 
270                bd.setBeanClass(StepParserStepFactoryBean.class);
271                bd.setAttribute("isNamespaceStep", true);
272                String flowRef = flowElement.getAttribute(PARENT_ATTR);
273                String idAttribute = stepElement.getAttribute(ID_ATTR);
274 
275                BeanDefinition flowDefinition = new GenericBeanDefinition();
276                flowDefinition.setParentName(flowRef);
277                MutablePropertyValues propertyValues = flowDefinition.getPropertyValues();
278                if (StringUtils.hasText(idAttribute)) {
279                        propertyValues.addPropertyValue("name", idAttribute);
280                }
281 
282                bd.getPropertyValues().addPropertyValue("flow", flowDefinition);
283 
284        }
285 
286}

[all classes][org.springframework.batch.core.configuration.xml]
EMMA 2.0.5312 (C) Vladimir Roubtsov