BATCH-2127: Refactor JSR Properties for outside of parsing use cases

* Main cleanups in BatchPropertyContext/PropertyParser, get rid of BatchPropertyContextEntry
This commit is contained in:
Chris Schaefer
2014-02-22 12:48:37 -05:00
committed by Michael Minella
parent be430126b5
commit 319c751432
9 changed files with 252 additions and 337 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2014 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.
@@ -16,7 +16,6 @@
package org.springframework.batch.core.jsr.configuration.support;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -35,6 +34,7 @@ import org.springframework.util.Assert;
*/
public class BatchPropertyContext {
private static final String PARTITION_INDICATOR = ":partition";
private Properties jobProperties = new Properties();
private Map<String, Properties> stepProperties = new HashMap<String, Properties>();
private Map<String, Properties> artifactProperties = new HashMap<String, Properties>();
@@ -51,6 +51,18 @@ public class BatchPropertyContext {
return jobProperties;
}
/**
* <p>
* Adds Job level properties to the context.
* </p>
*
* @param properties the job {@link Properties} to add
*/
public void setJobProperties(Properties properties) {
Assert.notNull(properties, "Job properties cannot be null");
this.jobProperties.putAll(properties);
}
/**
* <p>
* Obtains the Step level properties for the provided Step name.
@@ -60,6 +72,7 @@ public class BatchPropertyContext {
* @return the {@link Properties} for the Step
*/
public Properties getStepProperties(String stepName) {
Assert.hasText(stepName, "Step name must be provided");
Properties properties = new Properties();
if(stepProperties.containsKey(stepName)) {
@@ -74,6 +87,51 @@ public class BatchPropertyContext {
return properties;
}
/**
* <p>
* Adds Step level properties to the context.
* </p>
*
* @param properties the step {@link Properties} to add
*/
public void setStepProperties(Map<String, Properties> properties) {
Assert.notNull(properties, "Step properties cannot be null");
for(Map.Entry<String, Properties> propertiesEntry : properties.entrySet()) {
String stepName = propertiesEntry.getKey();
if (!propertiesEntry.getValue().isEmpty()) {
if (this.stepProperties.containsKey(stepName)) {
Properties existingStepProperties = this.stepProperties.get(stepName);
existingStepProperties.putAll(propertiesEntry.getValue());
this.stepProperties.put(stepName, existingStepProperties);
} else {
this.stepProperties.put(stepName, propertiesEntry.getValue());
}
}
}
}
/**
* <p>
* Convenience method to set step level properties. Simply wraps the provided parameters
* and delegates to {@link #setStepProperties(java.util.Map)}.
* </p>
*
* @param stepName the step name to set {@link Properties} for
* @param properties the {@link Properties} to set
*/
public void setStepProperties(String stepName, Properties properties) {
Assert.hasText(stepName, "Step name must be provided");
Assert.notNull(properties, "Step properties must not be null");
Map<String, Properties> stepProperties = new HashMap<String, Properties>();
stepProperties.put(stepName, properties);
setStepProperties(stepProperties);
}
/**
* <p>
* Obtains the batch {@link Properties} for the provided artifact name. The returned {@link Properties}
@@ -95,6 +153,26 @@ public class BatchPropertyContext {
return properties;
}
/**
* <p>
* Adds non-step artifact properties to the context.
* </p>
*
* @param properties the artifact {@link Properties} to add
*/
public void setArtifactProperties(Map<String, Properties> properties) {
Assert.notNull(properties, "Step properties cannot be null");
for(Map.Entry<String, Properties> propertiesEntry : properties.entrySet()) {
String artifactName = propertiesEntry.getKey();
Properties artifactProperties = propertiesEntry.getValue();
if(!artifactProperties.isEmpty()) {
this.artifactProperties.put(artifactName, artifactProperties);
}
}
}
/**
* <p>
* Obtains the batch {@link Properties} for the provided Step and artifact name.
@@ -131,207 +209,31 @@ public class BatchPropertyContext {
/**
* <p>
* Adds Job level properties to the context.
* Adds Step artifact properties to the context.
* </p>
*
* @param batchPropertyContextEntries the {@link BatchPropertyContextEntry} objects to add
* @param properties the step artifact {@link Properties} to add
*/
public void setJobPropertiesContextEntry(List<BatchPropertyContextEntry> batchPropertyContextEntries) {
for(BatchPropertyContextEntry batchPropertyContextEntry : batchPropertyContextEntries) {
Properties jobProperties = batchPropertyContextEntry.getProperties();
public void setStepArtifactProperties(Map<String, Map<String, Properties>> properties) {
Assert.notNull(properties, "Step artifact properties cannot be null");
if (jobProperties != null && !jobProperties.isEmpty()) {
this.jobProperties.putAll(jobProperties);
}
}
}
for(Map.Entry<String, Map<String, Properties>> propertyEntries : properties.entrySet()) {
String stepName = propertyEntries.getKey();
/**
* <p>
* Adds Step level properties to the context.
* </p>
*
* @param batchPropertyContextEntries the {@link BatchPropertyContextEntry} objects to add
*/
public void setStepPropertiesContextEntry(List<BatchPropertyContextEntry> batchPropertyContextEntries) {
for (BatchPropertyContextEntry batchPropertyContextEntry : batchPropertyContextEntries) {
Assert.hasText(batchPropertyContextEntry.getArtifactName(), "Step name must be defined as the artifact name.");
for(Map.Entry<String, Properties> artifactEntries : propertyEntries.getValue().entrySet()) {
final String artifactName = artifactEntries.getKey();
final Properties props = artifactEntries.getValue();
String stepName = batchPropertyContextEntry.getArtifactName();
Properties stepProperties = batchPropertyContextEntry.getProperties();
if (stepProperties != null && ! stepProperties.isEmpty()) {
if (this.stepProperties.containsKey(stepName)) {
Properties existingStepProperties = this.stepProperties.get(stepName);
existingStepProperties.putAll(stepProperties);
this.stepProperties.put(stepName, existingStepProperties);
} else {
this.stepProperties.put(stepName, stepProperties);
}
}
}
}
/**
* <p>
* Adds non-Step scoped artifact properties to the context.
* </p>
*
* @param batchPropertyContextEntries the {@link BatchPropertyContextEntry} objects to add
*/
public void setArtifactPropertiesContextEntry(List<BatchPropertyContextEntry> batchPropertyContextEntries) {
for (BatchPropertyContextEntry batchPropertyContextEntry : batchPropertyContextEntries) {
Assert.hasText(batchPropertyContextEntry.getArtifactName(), "Artifact name must be defined");
Properties properties = batchPropertyContextEntry.getProperties();
String artifactName = batchPropertyContextEntry.getArtifactName();
if (properties != null && !properties.isEmpty()) {
artifactProperties.put(artifactName, properties);
}
}
}
/**
* <p>
* Adds Step scoped artifact properties to the context.
* </p>
*
* @param batchPropertyContextEntries the {@link BatchPropertyContextEntry} objects to add
*/
@SuppressWarnings("serial")
public void setStepArtifactPropertiesContextEntry(List<BatchPropertyContextEntry> batchPropertyContextEntries) {
for (BatchPropertyContextEntry batchPropertyContextEntry : batchPropertyContextEntries) {
Assert.hasText(batchPropertyContextEntry.getStepName(), "Step name must be defined");
Assert.hasText(batchPropertyContextEntry.getArtifactName(), "Artifact name must be defined");
String stepName = batchPropertyContextEntry.getStepName();
final String artifactName = batchPropertyContextEntry.getArtifactName();
final Properties properties = batchPropertyContextEntry.getProperties();
if (!properties.isEmpty()) {
Map<String, Properties> artifactProperties = stepArtifactProperties.get(stepName);
if (artifactProperties == null) {
stepArtifactProperties.put(stepName, new HashMap<String, Properties>() {{
put(artifactName, properties);
put(artifactName, props);
}});
} else {
artifactProperties.put(artifactName, properties);
artifactProperties.put(artifactName, props);
}
}
}
}
/**
* <p>
* Obtains the property to be used when setting data for the provided {@link BatchArtifact.BatchArtifactType}.
* </p>
*
* @param batchArtifactType the {@link BatchArtifact.BatchArtifactType} to lookup the property name for
* @return the property name for
* @throws IllegalStateException if an unhandled {@link BatchArtifact.BatchArtifactType} is encountered
*/
public String getPropertyName(BatchArtifact.BatchArtifactType batchArtifactType) {
switch (batchArtifactType) {
case STEP:
return "stepPropertiesContextEntry";
case STEP_ARTIFACT:
return "stepArtifactPropertiesContextEntry";
case ARTIFACT:
return "artifactPropertiesContextEntry";
case JOB:
return "jobPropertiesContextEntry";
default:
throw new IllegalStateException("Unhandled BatchArtifactType of: " + batchArtifactType);
}
}
/**
* <p>
* Simple object to encapsulate batch properties of a given batch artifact.
* </p>
*
* @author Chris Schaefer
* @since 3.0
*/
public class BatchPropertyContextEntry {
private String stepName;
private String artifactName;
private Properties properties;
private BatchArtifact.BatchArtifactType batchArtifactType;
/**
* <p>
* Creates a new entry instance using the provided bean name representing batch artifact
* and its associated {@link Properties}.
* </p>
*
* @param artifactName the name representing the batch artifact
* @param properties the associated {@link Properties}
* @param batchArtifactType the associated {@link BatchArtifact.BatchArtifactType}
*/
public BatchPropertyContextEntry(String artifactName, Properties properties, BatchArtifact.BatchArtifactType batchArtifactType) {
this.artifactName = artifactName;
this.batchArtifactType = batchArtifactType;
this.properties = properties != null ? properties : new Properties();
}
/**
* <p>
* Obtains the name of the batch artifact this entry is associated with.
* </p>
*
* @return the name of the batch artifact
*/
public String getArtifactName() {
return artifactName;
}
/**
* <p>
* Obtains the batch {@link Properties} that are associated with this entry.
* </p>
*
* @return the batch {@link Properties}
*/
public Properties getProperties() {
return properties;
}
/**
* <p>
* Obtains the {@link BatchArtifact.BatchArtifactType} represented by this context entry.
* </p>
*
* @return the {@link BatchArtifact.BatchArtifactType}
*/
public BatchArtifact.BatchArtifactType getBatchArtifactType() {
return batchArtifactType;
}
/**
* <p>
* Sets the Step name associated with this entry.
* </p>
*
* @param stepName the Step name associated with this entry
*/
public void setStepName(String stepName) {
this.stepName = stepName;
}
/**
* <p>
* Obtains the Step name associated with this entry.
* </p>
*
* @return the step name associated with this entry
*/
public String getStepName() {
return stepName;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2014 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.
@@ -39,6 +39,8 @@ class JsrNamespaceUtils {
private static final String BATCH_PROPERTY_POST_PROCESSOR_BEAN_NAME = "batchPropertyPostProcessor";
private static final String THREAD_LOCAL_CLASS_LOADER_BEAN_POST_PROCESSOR_BEAN_NAME = "threadLocalClassloaderBeanPostProcessor";
private static final String BEAN_SCOPE_POST_PROCESSOR_BEAN_NAME = "beanScopeBeanPostProcessor";
private static final String BATCH_PROPERTY_CONTEXT_BEAN_CLASS_NAME = "org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext";
private static final String BATCH_PROPERTY_CONTEXT_BEAN_NAME = "batchPropertyContext";
static void autoregisterJsrBeansForNamespace(ParserContext parserContext) {
autoRegisterJobProperties(parserContext);
@@ -46,6 +48,7 @@ class JsrNamespaceUtils {
autoRegisterJsrAutowiredAnnotationBeanPostProcessor(parserContext);
autoRegisterThreadLocalClassloaderBeanPostProcessor(parserContext);
autoRegisterBeanScopeBeanFactoryPostProcessor(parserContext);
autoRegisterBatchPropertyContext(parserContext);
}
private static void autoRegisterBeanScopeBeanFactoryPostProcessor(
@@ -84,4 +87,16 @@ class JsrNamespaceUtils {
parserContext.getRegistry().registerBeanDefinition(JOB_PROPERTIES_BEAN_NAME, jobPropertiesBeanDefinition);
}
}
private static void autoRegisterBatchPropertyContext(ParserContext parserContext) {
if (!parserContext.getRegistry().containsBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_NAME)) {
AbstractBeanDefinition batchPropertyContextBeanDefinition =
BeanDefinitionBuilder.genericBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_CLASS_NAME)
.getBeanDefinition();
batchPropertyContextBeanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
parserContext.getRegistry().registerBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_NAME, batchPropertyContextBeanDefinition);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2014 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.
@@ -174,7 +174,7 @@ public class PartitionParser {
if(partitionProperties != null) {
for (Element partition : partitionProperties) {
String partitionStepName = stepName + ":partition" + partition.getAttribute("partition");
new PropertyParser(partitionStepName, parserContext, BatchArtifactType.STEP).parsePartitionProperties(partition);
new PropertyParser(partitionStepName, parserContext, BatchArtifactType.STEP, partitionStepName).parseProperty(partition);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2014 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.
@@ -15,20 +15,15 @@
*/
package org.springframework.batch.core.jsr.configuration.xml;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.springframework.batch.core.jsr.configuration.support.BatchArtifact;
import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
@@ -41,15 +36,18 @@ import org.w3c.dom.Element;
* @since 3.0
*/
public class PropertyParser {
private static final String PROPERTY_ELEMENT = "property";
private static final String PROPERTIES_ELEMENT = "properties";
private static final String PROPERTY_NAME_ATTRIBUTE = "name";
private static final String PROPERTY_VALUE_ATTRIBUTE = "value";
private static final String JOB_PROPERTIES_BEAN_NAME = "jobProperties";
private static final String BATCH_PROPERTY_CONTEXT_BEAN_CLASS_NAME = "org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext";
private static final String BATCH_PROPERTY_CONTEXT_BEAN_NAME = "batchPropertyContext";
private static final String PROPERTY_ELEMENT = "property";
private static final String PROPERTIES_ELEMENT = "properties";
private static final String PROPERTY_NAME_ATTRIBUTE = "name";
private static final String PROPERTY_VALUE_ATTRIBUTE = "value";
private static final String JOB_PROPERTIES_BEAN_NAME = "jobProperties";
private static final String BATCH_PROPERTY_CONTEXT_BEAN_NAME = "batchPropertyContext";
private static final String JOB_PROPERTIES_PROPERTY_NAME = "jobProperties";
private static final String STEP_PROPERTIES_PROPERTY_NAME = "stepProperties";
private static final String ARTIFACT_PROPERTIES_PROPERTY_NAME = "artifactProperties";
private static final String STEP_ARTIFACT_PROPERTIES_PROPERTY_NAME = "stepArtifactProperties";
private String beanName;
private String beanName;
private String stepName;
private ParserContext parserContext;
private BatchArtifact.BatchArtifactType batchArtifactType;
@@ -58,8 +56,6 @@ public class PropertyParser {
this.beanName = beanName;
this.parserContext = parserContext;
this.batchArtifactType = batchArtifactType;
registerBatchPropertyContext();
}
public PropertyParser(String beanName, ParserContext parserContext, BatchArtifact.BatchArtifactType batchArtifactType, String stepName) {
@@ -79,86 +75,98 @@ public class PropertyParser {
public void parseProperties(Element element) {
List<Element> propertiesElements = DomUtils.getChildElementsByTagName(element, PROPERTIES_ELEMENT);
Properties properties = new Properties();
if (propertiesElements.size() == 1) {
parsePropertiesElement(propertiesElements, properties);
parsePropertyElement(propertiesElements.get(0));
} else if (propertiesElements.size() > 1) {
parserContext.getReaderContext().error("The <properties> element may not appear more than once in a single <listener>.", element);
parserContext.getReaderContext().error("The <properties> element may not appear more than once.", element);
}
setJobProperties(properties);
}
public void parsePartitionProperties(Element element) {
/**
* <p>
* Parses a &lt;property&gt; tag value from the provided {@link Element}. &lt;property&gt; elements have a name and
* value attribute which represent the property entries key and value.
* </p>
*
* @param element the element to parse looking for &lt;property/&gt;
*/
public void parseProperty(Element element) {
parsePropertyElement(element);
}
private void parsePropertyElement(Element propertyElement) {
Properties properties = new Properties();
List<Element> elements = new ArrayList<Element>();
elements.add(element);
parsePropertiesElement(elements, properties);
setJobProperties(properties);
}
private void parsePropertiesElement(List<Element> propertiesElements, Properties properties) {
List<Element> propertyElements = DomUtils.getChildElementsByTagName(propertiesElements.get(0), PROPERTY_ELEMENT);
for (Element propertyElement : propertyElements) {
properties.put(propertyElement.getAttribute(PROPERTY_NAME_ATTRIBUTE), propertyElement.getAttribute(PROPERTY_VALUE_ATTRIBUTE));
for (Element element : DomUtils.getChildElementsByTagName(propertyElement, PROPERTY_ELEMENT)) {
properties.put(element.getAttribute(PROPERTY_NAME_ATTRIBUTE), element.getAttribute(PROPERTY_VALUE_ATTRIBUTE));
}
addProperties(properties);
setProperties(properties);
setJobPropertiesBean(properties);
}
private void addProperties(Properties properties) {
@SuppressWarnings("unchecked")
private void setProperties(Properties properties) {
Object propertyValue;
BeanDefinition beanDefinition = parserContext.getRegistry().getBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_NAME);
BatchPropertyContext batchPropertyContext = new BatchPropertyContext();
BatchPropertyContext.BatchPropertyContextEntry batchPropertyContextEntry =
batchPropertyContext.new BatchPropertyContextEntry(beanName, properties, batchArtifactType);
if (StringUtils.hasText(stepName)) {
batchPropertyContextEntry.setStepName(stepName);
if(batchArtifactType.equals(BatchArtifact.BatchArtifactType.JOB)) {
propertyValue = getJobProperties(properties);
} else if (batchArtifactType.equals(BatchArtifact.BatchArtifactType.STEP)) {
propertyValue = getProperties(stepName, properties);
} else if (batchArtifactType.equals(BatchArtifact.BatchArtifactType.ARTIFACT)) {
propertyValue = getProperties(beanName, properties);
} else if (batchArtifactType.equals(BatchArtifact.BatchArtifactType.STEP_ARTIFACT)) {
propertyValue = getStepArtifactProperties(beanDefinition, properties);
} else {
throw new IllegalStateException("Unhandled BatchArtifactType of: " + batchArtifactType);
}
ManagedList<BatchPropertyContext.BatchPropertyContextEntry> managedList = new ManagedList<BatchPropertyContext.BatchPropertyContextEntry>();
managedList.setMergeEnabled(true);
managedList.add(batchPropertyContextEntry);
beanDefinition.getPropertyValues().addPropertyValue(batchPropertyContext.getPropertyName(batchArtifactType), managedList);
beanDefinition.getPropertyValues().addPropertyValue(getPropertyName(batchArtifactType), propertyValue);
}
private void registerBatchPropertyContext() {
if (!parserContext.getRegistry().containsBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_NAME)) {
BeanDefinitionBuilder batchPropertyContextBeanDefinitionBuilder =
BeanDefinitionBuilder.genericBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_CLASS_NAME);
private Map<String, Properties> getProperties(String keyName, Properties properties) {
ManagedMap<String, Properties> stepProperties = new ManagedMap<String, Properties>();
stepProperties.setMergeEnabled(true);
stepProperties.put(keyName, properties);
AbstractBeanDefinition batchPropertyContextBeanDefinition = batchPropertyContextBeanDefinitionBuilder.getBeanDefinition();
batchPropertyContextBeanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
return stepProperties;
}
parserContext.getRegistry().registerBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_NAME, batchPropertyContextBeanDefinition);
private Properties getJobProperties(Properties properties) {
return properties;
}
@SuppressWarnings("unchecked")
private Map<String, Map<String, Properties>> getStepArtifactProperties(BeanDefinition beanDefinition, Properties properties) {
ManagedMap<String, Map<String, Properties>> stepArtifacts = new ManagedMap<String, Map<String, Properties>>();
stepArtifacts.setMergeEnabled(true);
Map<String, Map<String, Properties>> existingArtifacts
= (Map<String, Map<String, Properties>>) beanDefinition.getPropertyValues().get(getPropertyName(batchArtifactType));
ManagedMap<String, Properties> artifactProperties = new ManagedMap<String, Properties>();
artifactProperties.setMergeEnabled(true);
if(existingArtifacts != null && existingArtifacts.containsKey(stepName)) {
Map<String, Properties> existingArtifactsMap = existingArtifacts.get(stepName);
for(Map.Entry<String, Properties> existingArtifactEntry : existingArtifactsMap.entrySet()) {
artifactProperties.put(existingArtifactEntry.getKey(), existingArtifactEntry.getValue());
}
}
artifactProperties.put(beanName, properties);
stepArtifacts.put(stepName, artifactProperties);
return stepArtifacts;
}
private void setJobProperties(Properties properties) {
if (batchArtifactType.equals(BatchArtifact.BatchArtifactType.JOB)) {
BeanDefinition beanDefinition = parserContext.getRegistry().getBeanDefinition(BATCH_PROPERTY_CONTEXT_BEAN_NAME);
BatchPropertyContext batchPropertyContext = new BatchPropertyContext();
BatchPropertyContext.BatchPropertyContextEntry batchPropertyContextEntry =
batchPropertyContext.new BatchPropertyContextEntry(beanName, properties, batchArtifactType);
beanDefinition.getPropertyValues().addPropertyValue(batchPropertyContext.getPropertyName(batchArtifactType), batchPropertyContextEntry);
registerJobProperties(properties);
}
}
private void registerJobProperties(Properties properties) {
private void setJobPropertiesBean(Properties properties) {
if (batchArtifactType.equals(BatchArtifact.BatchArtifactType.JOB)) {
Map<String, String> jobProperties = new HashMap<String, String>();
if (properties != null && ! properties.isEmpty()) {
if (properties != null && !properties.isEmpty()) {
for (String param : properties.stringPropertyNames()) {
jobProperties.put(param, properties.getProperty(param));
}
@@ -168,4 +176,18 @@ public class PropertyParser {
jobPropertiesBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(jobProperties);
}
}
private String getPropertyName(BatchArtifact.BatchArtifactType batchArtifactType) {
if(batchArtifactType.equals(BatchArtifact.BatchArtifactType.JOB)) {
return JOB_PROPERTIES_PROPERTY_NAME;
} else if (batchArtifactType.equals(BatchArtifact.BatchArtifactType.STEP)) {
return STEP_PROPERTIES_PROPERTY_NAME;
} else if (batchArtifactType.equals(BatchArtifact.BatchArtifactType.ARTIFACT)) {
return ARTIFACT_PROPERTIES_PROPERTY_NAME;
} else if (batchArtifactType.equals(BatchArtifact.BatchArtifactType.STEP_ARTIFACT)) {
return STEP_ARTIFACT_PROPERTIES_PROPERTY_NAME;
} else {
throw new IllegalStateException("Unhandled BatchArtifactType of: " + batchArtifactType);
}
}
}

View File

@@ -76,7 +76,7 @@ public class StepParser extends AbstractSingleBeanDefinitionParser {
}
new ListenerParser(StepListenerFactoryBean.class, "listeners").parseListeners(element, parserContext, bd, stepName);
new PropertyParser(stepName, parserContext, BatchArtifact.BatchArtifactType.STEP).parseProperties(element);
new PropertyParser(stepName, parserContext, BatchArtifact.BatchArtifactType.STEP, stepName).parseProperties(element);
// look at all nested elements
NodeList children = element.getChildNodes();

View File

@@ -40,9 +40,7 @@ import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecutionException;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.jsr.configuration.support.BatchArtifact.BatchArtifactType;
import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext;
import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext.BatchPropertyContextEntry;
import org.springframework.batch.core.partition.JsrStepExecutionSplitter;
import org.springframework.batch.core.partition.PartitionHandler;
import org.springframework.batch.core.partition.StepExecutionSplitter;
@@ -343,11 +341,7 @@ public class JsrPartitionHandler implements PartitionHandler, InitializingBean {
if(i < partitionProperties.length) {
Properties partitionPropertyValues = partitionProperties[i];
if(partitionPropertyValues != null) {
List<BatchPropertyContextEntry> entries = new ArrayList<BatchPropertyContext.BatchPropertyContextEntry>();
BatchPropertyContextEntry entry = propertyContext.new BatchPropertyContextEntry(curExecution.getStepName(), partitionPropertyValues, BatchArtifactType.STEP);
entries.add(entry);
propertyContext.setStepPropertiesContextEntry(entries);
propertyContext.setStepProperties(curExecution.getStepName(), partitionPropertyValues);
}
i++;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2014 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.
@@ -17,9 +17,8 @@ package org.springframework.batch.core.jsr.configuration.support;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.junit.Before;
@@ -33,72 +32,64 @@ import org.junit.Test;
* @author Chris Schaefer
*/
public class BatchPropertyContextTests {
private List<BatchPropertyContext.BatchPropertyContextEntry> jobProperties = new ArrayList<BatchPropertyContext.BatchPropertyContextEntry>();
private List<BatchPropertyContext.BatchPropertyContextEntry> stepProperties = new ArrayList<BatchPropertyContext.BatchPropertyContextEntry>();
private List<BatchPropertyContext.BatchPropertyContextEntry> artifactProperties = new ArrayList<BatchPropertyContext.BatchPropertyContextEntry>();
private List<BatchPropertyContext.BatchPropertyContextEntry> stepArtifactProperties = new ArrayList<BatchPropertyContext.BatchPropertyContextEntry>();
private List<BatchPropertyContext.BatchPropertyContextEntry> partitionProperties = new ArrayList<BatchPropertyContext.BatchPropertyContextEntry>();
private Properties jobProperties = new Properties();
private Map<String, Properties> stepProperties = new HashMap<String, Properties>();
private Map<String, Properties> artifactProperties = new HashMap<String, Properties>();
private Map<String, Map<String, Properties>> partitionProperties = new HashMap<String, Map<String, Properties>>();
private Map<String, Map<String, Properties>> stepArtifactProperties = new HashMap<String, Map<String, Properties>>();
@Before
public void setUp() {
BatchPropertyContext batchPropertyContext = new BatchPropertyContext();
Properties step1Properties = new Properties();
step1Properties.setProperty("step1PropertyName1", "step1PropertyValue1");
step1Properties.setProperty("step1PropertyName2", "step1PropertyValue2");
stepProperties.add(batchPropertyContext.new BatchPropertyContextEntry("step1", step1Properties, BatchArtifact.BatchArtifactType.STEP));
this.stepProperties.put("step1", step1Properties);
Properties step2Properties = new Properties();
step2Properties.setProperty("step2PropertyName1", "step2PropertyValue1");
step2Properties.setProperty("step2PropertyName2", "step2PropertyValue2");
stepProperties.add(batchPropertyContext.new BatchPropertyContextEntry("step2", step2Properties, BatchArtifact.BatchArtifactType.STEP));
this.stepProperties.put("step2", step2Properties);
Properties jobProperties = new Properties();
jobProperties.setProperty("jobProperty1", "jobProperty1value");
jobProperties.setProperty("jobProperty2", "jobProperty2value");
this.jobProperties.add(batchPropertyContext.new BatchPropertyContextEntry("job1", jobProperties, BatchArtifact.BatchArtifactType.JOB));
this.jobProperties.putAll(jobProperties);
Properties artifactProperties = new Properties();
artifactProperties.setProperty("deciderProperty1", "deciderProperty1value");
artifactProperties.setProperty("deciderProperty2", "deciderProperty2value");
this.artifactProperties.add(batchPropertyContext.new BatchPropertyContextEntry("decider1", artifactProperties, BatchArtifact.BatchArtifactType.ARTIFACT));
this.artifactProperties.put("decider1", artifactProperties);
Properties stepArtifactProperties = new Properties();
final Properties stepArtifactProperties = new Properties();
stepArtifactProperties.setProperty("readerProperty1", "readerProperty1value");
stepArtifactProperties.setProperty("readerProperty2", "readerProperty2value");
BatchPropertyContext.BatchPropertyContextEntry batchPropertyContextEntry =
batchPropertyContext.new BatchPropertyContextEntry("reader", stepArtifactProperties, BatchArtifact.BatchArtifactType.STEP_ARTIFACT);
batchPropertyContextEntry.setStepName("step1");
this.stepArtifactProperties.put("step1", new HashMap<String, Properties>() {{
put("reader", stepArtifactProperties);
}});
this.stepArtifactProperties.add(batchPropertyContextEntry);
Properties partitionProperties = new Properties();
final Properties partitionProperties = new Properties();
partitionProperties.setProperty("writerProperty1", "writerProperty1valuePartition0");
partitionProperties.setProperty("writerProperty2", "writerProperty2valuePartition0");
BatchPropertyContext.BatchPropertyContextEntry partitionBatchPropertyContextEntry =
batchPropertyContext.new BatchPropertyContextEntry("writer", partitionProperties, BatchArtifact.BatchArtifactType.STEP_ARTIFACT);
partitionBatchPropertyContextEntry.setStepName("step2:partition0");
this.partitionProperties.put("step2:partition0", new HashMap<String, Properties>() {{
put("writer", partitionProperties);
}});
this.partitionProperties.add(partitionBatchPropertyContextEntry);
Properties partitionStepProperties = new Properties();
final Properties partitionStepProperties = new Properties();
partitionStepProperties.setProperty("writerProperty1Step", "writerProperty1");
partitionStepProperties.setProperty("writerProperty2Step", "writerProperty2");
BatchPropertyContext.BatchPropertyContextEntry partitionStepBatchPropertyContextEntry =
batchPropertyContext.new BatchPropertyContextEntry("writer", partitionStepProperties, BatchArtifact.BatchArtifactType.STEP_ARTIFACT);
partitionStepBatchPropertyContextEntry.setStepName("step2");
this.partitionProperties.add(partitionStepBatchPropertyContextEntry);
this.partitionProperties.put("step2", new HashMap<String, Properties>() {{
put("writer", partitionStepProperties);
}});
}
@Test
public void testStepLevelProperties() {
BatchPropertyContext batchPropertyContext = new BatchPropertyContext();
batchPropertyContext.setJobPropertiesContextEntry(jobProperties);
batchPropertyContext.setStepPropertiesContextEntry(stepProperties);
batchPropertyContext.setJobProperties(jobProperties);
batchPropertyContext.setStepProperties(stepProperties);
Properties step1Properties = batchPropertyContext.getStepProperties("step1");
assertEquals(2, step1Properties.size());
@@ -114,7 +105,7 @@ public class BatchPropertyContextTests {
@Test
public void testJobLevelProperties() {
BatchPropertyContext batchPropertyContext = new BatchPropertyContext();
batchPropertyContext.setJobPropertiesContextEntry(jobProperties);
batchPropertyContext.setJobProperties(jobProperties);
Properties jobProperties = batchPropertyContext.getJobProperties();
assertEquals(2, jobProperties.size());
@@ -125,8 +116,8 @@ public class BatchPropertyContextTests {
@Test
public void testAddPropertiesToExistingStep() {
BatchPropertyContext batchPropertyContext = new BatchPropertyContext();
batchPropertyContext.setJobPropertiesContextEntry(jobProperties);
batchPropertyContext.setStepPropertiesContextEntry(stepProperties);
batchPropertyContext.setJobProperties(jobProperties);
batchPropertyContext.setStepProperties(stepProperties);
Properties step1 = batchPropertyContext.getStepProperties("step1");
assertEquals(2, step1.size());
@@ -136,8 +127,7 @@ public class BatchPropertyContextTests {
Properties step1properties = new Properties();
step1properties.setProperty("newStep1PropertyName", "newStep1PropertyValue");
batchPropertyContext.setStepPropertiesContextEntry(
Collections.singletonList(batchPropertyContext.new BatchPropertyContextEntry("step1", step1properties, BatchArtifact.BatchArtifactType.STEP)));
batchPropertyContext.setStepProperties("step1", step1properties);
Properties step1updated = batchPropertyContext.getStepProperties("step1");
assertEquals(3, step1updated.size());
@@ -149,9 +139,9 @@ public class BatchPropertyContextTests {
@Test
public void testNonStepLevelArtifactProperties() {
BatchPropertyContext batchPropertyContext = new BatchPropertyContext();
batchPropertyContext.setJobPropertiesContextEntry(jobProperties);
batchPropertyContext.setArtifactPropertiesContextEntry(artifactProperties);
batchPropertyContext.setStepPropertiesContextEntry(stepProperties);
batchPropertyContext.setJobProperties(jobProperties);
batchPropertyContext.setArtifactProperties(artifactProperties);
batchPropertyContext.setStepProperties(stepProperties);
Properties artifactProperties = batchPropertyContext.getArtifactProperties("decider1");
assertEquals(4, artifactProperties.size());
@@ -164,10 +154,10 @@ public class BatchPropertyContextTests {
@Test
public void testStepLevelArtifactProperties() {
BatchPropertyContext batchPropertyContext = new BatchPropertyContext();
batchPropertyContext.setJobPropertiesContextEntry(jobProperties);
batchPropertyContext.setArtifactPropertiesContextEntry(artifactProperties);
batchPropertyContext.setStepPropertiesContextEntry(stepProperties);
batchPropertyContext.setStepArtifactPropertiesContextEntry(stepArtifactProperties);
batchPropertyContext.setJobProperties(jobProperties);
batchPropertyContext.setArtifactProperties(artifactProperties);
batchPropertyContext.setStepProperties(stepProperties);
batchPropertyContext.setStepArtifactProperties(stepArtifactProperties);
Properties artifactProperties = batchPropertyContext.getStepArtifactProperties("step1", "reader");
assertEquals(6, artifactProperties.size());
@@ -182,14 +172,13 @@ public class BatchPropertyContextTests {
@Test
public void testArtifactNonOverridingJobProperties() {
BatchPropertyContext batchPropertyContext = new BatchPropertyContext();
batchPropertyContext.setJobPropertiesContextEntry(jobProperties);
batchPropertyContext.setArtifactPropertiesContextEntry(artifactProperties);
batchPropertyContext.setJobProperties(jobProperties);
batchPropertyContext.setArtifactProperties(artifactProperties);
Properties jobProperties = new Properties();
jobProperties.setProperty("deciderProperty1", "decider1PropertyOverride");
batchPropertyContext.setJobPropertiesContextEntry(
Collections.singletonList(batchPropertyContext.new BatchPropertyContextEntry("job1", jobProperties, BatchArtifact.BatchArtifactType.JOB)));
batchPropertyContext.setJobProperties(jobProperties);
Properties step1 = batchPropertyContext.getArtifactProperties("decider1");
assertEquals(4, step1.size());
@@ -208,11 +197,11 @@ public class BatchPropertyContextTests {
@Test
public void testPartitionProperties() {
BatchPropertyContext batchPropertyContext = new BatchPropertyContext();
batchPropertyContext.setJobPropertiesContextEntry(jobProperties);
batchPropertyContext.setArtifactPropertiesContextEntry(artifactProperties);
batchPropertyContext.setStepPropertiesContextEntry(stepProperties);
batchPropertyContext.setStepArtifactPropertiesContextEntry(stepArtifactProperties);
batchPropertyContext.setStepArtifactPropertiesContextEntry(partitionProperties);
batchPropertyContext.setJobProperties(jobProperties);
batchPropertyContext.setArtifactProperties(artifactProperties);
batchPropertyContext.setStepProperties(stepProperties);
batchPropertyContext.setStepArtifactProperties(stepArtifactProperties);
batchPropertyContext.setStepArtifactProperties(partitionProperties);
Properties artifactProperties = batchPropertyContext.getStepArtifactProperties("step2:partition0", "writer");
assertEquals(8, artifactProperties.size());

View File

@@ -217,8 +217,6 @@ public class JsrBeanDefinitionDocumentReaderTests {
JobExecution jobExecution = JsrTestUtils.runJob("jsrSpringInstanceTests", new Properties(), 10000L);
String exitStatus = jobExecution.getExitStatus();
assertEquals("listener1listener1listener4listener4", exitStatus);
assertTrue("Exit status must contain listener1", exitStatus.contains("listener1"));
assertTrue("exitStatus must contain 2 listener1 values", StringUtils.countOccurrencesOf(exitStatus, "listener1") == 2);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2013 the original author or authors.
* Copyright 2006-2014 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.
@@ -32,9 +32,7 @@ import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.jsr.configuration.support.BatchArtifact.BatchArtifactType;
import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext;
import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext.BatchPropertyContextEntry;
import org.springframework.batch.item.ExecutionContext;
/**
@@ -72,11 +70,8 @@ public class StepContextTests {
public void testGetPartitionPlan() {
Properties partitionPropertyValues = new Properties();
partitionPropertyValues.put("key1", "value1");
List<BatchPropertyContextEntry> entries = new ArrayList<BatchPropertyContext.BatchPropertyContextEntry>();
BatchPropertyContextEntry entry = propertyContext.new BatchPropertyContextEntry(stepExecution.getStepName(), partitionPropertyValues, BatchArtifactType.STEP);
entries.add(entry);
propertyContext.setStepPropertiesContextEntry(entries);
propertyContext.setStepProperties(stepExecution.getStepName(), partitionPropertyValues);
context = new StepContext(stepExecution, propertyContext);