Remove property resolution through the original bean factory post processor and move resolution to

occur during XML pre-processing. JSR-352 allows for property replacement and expressions to be present
on any element and the preprocessing provides the ability to load a well formed XML document into the
context with the intended values already present.
This commit is contained in:
Chris Schaefer
2013-11-15 17:59:34 -05:00
parent 1f0d5496d1
commit e5fc0665cc
12 changed files with 732 additions and 343 deletions

View File

@@ -15,10 +15,9 @@
*/
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import java.io.Serializable;
import java.util.List;
import java.util.Properties;
import javax.batch.api.BatchProperty;
import javax.batch.api.Batchlet;
@@ -28,18 +27,15 @@ import javax.batch.api.chunk.ItemProcessor;
import javax.batch.api.chunk.ItemReader;
import javax.batch.api.chunk.ItemWriter;
import javax.batch.api.listener.StepListener;
import javax.batch.runtime.BatchStatus;
import javax.batch.runtime.JobExecution;
import javax.batch.runtime.context.JobContext;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.batch.core.jsr.JsrTestUtils;
import static junit.framework.Assert.assertEquals;
/**
* <p>
@@ -47,20 +43,18 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* </p>
*
* @author Chris Schaefer
* @since 3.0
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class JobPropertyTests {
@Autowired
private Job job;
@Autowired
private JobLauncher jobLauncher;
@Test
public void testJobPropertyConfiguration() throws Exception {
JobExecution jobExecution = jobLauncher.run(job, new JobParameters());
assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
Properties jobParameters = new Properties();
jobParameters.setProperty("allow.start.if.complete", "true");
jobParameters.setProperty("deciderName", "stepDecider");
jobParameters.setProperty("deciderNumber", "1");
JobExecution jobExecution = JsrTestUtils.runJob("jsrJobPropertyTests", jobParameters, 5000L);
assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
}
public static final class TestItemReader implements ItemReader {
@@ -74,7 +68,7 @@ public class JobPropertyTests {
@Inject @BatchProperty(name = "notDefinedAnnotationNamedProperty") String notDefinedAnnotationNamedProperty;
@Inject @BatchProperty String jobPropertyName1;
@Inject @BatchProperty String jobPropertyName2;
@Inject InjectTestObj injectAnnotatedOnlyField;
@Inject JobContext injectAnnotatedOnlyField;
@BatchProperty String batchAnnotatedOnlyField;
@Inject javax.batch.runtime.context.StepContext stepContext;
@@ -96,7 +90,7 @@ public class JobPropertyTests {
org.springframework.util.Assert.isNull(notDefinedAnnotationNamedProperty);
org.springframework.util.Assert.isNull(batchAnnotatedOnlyField);
org.springframework.util.Assert.notNull(injectAnnotatedOnlyField);
org.springframework.util.Assert.isTrue("Chris".equals(injectAnnotatedOnlyField.getName()));
org.springframework.util.Assert.isTrue("job1".equals(injectAnnotatedOnlyField.getJobName()));
org.springframework.util.Assert.isNull(readerPropertyName3);
}
@@ -272,16 +266,4 @@ public class JobPropertyTests {
public void stop() throws Exception {
}
}
public static class InjectTestObj {
private String name;
public InjectTestObj(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}

View File

@@ -0,0 +1,141 @@
package org.springframework.batch.core.jsr.configuration.xml;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.xml.DefaultDocumentLoader;
import org.springframework.beans.factory.xml.DelegatingEntityResolver;
import org.springframework.beans.factory.xml.DocumentLoader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.xml.SimpleSaxErrorHandler;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
/**
* <p>
* Test cases around {@link JsrBeanDefinitionDocumentReader}.
* </p>
*
* @author Chris Schaefer
*/
public class JsrBeanDefinitionDocumentReaderTests {
private static final String JOB_PARAMETERS_BEAN_DEFINITION_NAME = "jsr_jobParameters";
private Log logger = LogFactory.getLog(getClass());
private DocumentLoader documentLoader = new DefaultDocumentLoader();
private ErrorHandler errorHandler = new SimpleSaxErrorHandler(logger);
@Test
public void testGetJobParameters() {
Properties jobParameters = new Properties();
jobParameters.setProperty("jobParameter1", "jobParameter1Value");
jobParameters.setProperty("jobParameter2", "jobParameter2Value");
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(jobParameters);
applicationContext.setValidating(false);
applicationContext.load(new ClassPathResource("baseContext.xml"),
new ClassPathResource("/META-INF/batch.xml"),
new ClassPathResource("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml"));
applicationContext.refresh();
BeanDefinition beanDefinition = applicationContext.getBeanDefinition(JOB_PARAMETERS_BEAN_DEFINITION_NAME);
Properties processedJobParameters = (Properties) beanDefinition.getConstructorArgumentValues().getGenericArgumentValue(Properties.class).getValue();
assertNotNull(processedJobParameters);
assertTrue("Wrong number of job parameters", processedJobParameters.size() == 2);
assertEquals("jobParameter1Value", processedJobParameters.getProperty("jobParameter1"));
assertEquals("jobParameter2Value", processedJobParameters.getProperty("jobParameter2"));
}
@Test
public void testGetJobProperties() {
Document document = getDocument("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml");
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext();
JsrBeanDefinitionDocumentReader documentReader = new JsrBeanDefinitionDocumentReader(applicationContext);
documentReader.initProperties(document.getDocumentElement());
Properties documentJobProperties = documentReader.getJobProperties();
assertNotNull(documentJobProperties);
assertTrue("Wrong number of job properties", documentJobProperties.size() == 3);
assertEquals("jobProperty1Value", documentJobProperties.getProperty("jobProperty1"));
assertEquals("jobProperty1Value", documentJobProperties.getProperty("jobProperty2"));
assertEquals("", documentJobProperties.getProperty("jobProperty3"));
}
@Test
public void testJobParametersResolution() {
Properties jobParameters = new Properties();
jobParameters.setProperty("jobParameter1", "myfile.txt");
jobParameters.setProperty("jobParameter2", "#{jobProperties['jobProperty2']}");
jobParameters.setProperty("jobParameter3", "#{jobParameters['jobParameter1']}");
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(jobParameters);
applicationContext.setValidating(false);
applicationContext.load(new ClassPathResource("baseContext.xml"),
new ClassPathResource("/META-INF/batch.xml"),
new ClassPathResource("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml"));
applicationContext.refresh();
Document document = getDocument("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml");
JsrBeanDefinitionDocumentReader documentReader = new JsrBeanDefinitionDocumentReader(applicationContext);
documentReader.initProperties(document.getDocumentElement());
Properties resolvedParameters = documentReader.getJobParameters();
assertNotNull(resolvedParameters);
assertTrue("Wrong number of job parameters", resolvedParameters.size() == 3);
assertEquals("myfile.txt", resolvedParameters.getProperty("jobParameter1"));
assertEquals("jobProperty1Value", resolvedParameters.getProperty("jobParameter2"));
assertEquals("myfile.txt", resolvedParameters.getProperty("jobParameter3"));
}
@Test
public void testJobPropertyResolution() {
Properties jobParameters = new Properties();
jobParameters.setProperty("file.name", "myfile.txt");
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(jobParameters);
applicationContext.setValidating(false);
applicationContext.load(new ClassPathResource("baseContext.xml"),
new ClassPathResource("/META-INF/batch.xml"),
new ClassPathResource("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml"));
applicationContext.refresh();
Document document = getDocument("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml");
JsrBeanDefinitionDocumentReader documentReader = new JsrBeanDefinitionDocumentReader(applicationContext);
documentReader.initProperties(document.getDocumentElement());
Properties resolvedProperties = documentReader.getJobProperties();
assertNotNull(resolvedProperties);
assertTrue("Wrong number of job properties", resolvedProperties.size() == 3);
assertEquals("jobProperty1Value", resolvedProperties.getProperty("jobProperty1"));
assertEquals("jobProperty1Value", resolvedProperties.getProperty("jobProperty2"));
assertEquals("myfile.txt", resolvedProperties.getProperty("jobProperty3"));
}
private Document getDocument(String location) {
InputStream inputStream = ClassLoader.class.getResourceAsStream(location);
try {
return documentLoader.loadDocument(new InputSource(inputStream),
new DelegatingEntityResolver(getClass().getClassLoader()), errorHandler, 0, true);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
inputStream.close();
} catch (IOException e) { }
}
}
}

