diff --git a/execution/src/main/java/org/springframework/batch/execution/facade/BatchResourceFactoryBean.java b/execution/src/main/java/org/springframework/batch/execution/facade/BatchResourceFactoryBean.java index 25ca46698..c291da9b6 100644 --- a/execution/src/main/java/org/springframework/batch/execution/facade/BatchResourceFactoryBean.java +++ b/execution/src/main/java/org/springframework/batch/execution/facade/BatchResourceFactoryBean.java @@ -17,11 +17,9 @@ package org.springframework.batch.execution.facade; import java.io.File; -import java.text.SimpleDateFormat; import org.springframework.batch.core.domain.JobIdentifier; import org.springframework.batch.core.domain.StepExecution; -import org.springframework.batch.execution.runtime.ScheduledJobIdentifier; import org.springframework.batch.execution.scope.StepContext; import org.springframework.batch.execution.scope.StepContextAware; import org.springframework.beans.factory.FactoryBean; @@ -34,18 +32,16 @@ import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** - * *******This class is currently undergoing heavy refactoring***************** - * * Strategy for locating different resources on the file system. For each unique * step, the same file handle will be returned. A unique step is defined as - * having the same job name, job run, schedule date, stream name, and step name. - * An external file mover (such as an EAI solution) should rename and move any - * input files to conform to the patter defined by the file pattern.
+ * having the same job identifier and step name. An external file mover (such + * as an EAI solution) should rename and move any input files to conform to the + * patter defined by the file pattern.
* * If no pattern is passed in, then following default is used: * *
- * %BATCH_ROOT%/job_data/%JOB_NAME%/%SCHEDULE_DATE%-%STREAM_NAME%-%STEP_NAME%.txt
+ * %BATCH_ROOT%/job_data/%JOB_NAME%/%JOB_IDENTIFIER%-%STEP_NAME%.txt
  * 
