EMMA Coverage Report (generated Fri Jan 30 13:20:29 EST 2009)
[all classes][org.springframework.batch.core.resource]

COVERAGE SUMMARY FOR SOURCE FILE [StepExecutionResourceProxy.java]

nameclass, %method, %block, %line, %
StepExecutionResourceProxy.java100% (1/1)45%  (9/20)61%  (187/306)63%  (36.7/58)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class StepExecutionResourceProxy100% (1/1)45%  (9/20)61%  (187/306)63%  (36.7/58)
createRelative (String): Resource 0%   (0/1)0%   (0/13)0%   (0/2)
getDescription (): String 0%   (0/1)0%   (0/12)0%   (0/2)
getFilename (): String 0%   (0/1)0%   (0/12)0%   (0/2)
getInputStream (): InputStream 0%   (0/1)0%   (0/12)0%   (0/2)
getURI (): URI 0%   (0/1)0%   (0/12)0%   (0/2)
getURL (): URL 0%   (0/1)0%   (0/12)0%   (0/2)
isOpen (): boolean 0%   (0/1)0%   (0/12)0%   (0/2)
isReadable (): boolean 0%   (0/1)0%   (0/12)0%   (0/2)
isSingleton (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
lastModified (): long 0%   (0/1)0%   (0/12)0%   (0/2)
setJobParametersFactory (JobParametersConverter): void 0%   (0/1)0%   (0/4)0%   (0/2)
exists (): boolean 100% (1/1)92%  (11/12)96%  (1.9/2)
getFile (): File 100% (1/1)92%  (11/12)96%  (1.9/2)
createFileName (String, String, Properties): String 100% (1/1)97%  (58/60)99%  (10.9/11)
StepExecutionResourceProxy (): void 100% (1/1)100% (16/16)100% (4/4)
beforeStep (StepExecution): void 100% (1/1)100% (53/53)100% (8/8)
replacePattern (String, String, String): String 100% (1/1)100% (16/16)100% (5/5)
setFilePattern (String): void 100% (1/1)100% (8/8)100% (2/2)
setResourceLoader (ResourceLoader): void 100% (1/1)100% (4/4)100% (2/2)
toString (): String 100% (1/1)100% (10/10)100% (1/1)

1/*
2 * Copyright 2006-2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17package org.springframework.batch.core.resource;
18 
19import java.io.File;
20import java.io.IOException;
21import java.io.InputStream;
22import java.net.URI;
23import java.net.URL;
24import java.util.Iterator;
25import java.util.Properties;
26import java.util.Map.Entry;
27 
28import org.springframework.batch.core.JobParameters;
29import org.springframework.batch.core.StepExecution;
30import org.springframework.batch.core.StepExecutionListener;
31import org.springframework.batch.core.converter.DefaultJobParametersConverter;
32import org.springframework.batch.core.converter.JobParametersConverter;
33import org.springframework.batch.core.listener.StepExecutionListenerSupport;
34import org.springframework.context.ResourceLoaderAware;
35import org.springframework.core.io.FileSystemResourceLoader;
36import org.springframework.core.io.Resource;
37import org.springframework.core.io.ResourceLoader;
38import org.springframework.util.Assert;
39import org.springframework.util.StringUtils;
40 
41/**
42 * Strategy for locating different resources on the file system. For each unique
43 * step execution, the same file handle will be returned. A unique step is
44 * defined as having the same job instance and step name. An external file mover
45 * (such as an EAI solution) should rename and move any input files to conform
46 * to the pattern defined here.<br/>
47 * 
48 * If no pattern is passed in, then following default is used:
49 * 
50 * <pre>
51 * data/%JOB_NAME%/%STEP_NAME%.txt
52 * </pre>
53 * 
54 * The %% variables are replaced with the corresponding bean property at run
55 * time, when the factory method is executed. To insert {@link JobParameters}
56 * use a pattern with the parameter key surrounded by %%, e.g.
57 * 
58 * <pre>
59 * //home/jobs/data/%JOB_NAME%/%STEP_NAME%-%schedule.date%.txt
60 * </pre>
61 * 
62 * Note that the default pattern does not start with a separator. Because of the
63 * implementation of the Spring Core Resource abstractions, it would need to
64 * start with a double forward slash "//" to resolve to an absolute directory
65 * (or else use a full URL with the file: prefix).<br/>
66 * 
67 * To use this resource it must be initialised with a {@link StepExecution}.
68 * The best way to do that is to register it as a listener in the step that is
69 * going to need it. For this reason the resource implements
70 * {@link StepExecutionListener}.
71 * 
72 * @author Tomas Slanina
73 * @author Lucas Ward
74 * @author Dave Syer
75 * 
76 * @see Resource
77 */
78public class StepExecutionResourceProxy extends StepExecutionListenerSupport implements Resource, ResourceLoaderAware,
79                StepExecutionListener {
80 
81        private static final String JOB_NAME_PATTERN = "%JOB_NAME%";
82 
83        private static final String STEP_NAME_PATTERN = "%STEP_NAME%";
84 
85        private static final String DEFAULT_PATTERN = "data/%JOB_NAME%/" + "%STEP_NAME%.txt";
86 
87        private String filePattern = DEFAULT_PATTERN;
88 
89        private JobParametersConverter jobParametersConverter = new DefaultJobParametersConverter();
90 
91        private ResourceLoader resourceLoader = new FileSystemResourceLoader();
92 
93        private Resource delegate;
94 
95        /**
96         * @param relativePath
97         * @throws IOException
98         * @see org.springframework.core.io.Resource#createRelative(java.lang.String)
99         */
100        public Resource createRelative(String relativePath) throws IOException {
101                Assert.state(delegate != null, "The delegate resource has not been initialised. "
102                                + "Remember to register this object as a StepListener.");
103                return delegate.createRelative(relativePath);
104        }
105 
106        /**
107         * @see org.springframework.core.io.Resource#exists()
108         */
109        public boolean exists() {
110                Assert.state(delegate != null, "The delegate resource has not been initialised. "
111                                + "Remember to register this object as a StepListener.");
112                return delegate.exists();
113        }
114 
115        /**
116         * @see org.springframework.core.io.Resource#getDescription()
117         */
118        public String getDescription() {
119                Assert.state(delegate != null, "The delegate resource has not been initialised. "
120                                + "Remember to register this object as a StepListener.");
121                return delegate.getDescription();
122        }
123 
124        /**
125         * @throws IOException
126         * @see org.springframework.core.io.Resource#getFile()
127         */
128        public File getFile() throws IOException {
129                Assert.state(delegate != null, "The delegate resource has not been initialised. "
130                                + "Remember to register this object as a StepListener.");
131                return delegate.getFile();
132        }
133 
134        /**
135         * @see org.springframework.core.io.Resource#getFilename()
136         */
137        public String getFilename() {
138                Assert.state(delegate != null, "The delegate resource has not been initialised. "
139                                + "Remember to register this object as a StepListener.");
140                return delegate.getFilename();
141        }
142 
143        /**
144         * @throws IOException
145         * @see org.springframework.core.io.InputStreamSource#getInputStream()
146         */
147        public InputStream getInputStream() throws IOException {
148                Assert.state(delegate != null, "The delegate resource has not been initialised. "
149                                + "Remember to register this object as a StepListener.");
150                return delegate.getInputStream();
151        }
152 
153        /**
154         * @throws IOException
155         * @see org.springframework.core.io.Resource#getURI()
156         */
157        public URI getURI() throws IOException {
158                Assert.state(delegate != null, "The delegate resource has not been initialised. "
159                                + "Remember to register this object as a StepListener.");
160                return delegate.getURI();
161        }
162 
163        /**
164         * @throws IOException
165         * @see org.springframework.core.io.Resource#getURL()
166         */
167        public URL getURL() throws IOException {
168                Assert.state(delegate != null, "The delegate resource has not been initialised. "
169                                + "Remember to register this object as a StepListener.");
170                return delegate.getURL();
171        }
172 
173        /**
174         * @see org.springframework.core.io.Resource#isOpen()
175         */
176        public boolean isOpen() {
177                Assert.state(delegate != null, "The delegate resource has not been initialised. "
178                                + "Remember to register this object as a StepListener.");
179                return delegate.isOpen();
180        }
181 
182        /**
183         * @see org.springframework.core.io.Resource#isReadable()
184         */
185        public boolean isReadable() {
186                Assert.state(delegate != null, "The delegate resource has not been initialised. "
187                                + "Remember to register this object as a StepListener.");
188                return delegate.isReadable();
189        }
190 
191        /**
192         * @see org.springframework.core.io.Resource#lastModified()
193         */
194        public long lastModified() throws IOException {
195                Assert.state(delegate != null, "The delegate resource has not been initialised. "
196                                + "Remember to register this object as a StepListener.");
197                return delegate.lastModified();
198        }
199 
200        /**
201         * Public setter for the {@link JobParametersConverter} used to translate
202         * {@link JobParameters} into {@link Properties}. Defaults to a
203         * {@link DefaultJobParametersConverter}.
204         * @param jobParametersConverter the {@link JobParametersConverter} to set
205         */
206        public void setJobParametersFactory(JobParametersConverter jobParametersConverter) {
207                this.jobParametersConverter = jobParametersConverter;
208        }
209 
210        /**
211         * Always false because we are expecting to be step scoped.
212         * 
213         * @see org.springframework.beans.factory.config.AbstractFactoryBean#isSingleton()
214         */
215        public boolean isSingleton() {
216                return false;
217        }
218 
219        /*
220         * (non-Javadoc)
221         * 
222         * @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader)
223         */
224        public void setResourceLoader(ResourceLoader resourceLoader) {
225                this.resourceLoader = resourceLoader;
226        }
227 
228        /**
229         * helper method for <code>createFileName()</code>
230         */
231        private String replacePattern(String string, String pattern, String replacement) {
232 
233                if (string == null)
234                        return null;
235 
236                // check to ensure pattern exists in string.
237                if (string.indexOf(pattern) != -1) {
238                        return StringUtils.replace(string, pattern, replacement);
239                }
240 
241                return string;
242        }
243 
244        /**
245         * Creates a filename given a pattern and step context information.
246         * 
247         * Deliberate package access, so that the method can be accessed by unit
248         * tests
249         * @param jobName
250         * @param stepName
251         * @param properties
252         */
253        private String createFileName(String jobName, String stepName, Properties properties) {
254                Assert.notNull(filePattern, "filename pattern is null");
255 
256                String fileName = filePattern;
257 
258                fileName = replacePattern(fileName, JOB_NAME_PATTERN, jobName == null ? "job" : jobName);
259                fileName = replacePattern(fileName, STEP_NAME_PATTERN, stepName);
260 
261                if (properties != null) {
262                        for (Iterator iterator = properties.entrySet().iterator(); iterator.hasNext();) {
263                                Entry entry = (Entry) iterator.next();
264                                String key = (String) entry.getKey();
265                                fileName = replacePattern(fileName, "%" + key + "%", (String) entry.getValue());
266                        }
267                }
268 
269                return fileName;
270        }
271 
272        public void setFilePattern(String filePattern) {
273                this.filePattern = replacePattern(filePattern, "\\", File.separator);
274        }
275 
276        /**
277         * Collect the properties of the enclosing {@link StepExecution} that will
278         * be needed to create a file name.
279         * 
280         * @see org.springframework.batch.core.StepExecutionListener#beforeStep(org.springframework.batch.core.StepExecution)
281         */
282        public void beforeStep(StepExecution execution) {
283                String stepName = execution.getStepName();
284                String jobName = execution.getJobExecution().getJobInstance().getJobName();
285                Properties properties = jobParametersConverter.getProperties(execution.getJobExecution().getJobInstance()
286                                .getJobParameters());
287                String fileName = createFileName(jobName, stepName, properties);
288                if(fileName.indexOf("%") > -1){
289                        //if a % is still left in the fileName after matching, we have to assume that either no job parameter was found,
290                        //or an invalid path was used.
291                        throw new IllegalStateException("Invalid file pattern provided: [" + this.filePattern + "], tokens still remain after parameter matching: [" +
292                                        fileName + "]");
293                }
294                delegate = resourceLoader.getResource(fileName);
295        }
296 
297        /**
298         * Delegates to the proxied Resource if set, otherwise returns the value of {@link #setFilePattern(String)}.
299         */
300        public String toString() {
301                return (delegate == null) ? filePattern : delegate.toString(); 
302        }
303 
304}

[all classes][org.springframework.batch.core.resource]
EMMA 2.0.5312 (C) Vladimir Roubtsov