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 [CoreNamespacePostProcessor.java]

nameclass, %method, %block, %line, %
CoreNamespacePostProcessor.java100% (1/1)100% (8/8)100% (157/157)100% (40/40)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CoreNamespacePostProcessor100% (1/1)100% (8/8)100% (157/157)100% (40/40)
CoreNamespacePostProcessor (): void 100% (1/1)100% (3/3)100% (1/1)
injectDefaults (Object): Object 100% (1/1)100% (54/54)100% (15/15)
injectJobRepositoryIntoSteps (String, ConfigurableListableBeanFactory): void 100% (1/1)100% (43/43)100% (11/11)
overrideStepClass (String, ConfigurableListableBeanFactory): void 100% (1/1)100% (21/21)100% (5/5)
postProcessAfterInitialization (Object, String): Object 100% (1/1)100% (2/2)100% (1/1)
postProcessBeanFactory (ConfigurableListableBeanFactory): void 100% (1/1)100% (26/26)100% (4/4)
postProcessBeforeInitialization (Object, String): Object 100% (1/1)100% (4/4)100% (1/1)
setApplicationContext (ApplicationContext): void 100% (1/1)100% (4/4)100% (2/2)

1/*
2 * Copyright 2006-2013 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.repository.JobRepository;
19import org.springframework.batch.core.step.AbstractStep;
20import org.springframework.beans.BeansException;
21import org.springframework.beans.MutablePropertyValues;
22import org.springframework.beans.PropertyValue;
23import org.springframework.beans.factory.config.BeanDefinition;
24import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
25import org.springframework.beans.factory.config.BeanPostProcessor;
26import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
27import org.springframework.beans.factory.config.RuntimeBeanReference;
28import org.springframework.beans.factory.support.AbstractBeanDefinition;
29import org.springframework.context.ApplicationContext;
30import org.springframework.context.ApplicationContextAware;
31import org.springframework.transaction.PlatformTransactionManager;
32 
33/**
34 * Post-process jobs and steps defined using the batch namespace to inject
35 * dependencies.
36 *
37 * @author Dan Garrette
38 * @since 2.0.1
39 */
40public class CoreNamespacePostProcessor implements BeanPostProcessor, BeanFactoryPostProcessor, ApplicationContextAware {
41 
42        private static final String DEFAULT_JOB_REPOSITORY_NAME = "jobRepository";
43 
44        private static final String DEFAULT_TRANSACTION_MANAGER_NAME = "transactionManager";
45 
46        private static final String JOB_FACTORY_PROPERTY_NAME = "jobParserJobFactoryBeanRef";
47 
48        private static final String JOB_REPOSITORY_PROPERTY_NAME = "jobRepository";
49 
50        private ApplicationContext applicationContext;
51 
52        @Override
53        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
54                for (String beanName : beanFactory.getBeanDefinitionNames()) {
55                        injectJobRepositoryIntoSteps(beanName, beanFactory);
56                        overrideStepClass(beanName, beanFactory);
57                }
58        }
59 
60        /**
61         * Automatically inject job-repository from a job into its steps. Only
62         * inject if the step is an AbstractStep or StepParserStepFactoryBean.
63         *
64         * @param beanName
65         * @param beanFactory
66         */
67        private void injectJobRepositoryIntoSteps(String beanName, ConfigurableListableBeanFactory beanFactory) {
68                BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
69                if (bd.hasAttribute(JOB_FACTORY_PROPERTY_NAME)) {
70                        MutablePropertyValues pvs = bd.getPropertyValues();
71                        if (beanFactory.isTypeMatch(beanName, AbstractStep.class)) {
72                                String jobName = (String) bd.getAttribute(JOB_FACTORY_PROPERTY_NAME);
73                                PropertyValue jobRepository = BeanDefinitionUtils.getPropertyValue(jobName,
74                                                JOB_REPOSITORY_PROPERTY_NAME, beanFactory);
75                                if (jobRepository != null) {
76                                        // Set the job's JobRepository onto the step
77                                        pvs.addPropertyValue(jobRepository);
78                                }
79                                else {
80                                        // No JobRepository found, so inject the default
81                                        RuntimeBeanReference jobRepositoryBeanRef = new RuntimeBeanReference(DEFAULT_JOB_REPOSITORY_NAME);
82                                        pvs.addPropertyValue(JOB_REPOSITORY_PROPERTY_NAME, jobRepositoryBeanRef);
83                                }
84                        }
85                }
86        }
87 
88        /**
89         * If any of the beans in the parent hierarchy is a <step/> with a
90         * <tasklet/>, then the bean class must be
91         * {@link StepParserStepFactoryBean}.
92         *
93         * @param beanName
94         * @param beanFactory
95         */
96        private void overrideStepClass(String beanName, ConfigurableListableBeanFactory beanFactory) {
97                BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
98                Object isNamespaceStep = BeanDefinitionUtils
99                                .getAttribute(beanName, "isNamespaceStep", beanFactory);
100                if (isNamespaceStep != null && (Boolean) isNamespaceStep == true) {
101                        ((AbstractBeanDefinition) bd).setBeanClass(StepParserStepFactoryBean.class);
102                }
103        }
104 
105        @Override
106        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
107                return injectDefaults(bean);
108        }
109 
110        /**
111         * Inject defaults into factory beans.
112         * <ul>
113         * <li>Inject "jobRepository" into any {@link JobParserJobFactoryBean}
114         * without a jobRepository.
115         * <li>Inject "transactionManager" into any
116         * {@link StepParserStepFactoryBean} without a transactionManager.
117         * </ul>
118         *
119         * @param bean
120         * @return
121         */
122        private Object injectDefaults(Object bean) {
123                if (bean instanceof JobParserJobFactoryBean) {
124                        JobParserJobFactoryBean fb = (JobParserJobFactoryBean) bean;
125                        JobRepository jobRepository = fb.getJobRepository();
126                        if (jobRepository == null) {
127                                fb.setJobRepository((JobRepository) applicationContext.getBean(DEFAULT_JOB_REPOSITORY_NAME));
128                        }
129                }
130                else if (bean instanceof StepParserStepFactoryBean) {
131                        StepParserStepFactoryBean<?, ?> fb = (StepParserStepFactoryBean<?, ?>) bean;
132                        JobRepository jobRepository = fb.getJobRepository();
133                        if (jobRepository == null) {
134                                fb.setJobRepository((JobRepository) applicationContext.getBean(DEFAULT_JOB_REPOSITORY_NAME));
135                        }
136                        PlatformTransactionManager transactionManager = fb.getTransactionManager();
137                        if (transactionManager == null && fb.requiresTransactionManager()) {
138                                fb.setTransactionManager((PlatformTransactionManager) applicationContext
139                                                .getBean(DEFAULT_TRANSACTION_MANAGER_NAME));
140                        }
141                }
142                return bean;
143        }
144 
145        @Override
146        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
147                return bean;
148        }
149 
150        @Override
151        public void setApplicationContext(ApplicationContext applicationContext) {
152                this.applicationContext = applicationContext;
153        }
154}

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