BATCH-1213: Added check in CoreNamespacePostProcessor to ensure that the parent of a <step/> does not have to be an AbstractStep

This commit is contained in:
dhgarrette
2009-05-20 23:47:49 +00:00
parent 9bdfdcbc43
commit 2c56a1b0c2
4 changed files with 132 additions and 12 deletions

View File

@@ -16,6 +16,7 @@
package org.springframework.batch.core.configuration.xml;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.AbstractStep;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
@@ -50,7 +51,8 @@ public class CoreNamespacePostProcessor implements BeanPostProcessor, BeanFactor
private ApplicationContext applicationContext;
/**
* Inject job-repository from a job into its steps.
* Automatically inject job-repository from a job into its steps. Only
* inject if the step is an AbstractStep or StepParserStepFactoryBean.
*
* @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
*/
@@ -59,30 +61,85 @@ public class CoreNamespacePostProcessor implements BeanPostProcessor, BeanFactor
BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
MutablePropertyValues pvs = (MutablePropertyValues) bd.getPropertyValues();
if (pvs.contains(JOB_FACTORY_PROPERTY_NAME)) {
String jobName = (String) pvs.getPropertyValue(JOB_FACTORY_PROPERTY_NAME).getValue();
PropertyValue jobRepository = getJobRepository(beanFactory, jobName);
if (jobRepository != null) {
pvs.addPropertyValue(jobRepository);
}
else {
RuntimeBeanReference jobRepositoryBeanRef = new RuntimeBeanReference(DEFAULT_JOB_REPOSITORY_NAME);
pvs.addPropertyValue(JOB_REPOSITORY_PROPERTY_NAME, jobRepositoryBeanRef);
if (isAbstractStep(bd, beanFactory)) {
String jobName = (String) pvs.getPropertyValue(JOB_FACTORY_PROPERTY_NAME).getValue();
PropertyValue jobRepository = getJobRepository(jobName, beanFactory);
if (jobRepository != null) {
// Set the job's JobRepository onto the step
pvs.addPropertyValue(jobRepository);
}
else {
// No JobRepository found, so inject the default
RuntimeBeanReference jobRepositoryBeanRef = new RuntimeBeanReference(
DEFAULT_JOB_REPOSITORY_NAME);
pvs.addPropertyValue(JOB_REPOSITORY_PROPERTY_NAME, jobRepositoryBeanRef);
}
}
pvs.removePropertyValue(JOB_FACTORY_PROPERTY_NAME);
}
}
}
private PropertyValue getJobRepository(ConfigurableListableBeanFactory beanFactory, String jobName) {
/**
* @param bd
* @param beanFactory
* @return TRUE if the bean represents an AbstractStep (or
* StepParserStepFactoryBean).
*/
private boolean isAbstractStep(BeanDefinition bd, ConfigurableListableBeanFactory beanFactory) {
Class<?> stepClass = getClass(bd, beanFactory);
return StepParserStepFactoryBean.class.isAssignableFrom(stepClass)
|| AbstractStep.class.isAssignableFrom(stepClass);
}
/**
* @param bd
* @param beanFactory
* @return The class of the bean. Search parent hierarchy if necessary.
* Return null if none is found.
*/
private Class<?> getClass(BeanDefinition bd, ConfigurableListableBeanFactory beanFactory) {
// Get the declared class of the bean
String className = bd.getBeanClassName();
if (StringUtils.hasText(className)) {
try {
return Class.forName(className);
}
catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
else {
// Search the parent until you find it
String parentName = bd.getParentName();
if (StringUtils.hasText(parentName)) {
return getClass(beanFactory.getBeanDefinition(parentName), beanFactory);
}
else {
return null;
}
}
}
/**
* @param jobName
* @param beanFactory
* @return The {@link PropertyValue} for the {@link JobRepository} of the
* bean. Search parent hierarchy if necessary. Return null if none
* is found.
*/
private PropertyValue getJobRepository(String jobName, ConfigurableListableBeanFactory beanFactory) {
BeanDefinition jobDef = beanFactory.getBeanDefinition(jobName);
PropertyValues jobDefPvs = jobDef.getPropertyValues();
if (jobDefPvs.contains(JOB_REPOSITORY_PROPERTY_NAME)) {
// return the job repository property
return jobDefPvs.getPropertyValue(JOB_REPOSITORY_PROPERTY_NAME);
}
else {
// Search the parent until you find it
String parentName = jobDef.getParentName();
if (StringUtils.hasText(parentName)) {
return getJobRepository(beanFactory, parentName);
return getJobRepository(parentName, beanFactory);
}
else {
return null;

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2006-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.configuration.xml;
import org.springframework.batch.core.JobInterruptedException;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.beans.factory.BeanNameAware;
/**
* @author Dan Garrette
* @since 2.0.1
*/
public class DummyStep implements Step, BeanNameAware {
private String name;
public String getName() {
return name;
}
public void setBeanName(String name) {
this.name = name;
}
public void execute(StepExecution stepExecution) throws JobInterruptedException {
System.out.println("EXECUTING " + getName());
}
public int getStartLimit() {
return 100;
}
public boolean isAllowStartIfComplete() {
return false;
}
}

View File

@@ -308,4 +308,14 @@ public class StepParserTests {
}
return property;
}
@Test
public void testNonAbstractStep() {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"org/springframework/batch/core/configuration/xml/StepParserParentAttributeTests-context.xml");
assertTrue(ctx.containsBean("s11"));
Object bean = ctx.getBean("s11");
assertTrue(bean instanceof DummyStep);
}
}

View File

@@ -34,7 +34,8 @@
</step>
<step id="s8" parent="standalone8" next="s9" />
<step id="s9" parent="standalone9" next="s10" />
<step id="s10" parent="standalone10" />
<step id="s10" parent="standalone10" next="s11"/>
<step id="s11" parent="dummyStep" />
</job>
<step id="standalone2" parent="baseStep">
@@ -84,6 +85,8 @@
</tasklet>
</step>
<beans:bean id="dummyStep" class="org.springframework.batch.core.configuration.xml.DummyStep"/>
<job id="jobWithoutRepo">
<step id="defaultRepoStep"><tasklet ref="dummyTasklet"/></step>
<step id="defaultRepoStepWithParent" parent="defaultRepoStandaloneStep"><tasklet ref="dummyTasklet"/></step>