* * The %% variables are replaced with the corresponding bean property at run @@ -57,41 +53,32 @@ import org.springframework.util.StringUtils; * * @see FactoryBean */ -public class BatchResourceFactoryBean extends AbstractFactoryBean implements ResourceLoaderAware, StepContextAware { +public class BatchResourceFactoryBean extends AbstractFactoryBean implements + ResourceLoaderAware, StepContextAware { private static final String BATCH_ROOT_PATTERN = "%BATCH_ROOT%"; - private static final String JOB_NAME_PATTERN = "%JOB_NAME%"; + private static final String JOB_IDENTIFIER_PATTERN = "%JOB_IDENTIFIER%"; - private static final String JOB_RUN_PATTERN = "%JOB_RUN%"; + private static final String JOB_NAME_PATTERN = "%JOB_NAME%"; private static final String STEP_NAME_PATTERN = "%STEP_NAME%"; - private static final String STREAM_PATTERN = "%STREAM_NAME%"; - - private static final String SCHEDULE_DATE_PATTERN = "%SCHEDULE_DATE%"; - - private static final String DEFAULT_PATTERN = "%BATCH_ROOT%/job_data/%JOB_NAME%/" - + "%SCHEDULE_DATE%-%STREAM_NAME%-%STEP_NAME%.txt"; + private static final String DEFAULT_PATTERN = "%BATCH_ROOT%/data/%JOB_NAME%/" + + "%JOB_IDENTIFIER%-%STEP_NAME%.txt"; private String filePattern = DEFAULT_PATTERN; private String jobName = null; - private String jobStream = ""; - - private int jobRun = 0; - - private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); - - private String scheduleDate = ""; - private String rootDirectory = ""; private String stepName = ""; private ResourceLoader resourceLoader; - + + private JobIdentifier jobIdentifier; + /** * Always false because we are usually expecting to be step scoped. * @@ -103,29 +90,26 @@ public class BatchResourceFactoryBean extends AbstractFactoryBean implements Res /* * (non-Javadoc) + * * @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader) */ public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } - /* + /* * (non-Javadoc) + * * @see org.springframework.batch.execution.scope.StepContextAware#setStepScopeContext(org.springframework.core.AttributeAccessor) */ public void setStepContext(StepContext context) { - Assert.state(context.getStepExecution()!=null, "The StepContext does not have an execution."); + Assert.state(context.getStepExecution() != null, + "The StepContext does not have an execution."); StepExecution execution = context.getStepExecution(); stepName = execution.getStep().getName(); jobName = execution.getStep().getJob().getName(); - JobIdentifier identifier = execution.getJobExecution().getJobIdentifier(); - if (identifier instanceof ScheduledJobIdentifier) { - ScheduledJobIdentifier scheduledJobIdentifier = (ScheduledJobIdentifier) identifier; - jobStream = scheduledJobIdentifier.getJobStream(); - jobRun = scheduledJobIdentifier.getJobRun(); - scheduleDate = dateFormat.format(scheduledJobIdentifier.getScheduleDate()); - } - + jobIdentifier = execution.getJobExecution() + .getJobIdentifier(); } /** @@ -150,7 +134,8 @@ public class BatchResourceFactoryBean extends AbstractFactoryBean implements Res /** * helper method for createFileName() */ - private String replacePattern(String string, String pattern, String replacement) { + private String replacePattern(String string, String pattern, + String replacement) { // check to ensure pattern exists in string. if (string.indexOf(pattern) != -1) { @@ -174,11 +159,10 @@ public class BatchResourceFactoryBean extends AbstractFactoryBean implements Res // TODO consider refactoring to void replacePattern() method and // collecting variable fileName fileName = replacePattern(fileName, BATCH_ROOT_PATTERN, rootDirectory); - fileName = replacePattern(fileName, JOB_NAME_PATTERN, jobName==null?"job":jobName); + fileName = replacePattern(fileName, JOB_NAME_PATTERN, + jobName == null ? "job" : jobName); fileName = replacePattern(fileName, STEP_NAME_PATTERN, stepName); - fileName = replacePattern(fileName, STREAM_PATTERN, jobStream); - fileName = replacePattern(fileName, JOB_RUN_PATTERN, String.valueOf(jobRun)); - fileName = replacePattern(fileName, SCHEDULE_DATE_PATTERN, scheduleDate); + fileName = replacePattern(fileName, JOB_IDENTIFIER_PATTERN, jobIdentifier==null ? "step": jobIdentifier.getLabel()); return fileName; } @@ -189,33 +173,10 @@ public class BatchResourceFactoryBean extends AbstractFactoryBean implements Res public void setRootDirectory(String rootDirectory) { this.rootDirectory = rootDirectory; - if (rootDirectory!=null && rootDirectory.endsWith(File.separator)) { - this.rootDirectory = rootDirectory.substring(0, rootDirectory.lastIndexOf(File.separator)); + if (rootDirectory != null && rootDirectory.endsWith(File.separator)) { + this.rootDirectory = rootDirectory.substring(0, rootDirectory + .lastIndexOf(File.separator)); } } - public void setStepName(String stepName) { - this.stepName = stepName; - } - - public void setJobName(String jobName) { - this.jobName = jobName; - } - - public void setJobRun(int jobRun) { - this.jobRun = jobRun; - } - - public void setJobStream(String jobStream) { - this.jobStream = jobStream; - } - - public void setScheduleDate(String scheduleDate) { - this.scheduleDate = scheduleDate; - } - - public void setDateFormatPattern(String pattern) { - dateFormat = new SimpleDateFormat(pattern); - } - } diff --git a/execution/src/main/java/org/springframework/batch/execution/runtime/ScheduledJobIdentifier.java b/execution/src/main/java/org/springframework/batch/execution/runtime/ScheduledJobIdentifier.java index e2b2c7ac8..c7fa625ce 100644 --- a/execution/src/main/java/org/springframework/batch/execution/runtime/ScheduledJobIdentifier.java +++ b/execution/src/main/java/org/springframework/batch/execution/runtime/ScheduledJobIdentifier.java @@ -16,6 +16,8 @@ package org.springframework.batch.execution.runtime; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.lang.builder.EqualsBuilder; @@ -25,6 +27,8 @@ import org.springframework.batch.core.runtime.SimpleJobIdentifier; public class ScheduledJobIdentifier extends SimpleJobIdentifier implements JobIdentifier { + private static final DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); + private Date scheduleDate = new Date(0); private int jobRun = 0; @@ -60,6 +64,12 @@ public class ScheduledJobIdentifier extends SimpleJobIdentifier implements JobId public void setScheduleDate(Date scheduleDate) { this.scheduleDate = scheduleDate; } + + + + public String getLabel() { + return super.getLabel()+"-"+jobStream+"-"+jobRun+"-"+dateFormat.format(scheduleDate); + } public String toString() { diff --git a/execution/src/test/java/org/springframework/batch/execution/facade/BatchResourceFactoryBeanTests.java b/execution/src/test/java/org/springframework/batch/execution/facade/BatchResourceFactoryBeanTests.java index 329fbd2ac..6b093e168 100644 --- a/execution/src/test/java/org/springframework/batch/execution/facade/BatchResourceFactoryBeanTests.java +++ b/execution/src/test/java/org/springframework/batch/execution/facade/BatchResourceFactoryBeanTests.java @@ -19,7 +19,6 @@ package org.springframework.batch.execution.facade; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; -import java.util.Calendar; import junit.framework.TestCase; @@ -44,37 +43,43 @@ import org.springframework.util.StringUtils; public class BatchResourceFactoryBeanTests extends TestCase { /** - * object under test + * Object under test */ private BatchResourceFactoryBean resourceFactory = new BatchResourceFactoryBean(); private String rootDir = getRootDir(); - + private char pathsep = File.separatorChar; - private String PATTERN_STRING = "/%BATCH_ROOT%" + pathsep - + "%JOB_NAME%-%SCHEDULE_DATE%-%JOB_RUN%-%STREAM_NAME%"; + private String path = "data" + pathsep; + + private ScheduledJobIdentifier identifier; /** * mock step context */ protected void setUp() throws Exception { - Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.YEAR, 2007); - calendar.set(Calendar.MONTH, Calendar.JULY); - calendar.set(Calendar.DAY_OF_MONTH, 30); - // define mock behaviour - resourceFactory.setScheduleDate("20070730"); resourceFactory.setRootDirectory(rootDir); - resourceFactory.setJobName("testJob"); - resourceFactory.setJobStream("testStream"); - resourceFactory.setJobRun(0); - resourceFactory.setStepName("testStep"); - resourceFactory.setFilePattern(PATTERN_STRING); + + identifier = new ScheduledJobIdentifier("testJob"); + // define mock behaviour + identifier.setScheduleDate(new SimpleDateFormat("yyyyMMdd") + .parse("20070730")); + identifier.setJobStream("testStream"); + identifier.setJobRun(11); + + SimpleStepContext context = new SimpleStepContext(); + JobInstance job = new JobInstance(identifier); + JobExecution jobExecution = new JobExecution(job); + StepInstance step = new StepInstance(job, "bar"); + StepExecution stepExecution = new StepExecution(step, jobExecution); + context.setStepExecution(stepExecution); + resourceFactory.setStepContext(context); resourceFactory.afterPropertiesSet(); + } private String getRootDir() { @@ -90,20 +95,7 @@ public class BatchResourceFactoryBeanTests extends TestCase { * regular use with valid context and pattern provided */ public void testCreateFileName() throws Exception { - doTestPathName("testJob-20070730-0-testStream"); - } - - /** - * Set the job name to null and attempt to get the resource, %JOB_NAME% - * should not be replaced. - */ - public void testNullJobName() throws Exception { - - resourceFactory.setJobName(null); - // set singleton to false so a new instance is returned. - resourceFactory.setSingleton(false); - - doTestPathName("job-20070730-0-testStream"); + doTestPathName("testJob-testStream-11-20070730-bar.txt", path); } public void testObjectType() throws Exception { @@ -112,7 +104,6 @@ public class BatchResourceFactoryBeanTests extends TestCase { public void testNullFilePattern() throws Exception { resourceFactory = new BatchResourceFactoryBean(); - resourceFactory.setSingleton(false); resourceFactory.setFilePattern(null); try { resourceFactory.getObject(); @@ -122,6 +113,12 @@ public class BatchResourceFactoryBeanTests extends TestCase { } } + public void testNonStandardFilePattern() throws Exception { + resourceFactory.setFilePattern("%BATCH_ROOT%/data/%JOB_NAME%/" + + "%STEP_NAME%+%JOB_IDENTIFIER%"); + doTestPathName("bar+testJob-testStream-11-20070730", path); + } + public void testResoureLoaderAware() throws Exception { resourceFactory = new BatchResourceFactoryBean(); resourceFactory.setSingleton(false); @@ -135,30 +132,11 @@ public class BatchResourceFactoryBeanTests extends TestCase { assertTrue(resource.exists()); } - public void testStepContextAware() throws Exception { - - SimpleStepContext context = new SimpleStepContext(); - ScheduledJobIdentifier identifier = new ScheduledJobIdentifier("foo"); - identifier.setJobStream("stream"); - identifier.setJobRun(11); - identifier.setScheduleDate(new SimpleDateFormat("yyyyMMdd") - .parse("20070801")); - JobInstance job = new JobInstance(identifier); - JobExecution jobExecution = new JobExecution(job); - StepInstance step = new StepInstance(job, "bar"); - StepExecution stepExecution = new StepExecution(step, jobExecution); - context.setStepExecution(stepExecution); - resourceFactory.setStepContext(context); - - doTestPathName("foo-20070801-11-stream"); - - } - public void testRootDirectoryEndsWithForwardSlash() throws Exception { String rootDir = getRootDir(); rootDir = StringUtils.replace(rootDir, File.separator, "/") + "/"; resourceFactory.setRootDirectory(rootDir); - doTestPathName("testJob-20070730-0-testStream"); + doTestPathName("testJob-testStream-11-20070730-bar.txt", path); } public void testRootDirectoryEndsWithBackSlash() throws Exception { @@ -166,38 +144,18 @@ public class BatchResourceFactoryBeanTests extends TestCase { rootDir = StringUtils.replace(rootDir, File.separator, "\\") + "\\"; resourceFactory.setRootDirectory(rootDir); // TODO: this one fails on UNIX (so Bamboo)... -// doTestPathName("testJob-20070730-0-testStream"); +// doTestPathName("testJob-testStream-11-20070730-bar.txt"); } - public void testDateFormatPattern() throws Exception { - resourceFactory.setDateFormatPattern("ddMMyyyy"); - - SimpleStepContext context = new SimpleStepContext(); - ScheduledJobIdentifier identifier = new ScheduledJobIdentifier("foo"); - identifier.setJobStream("stream"); - identifier.setJobRun(11); - identifier.setScheduleDate(new SimpleDateFormat("yyyyMMdd") - .parse("20070802")); - JobInstance job = new JobInstance(identifier); - JobExecution jobExecution = new JobExecution(job); - StepInstance step = new StepInstance(job, "bar"); - StepExecution stepExecution = new StepExecution(step, jobExecution); - context.setStepExecution(stepExecution); - resourceFactory.setStepContext(context); - - doTestPathName("foo-02082007-11-stream"); - } - - private void doTestPathName(String filename) throws Exception, IOException { + private void doTestPathName(String filename, String path) throws Exception, IOException { Resource resource = (Resource) resourceFactory.getObject(); String returnedPath = resource.getFile().getAbsolutePath(); - String absolutePath = new File("/" + rootDir + pathsep - + filename).getAbsolutePath(); + String absolutePath = new File("/" + rootDir + pathsep + path + identifier.getName() + pathsep + filename).getAbsolutePath(); - // System.err.println(absolutePath); - // System.err.println(returnedPath); + System.err.println(absolutePath); + System.err.println(returnedPath); assertEquals(absolutePath, returnedPath); } diff --git a/execution/src/test/java/org/springframework/batch/execution/runtime/ScheduledJobIdentifierTests.java b/execution/src/test/java/org/springframework/batch/execution/runtime/ScheduledJobIdentifierTests.java index 73e3b194f..ce491048b 100644 --- a/execution/src/test/java/org/springframework/batch/execution/runtime/ScheduledJobIdentifierTests.java +++ b/execution/src/test/java/org/springframework/batch/execution/runtime/ScheduledJobIdentifierTests.java @@ -16,6 +16,7 @@ package org.springframework.batch.execution.runtime; import java.sql.Date; +import java.text.SimpleDateFormat; import junit.framework.TestCase; @@ -63,4 +64,22 @@ public class ScheduledJobIdentifierTests extends TestCase { assertEquals(1, instance.getJobRun()); } + + /** + * Test method for {@link org.springframework.batch.core.domain.JobInstance#getLabel()}. + */ + public void testDefaultGetLabel() throws Exception { + assertEquals("null--0-19700101", instance.getLabel()); + } + + /** + * Test method for {@link org.springframework.batch.core.domain.JobInstance#getLabel()}. + */ + public void testGetLabelWithAllProperties() throws Exception { + instance.setName("foo"); + instance.setJobStream("bar"); + instance.setJobRun(11); + instance.setScheduleDate(new SimpleDateFormat("yyyyMMdd").parse("20070730")); + assertEquals("foo-bar-11-20070730", instance.getLabel()); + } }