EMMA Coverage Report (generated Fri Aug 21 15:59:46 BST 2009)
[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% (153/153)100% (42/42)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CoreNamespacePostProcessor100% (1/1)100% (8/8)100% (153/153)100% (42/42)
CoreNamespacePostProcessor (): void 100% (1/1)100% (3/3)100% (1/1)
injectDefaults (Object): Object 100% (1/1)100% (51/51)100% (15/15)
injectJobRepositoryIntoSteps (String, ConfigurableListableBeanFactory): void 100% (1/1)100% (43/43)100% (12/12)
overrideStepClass (String, ConfigurableListableBeanFactory): void 100% (1/1)100% (20/20)100% (6/6)
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-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.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        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
53                for (String beanName : beanFactory.getBeanDefinitionNames()) {
54                        injectJobRepositoryIntoSteps(beanName, beanFactory);
55                        overrideStepClass(beanName, beanFactory);
56                }
57        }
58 
59        /**
60         * Automatically inject job-repository from a job into its steps. Only
61         * inject if the step is an AbstractStep or StepParserStepFactoryBean.
62         * 
63         * @param beanName
64         * @param beanFactory
65         */
66        private void injectJobRepositoryIntoSteps(String beanName, ConfigurableListableBeanFactory beanFactory) {
67                BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
68                if (bd.hasAttribute(JOB_FACTORY_PROPERTY_NAME)) {
69                        MutablePropertyValues pvs = (MutablePropertyValues) bd.getPropertyValues();
70                        if (beanFactory.isTypeMatch(beanName, AbstractStep.class)) {
71                                String jobName = (String) bd.getAttribute(JOB_FACTORY_PROPERTY_NAME);
72                                PropertyValue jobRepository = BeanDefinitionUtils.getPropertyValue(jobName,
73                                                JOB_REPOSITORY_PROPERTY_NAME, beanFactory);
74                                if (jobRepository != null) {
75                                        // Set the job's JobRepository onto the step
76                                        pvs.addPropertyValue(jobRepository);
77                                }
78                                else {
79                                        // No JobRepository found, so inject the default
80                                        RuntimeBeanReference jobRepositoryBeanRef = new RuntimeBeanReference(DEFAULT_JOB_REPOSITORY_NAME);
81                                        pvs.addPropertyValue(JOB_REPOSITORY_PROPERTY_NAME, jobRepositoryBeanRef);
82                                }
83                        }
84                }
85        }
86 
87        /**
88         * If any of the beans in the parent hierarchy is a <step/> with a
89         * <tasklet/>, then the bean class must be
90         * {@link StepParserStepFactoryBean}.
91         * 
92         * @param beanName
93         * @param beanFactory
94         */
95        private void overrideStepClass(String beanName, ConfigurableListableBeanFactory beanFactory) {
96                BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
97                Object isNamespaceStep = BeanDefinitionUtils
98                                .getAttribute(beanName, "isNamespaceStep", beanFactory);
99                if (isNamespaceStep != null && (Boolean) isNamespaceStep == true) {
100                        ((AbstractBeanDefinition) bd).setBeanClass(StepParserStepFactoryBean.class);
101                }
102        }
103 
104        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
105                return injectDefaults(bean);
106        }
107 
108        /**
109         * Inject defaults into factory beans.
110         * <ul>
111         * <li>Inject "jobRepository" into any {@link JobParserJobFactoryBean}
112         * without a jobRepository.
113         * <li>Inject "transactionManager" into any
114         * {@link StepParserStepFactoryBean} without a transactionManager.
115         * </ul>
116         * 
117         * @param bean
118         * @return
119         */
120        private Object injectDefaults(Object bean) {
121                if (bean instanceof JobParserJobFactoryBean) {
122                        JobParserJobFactoryBean fb = (JobParserJobFactoryBean) bean;
123                        JobRepository jobRepository = fb.getJobRepository();
124                        if (jobRepository == null) {
125                                fb.setJobRepository((JobRepository) applicationContext.getBean(DEFAULT_JOB_REPOSITORY_NAME));
126                        }
127                }
128                else if (bean instanceof StepParserStepFactoryBean) {
129                        StepParserStepFactoryBean<?, ?> fb = (StepParserStepFactoryBean<?, ?>) bean;
130                        JobRepository jobRepository = fb.getJobRepository();
131                        if (jobRepository == null) {
132                                fb.setJobRepository((JobRepository) applicationContext.getBean(DEFAULT_JOB_REPOSITORY_NAME));
133                        }
134                        PlatformTransactionManager transactionManager = fb.getTransactionManager();
135                        if (transactionManager == null) {
136                                fb.setTransactionManager((PlatformTransactionManager) applicationContext
137                                                .getBean(DEFAULT_TRANSACTION_MANAGER_NAME));
138                        }
139                }
140                return bean;
141        }
142 
143        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
144                return bean;
145        }
146 
147        public void setApplicationContext(ApplicationContext applicationContext) {
148                this.applicationContext = applicationContext;
149        }
150}

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