diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContext.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContext.java index 0e0d4d3b3..c5355a312 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContext.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContext.java @@ -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 stepProperties = new HashMap(); private Map artifactProperties = new HashMap(); @@ -51,6 +51,18 @@ public class BatchPropertyContext { return jobProperties; } + /** + *

+ * Adds Job level properties to the context. + *

+ * + * @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); + } + /** *

* 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; } + /** + *

+ * Adds Step level properties to the context. + *

+ * + * @param properties the step {@link Properties} to add + */ + public void setStepProperties(Map properties) { + Assert.notNull(properties, "Step properties cannot be null"); + + for(Map.Entry 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()); + } + } + } + } + + /** + *

+ * Convenience method to set step level properties. Simply wraps the provided parameters + * and delegates to {@link #setStepProperties(java.util.Map)}. + *

+ * + * @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 stepProperties = new HashMap(); + stepProperties.put(stepName, properties); + + setStepProperties(stepProperties); + } + /** *

* Obtains the batch {@link Properties} for the provided artifact name. The returned {@link Properties} @@ -95,6 +153,26 @@ public class BatchPropertyContext { return properties; } + /** + *

+ * Adds non-step artifact properties to the context. + *

+ * + * @param properties the artifact {@link Properties} to add + */ + public void setArtifactProperties(Map properties) { + Assert.notNull(properties, "Step properties cannot be null"); + + for(Map.Entry propertiesEntry : properties.entrySet()) { + String artifactName = propertiesEntry.getKey(); + Properties artifactProperties = propertiesEntry.getValue(); + + if(!artifactProperties.isEmpty()) { + this.artifactProperties.put(artifactName, artifactProperties); + } + } + } + /** *

* Obtains the batch {@link Properties} for the provided Step and artifact name. @@ -131,207 +209,31 @@ public class BatchPropertyContext { /** *

- * Adds Job level properties to the context. + * Adds Step artifact properties to the context. *

* - * @param batchPropertyContextEntries the {@link BatchPropertyContextEntry} objects to add + * @param properties the step artifact {@link Properties} to add */ - public void setJobPropertiesContextEntry(List batchPropertyContextEntries) { - for(BatchPropertyContextEntry batchPropertyContextEntry : batchPropertyContextEntries) { - Properties jobProperties = batchPropertyContextEntry.getProperties(); + public void setStepArtifactProperties(Map> properties) { + Assert.notNull(properties, "Step artifact properties cannot be null"); - if (jobProperties != null && !jobProperties.isEmpty()) { - this.jobProperties.putAll(jobProperties); - } - } - } + for(Map.Entry> propertyEntries : properties.entrySet()) { + String stepName = propertyEntries.getKey(); - /** - *

- * Adds Step level properties to the context. - *

- * - * @param batchPropertyContextEntries the {@link BatchPropertyContextEntry} objects to add - */ - public void setStepPropertiesContextEntry(List batchPropertyContextEntries) { - for (BatchPropertyContextEntry batchPropertyContextEntry : batchPropertyContextEntries) { - Assert.hasText(batchPropertyContextEntry.getArtifactName(), "Step name must be defined as the artifact name."); + for(Map.Entry 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); - } - } - } - } - - /** - *

- * Adds non-Step scoped artifact properties to the context. - *

- * - * @param batchPropertyContextEntries the {@link BatchPropertyContextEntry} objects to add - */ - public void setArtifactPropertiesContextEntry(List 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); - } - } - } - - /** - *

- * Adds Step scoped artifact properties to the context. - *

- * - * @param batchPropertyContextEntries the {@link BatchPropertyContextEntry} objects to add - */ - @SuppressWarnings("serial") - public void setStepArtifactPropertiesContextEntry(List 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 artifactProperties = stepArtifactProperties.get(stepName); if (artifactProperties == null) { stepArtifactProperties.put(stepName, new HashMap() {{ - put(artifactName, properties); + put(artifactName, props); }}); } else { - artifactProperties.put(artifactName, properties); + artifactProperties.put(artifactName, props); } } } } - - /** - *

- * Obtains the property to be used when setting data for the provided {@link BatchArtifact.BatchArtifactType}. - *

- * - * @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); - } - } - - /** - *

- * Simple object to encapsulate batch properties of a given batch artifact. - *

- * - * @author Chris Schaefer - * @since 3.0 - */ - public class BatchPropertyContextEntry { - private String stepName; - private String artifactName; - private Properties properties; - private BatchArtifact.BatchArtifactType batchArtifactType; - - /** - *

- * Creates a new entry instance using the provided bean name representing batch artifact - * and its associated {@link Properties}. - *

- * - * @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(); - } - - /** - *

- * Obtains the name of the batch artifact this entry is associated with. - *

- * - * @return the name of the batch artifact - */ - public String getArtifactName() { - return artifactName; - } - - /** - *

- * Obtains the batch {@link Properties} that are associated with this entry. - *

- * - * @return the batch {@link Properties} - */ - public Properties getProperties() { - return properties; - } - - /** - *

- * Obtains the {@link BatchArtifact.BatchArtifactType} represented by this context entry. - *

- * - * @return the {@link BatchArtifact.BatchArtifactType} - */ - public BatchArtifact.BatchArtifactType getBatchArtifactType() { - return batchArtifactType; - } - - /** - *

- * Sets the Step name associated with this entry. - *

- * - * @param stepName the Step name associated with this entry - */ - public void setStepName(String stepName) { - this.stepName = stepName; - } - - /** - *

- * Obtains the Step name associated with this entry. - *

- * - * @return the step name associated with this entry - */ - public String getStepName() { - return stepName; - } - } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespaceUtils.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespaceUtils.java index d61fd7495..85734cd7c 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespaceUtils.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/JsrNamespaceUtils.java @@ -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); + } + } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PartitionParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PartitionParser.java index 5cedbdbd3..d3d619036 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PartitionParser.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PartitionParser.java @@ -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); } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PropertyParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PropertyParser.java index 253df467a..28b373916 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PropertyParser.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/PropertyParser.java @@ -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 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 element may not appear more than once in a single .", element); + parserContext.getReaderContext().error("The element may not appear more than once.", element); } - - setJobProperties(properties); } - public void parsePartitionProperties(Element element) { + /** + *