View File

@@ -0,0 +1,46 @@
package org.springframework.batch.core.jsr.configuration.xml;
import java.util.Properties;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
/**
* <p>
* Test cases around {@link JsrXmlApplicationContext}.
* </p>
*
* @author Chris Schaefer
*/
public class JsrXmlApplicationContextTests {
private static final String JOB_PARAMETERS_BEAN_DEFINITION_NAME = "jsr_jobParameters";
@Test
public void testNullProperties() {
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(null);
BeanDefinition beanDefinition = applicationContext.getBeanDefinition(JOB_PARAMETERS_BEAN_DEFINITION_NAME);
Properties properties = (Properties) beanDefinition.getConstructorArgumentValues().getGenericArgumentValue(Properties.class).getValue();
assertNotNull("Properties should not be null", properties);
assertTrue("Properties should be empty", properties.isEmpty());
}
@Test
public void testWithProperties() {
Properties properties = new Properties();
properties.put("prop1key", "prop1val");
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(properties);
BeanDefinition beanDefinition = applicationContext.getBeanDefinition(JOB_PARAMETERS_BEAN_DEFINITION_NAME);
Properties storedProperties = (Properties) beanDefinition.getConstructorArgumentValues().getGenericArgumentValue(Properties.class).getValue();
assertNotNull("Properties should not be null", storedProperties);
assertFalse("Properties not be empty", storedProperties.isEmpty());
assertEquals("prop1val", storedProperties.getProperty("prop1key"));
}
}