EMMA Coverage Report (generated Thu May 22 12:08:10 CDT 2014)
[all classes][org.springframework.batch.core.configuration.xml]

COVERAGE SUMMARY FOR SOURCE FILE [CoreNamespaceUtils.java]

nameclass, %method, %block, %line, %
CoreNamespaceUtils.java100% (1/1)91%  (10/11)95%  (266/279)93%  (55/59)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CoreNamespaceUtils100% (1/1)91%  (10/11)95%  (266/279)93%  (55/59)
CoreNamespaceUtils (): void 0%   (0/1)0%   (0/3)0%   (0/1)
rangeArrayEditorAlreadyDefined (BeanDefinitionRegistry): boolean 100% (1/1)86%  (63/73)79%  (11/14)
addCoreNamespacePostProcessor (ParserContext): void 100% (1/1)100% (18/18)100% (6/6)
addRangePropertyEditor (ParserContext): void 100% (1/1)100% (32/32)100% (9/9)
autoregisterBeansForNamespace (ParserContext, Object): void 100% (1/1)100% (8/8)100% (4/4)
checkForStepScope (ParserContext, Object): void 100% (1/1)100% (55/55)100% (14/14)
coreNamespaceBeanPostProcessorAlreadyDefined (BeanDefinitionRegistry): boolean 100% (1/1)100% (30/30)100% (5/5)
isAbstract (Element): boolean 100% (1/1)100% (15/15)100% (2/2)
isUnderspecified (Element): boolean 100% (1/1)100% (12/12)100% (1/1)
matchesVersionInternal (Element): boolean 100% (1/1)100% (21/21)100% (2/2)
namespaceMatchesVersion (Element): boolean 100% (1/1)100% (12/12)100% (1/1)

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 java.util.Map;
19 
20import org.springframework.beans.PropertyValue;
21import org.springframework.beans.factory.config.BeanDefinition;
22import org.springframework.beans.factory.config.TypedStringValue;
23import org.springframework.beans.factory.support.AbstractBeanDefinition;
24import org.springframework.beans.factory.support.BeanDefinitionBuilder;
25import org.springframework.beans.factory.support.BeanDefinitionRegistry;
26import org.springframework.beans.factory.support.ManagedMap;
27import org.springframework.beans.factory.xml.ParserContext;
28import org.springframework.util.StringUtils;
29import org.w3c.dom.Element;
30 
31/**
32 * Utility methods used in parsing of the batch core namespace
33 *
34 * @author Thomas Risberg
35 */
36public class CoreNamespaceUtils {
37 
38        private static final String STEP_SCOPE_PROCESSOR_BEAN_NAME = "org.springframework.batch.core.scope.internalStepScope";
39 
40        private static final String STEP_SCOPE_PROCESSOR_CLASS_NAME = "org.springframework.batch.core.scope.StepScope";
41 
42        private static final String CUSTOM_EDITOR_CONFIGURER_CLASS_NAME = "org.springframework.beans.factory.config.CustomEditorConfigurer";
43 
44        private static final String RANGE_ARRAY_CLASS_NAME = "org.springframework.batch.item.file.transform.Range[]";
45 
46        private static final String RANGE_ARRAY_EDITOR_CLASS_NAME = "org.springframework.batch.item.file.transform.RangeArrayPropertyEditor";
47 
48        private static final String CORE_NAMESPACE_POST_PROCESSOR_CLASS_NAME = "org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor";
49 
50        protected static void autoregisterBeansForNamespace(ParserContext parserContext, Object source) {
51                checkForStepScope(parserContext, source);
52                addRangePropertyEditor(parserContext);
53                addCoreNamespacePostProcessor(parserContext);
54        }
55 
56        private static void checkForStepScope(ParserContext parserContext, Object source) {
57                boolean foundStepScope = false;
58                String[] beanNames = parserContext.getRegistry().getBeanDefinitionNames();
59                for (String beanName : beanNames) {
60                        BeanDefinition bd = parserContext.getRegistry().getBeanDefinition(beanName);
61                        if (STEP_SCOPE_PROCESSOR_CLASS_NAME.equals(bd.getBeanClassName())) {
62                                foundStepScope = true;
63                                break;
64                        }
65                }
66                if (!foundStepScope) {
67                        BeanDefinitionBuilder stepScopeBuilder = BeanDefinitionBuilder
68                                        .genericBeanDefinition(STEP_SCOPE_PROCESSOR_CLASS_NAME);
69                        AbstractBeanDefinition abd = stepScopeBuilder.getBeanDefinition();
70                        abd.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
71                        abd.setSource(source);
72                        parserContext.getRegistry().registerBeanDefinition(STEP_SCOPE_PROCESSOR_BEAN_NAME, abd);
73                }
74        }
75 
76        /**
77         * Register a RangePropertyEditor if one does not already exist.
78         *
79         * @param parserContext
80         */
81        @SuppressWarnings("unchecked")
82        private static void addRangePropertyEditor(ParserContext parserContext) {
83                BeanDefinitionRegistry registry = parserContext.getRegistry();
84                if (!rangeArrayEditorAlreadyDefined(registry)) {
85                        AbstractBeanDefinition customEditorConfigurer = BeanDefinitionBuilder.genericBeanDefinition(
86                                        CUSTOM_EDITOR_CONFIGURER_CLASS_NAME).getBeanDefinition();
87                        customEditorConfigurer.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
88                        ManagedMap editors = new ManagedMap();
89                        editors.put(RANGE_ARRAY_CLASS_NAME, RANGE_ARRAY_EDITOR_CLASS_NAME);
90                        customEditorConfigurer.getPropertyValues().addPropertyValue("customEditors", editors);
91                        registry.registerBeanDefinition(CUSTOM_EDITOR_CONFIGURER_CLASS_NAME, customEditorConfigurer);
92                }
93        }
94 
95        private static boolean rangeArrayEditorAlreadyDefined(BeanDefinitionRegistry registry) {
96                for (String beanName : registry.getBeanDefinitionNames()) {
97                        BeanDefinition bd = registry.getBeanDefinition(beanName);
98                        if (CUSTOM_EDITOR_CONFIGURER_CLASS_NAME.equals(bd.getBeanClassName())) {
99                                PropertyValue pv = bd.getPropertyValues().getPropertyValue("customEditors");
100                                if (pv != null) {
101                                        for (Map.Entry<?, ?> entry : ((Map<?, ?>) pv.getValue()).entrySet()) {
102                                                if (entry.getKey() instanceof TypedStringValue) {
103                                                        if (RANGE_ARRAY_CLASS_NAME.equals(((TypedStringValue) entry.getKey()).getValue())) {
104                                                                return true;
105                                                        }
106                                                }
107                                                else if (entry.getKey() instanceof String) {
108                                                        if (RANGE_ARRAY_CLASS_NAME.equals(entry.getKey())) {
109                                                                return true;
110                                                        }
111                                                }
112                                        }
113                                }
114                        }
115                }
116                return false;
117        }
118 
119        /**
120         * @param parserContext
121         */
122        private static void addCoreNamespacePostProcessor(ParserContext parserContext) {
123                BeanDefinitionRegistry registry = parserContext.getRegistry();
124                if (!coreNamespaceBeanPostProcessorAlreadyDefined(registry)) {
125                        AbstractBeanDefinition postProcessorBeanDef = BeanDefinitionBuilder.genericBeanDefinition(
126                                        CORE_NAMESPACE_POST_PROCESSOR_CLASS_NAME).getBeanDefinition();
127                        postProcessorBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
128                        registry.registerBeanDefinition(CORE_NAMESPACE_POST_PROCESSOR_CLASS_NAME, postProcessorBeanDef);
129                }
130        }
131 
132        private static boolean coreNamespaceBeanPostProcessorAlreadyDefined(BeanDefinitionRegistry registry) {
133                for (String beanName : registry.getBeanDefinitionNames()) {
134                        BeanDefinition bd = registry.getBeanDefinition(beanName);
135                        if (CORE_NAMESPACE_POST_PROCESSOR_CLASS_NAME.equals(bd.getBeanClassName())) {
136                                return true;
137                        }
138                }
139                return false;
140        }
141 
142        /**
143         * Should this element be treated as incomplete? If it has a parent or is
144         * abstract, then it may not have all properties.
145         *
146         * @param element
147         * @return TRUE if the element is abstract or has a parent
148         */
149        public static boolean isUnderspecified(Element element) {
150                return isAbstract(element) || StringUtils.hasText(element.getAttribute("parent"));
151        }
152 
153        /**
154         * @param element
155         * @return TRUE if the element is abstract
156         */
157        public static boolean isAbstract(Element element) {
158                String abstractAttr = element.getAttribute("abstract");
159                return StringUtils.hasText(abstractAttr) && Boolean.valueOf(abstractAttr);
160        }
161 
162        /**
163         * Check that the schema location declared in the source file being parsed
164         * matches the Spring Batch version. (The old 2.0 schema is not 100%
165         * compatible with the new parser, so it is an error to explicitly define
166         * 2.0. It might be an error to declare spring-batch.xsd as an alias, but
167         * you are only going to find that out when one of the sub parses breaks.)
168         *
169         * @param element the element that is to be parsed next
170         * @return true if we find a schema declaration that matches
171         */
172        public static boolean namespaceMatchesVersion(Element element) {
173                return matchesVersionInternal(element)
174                                && matchesVersionInternal(element.getOwnerDocument().getDocumentElement());
175        }
176 
177        private static boolean matchesVersionInternal(Element element) {
178                String schemaLocation = element.getAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation");
179                return schemaLocation.matches("(?m).*spring-batch-2.2.xsd.*")
180                                || schemaLocation.matches("(?m).*spring-batch.xsd.*")
181                                || !schemaLocation.matches("(?m).*spring-batch.*");
182        }
183 
184}

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