+ * Parses a <property> tag value from the provided {@link Element}. <property> elements have a name and + * value attribute which represent the property entries key and value. + *

+ * + * @param element the element to parse looking for <property/> + */ + public void parseProperty(Element element) { + parsePropertyElement(element); + } + + private void parsePropertyElement(Element propertyElement) { Properties properties = new Properties(); - List elements = new ArrayList(); - elements.add(element); - parsePropertiesElement(elements, properties); - - setJobProperties(properties); - } - - private void parsePropertiesElement(List propertiesElements, Properties properties) { - List 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 managedList = new ManagedList(); - 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 getProperties(String keyName, Properties properties) { + ManagedMap stepProperties = new ManagedMap(); + 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> getStepArtifactProperties(BeanDefinition beanDefinition, Properties properties) { + ManagedMap> stepArtifacts = new ManagedMap>(); + stepArtifacts.setMergeEnabled(true); + + Map> existingArtifacts + = (Map>) beanDefinition.getPropertyValues().get(getPropertyName(batchArtifactType)); + + ManagedMap artifactProperties = new ManagedMap(); + artifactProperties.setMergeEnabled(true); + + if(existingArtifacts != null && existingArtifacts.containsKey(stepName)) { + Map existingArtifactsMap = existingArtifacts.get(stepName); + + for(Map.Entry 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 jobProperties = new HashMap(); - 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); + } + } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/StepParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/StepParser.java index 8d423c54d..f93150814 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/StepParser.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/configuration/xml/StepParser.java @@ -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(); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/JsrPartitionHandler.java b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/JsrPartitionHandler.java index b7267ac37..47b93cf39 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/JsrPartitionHandler.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/jsr/partition/JsrPartitionHandler.java @@ -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 entries = new ArrayList(); - BatchPropertyContextEntry entry = propertyContext.new BatchPropertyContextEntry(curExecution.getStepName(), partitionPropertyValues, BatchArtifactType.STEP); - entries.add(entry); - - propertyContext.setStepPropertiesContextEntry(entries); + propertyContext.setStepProperties(curExecution.getStepName(), partitionPropertyValues); } i++; diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContextTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContextTests.java index 84d02b1ca..d8d555089 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContextTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/support/BatchPropertyContextTests.java @@ -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 jobProperties = new ArrayList(); - private List stepProperties = new ArrayList(); - private List artifactProperties = new ArrayList(); - private List stepArtifactProperties = new ArrayList(); - private List partitionProperties = new ArrayList(); + private Properties jobProperties = new Properties(); + private Map stepProperties = new HashMap(); + private Map artifactProperties = new HashMap(); + private Map> partitionProperties = new HashMap>(); + private Map> stepArtifactProperties = new HashMap>(); @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() {{ + 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() {{ + 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() {{ + 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()); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrBeanDefinitionDocumentReaderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrBeanDefinitionDocumentReaderTests.java index 66e6e5474..1c996fc2e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrBeanDefinitionDocumentReaderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrBeanDefinitionDocumentReaderTests.java @@ -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); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepContextTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepContextTests.java index 9f615e3a0..f754f252e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepContextTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/StepContextTests.java @@ -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 entries = new ArrayList(); - 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);