2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.core
.execution
;
19 import java
.io
.FileOutputStream
;
20 import java
.io
.IOException
;
21 import java
.io
.InputStream
;
22 import java
.io
.OutputStream
;
23 import java
.text
.SimpleDateFormat
;
24 import java
.util
.Date
;
26 import org
.apache
.commons
.io
.IOUtils
;
27 import org
.apache
.commons
.logging
.Log
;
28 import org
.apache
.commons
.logging
.LogFactory
;
29 import org
.argeo
.slc
.SlcException
;
30 import org
.argeo
.slc
.execution
.ExecutionContext
;
31 import org
.springframework
.core
.io
.FileSystemResource
;
32 import org
.springframework
.core
.io
.Resource
;
33 import org
.springframework
.util
.Assert
;
35 /** Implements write access to resources based on standard Java {@link File} */
36 public class FileExecutionResources
implements ExecutionResources
{
37 private final static Log log
= LogFactory
38 .getLog(FileExecutionResources
.class);
39 protected final static String DEFAULT_EXECUTION_RESOURCES_DIRNAME
= "executionResources";
40 public final static String DEFAULT_EXECUTION_RESOURCES_TMP_PATH
= System
41 .getProperty("java.io.tmpdir")
43 + System
.getProperty("user.name")
46 + File
.separator
+ DEFAULT_EXECUTION_RESOURCES_DIRNAME
;
49 private ExecutionContext executionContext
;
50 private String prefixDatePattern
= "yyMMdd_HHmmss_SSS";
51 private SimpleDateFormat sdf
= null;
53 private Boolean withExecutionSubdirectory
= true;
55 public FileExecutionResources() {
56 // Default base directory
57 String osgiInstanceArea
= System
.getProperty("osgi.instance.area");
58 String osgiInstanceAreaDefault
= System
59 .getProperty("osgi.instance.area.default");
61 if (osgiInstanceArea
!= null) {
62 // within OSGi with -data specified
63 osgiInstanceArea
= removeFilePrefix(osgiInstanceArea
);
64 baseDir
= new File(osgiInstanceArea
+ File
.separator
65 + DEFAULT_EXECUTION_RESOURCES_DIRNAME
);
66 } else if (osgiInstanceAreaDefault
!= null) {
67 // within OSGi without -data specified
68 osgiInstanceAreaDefault
= removeFilePrefix(osgiInstanceAreaDefault
);
69 baseDir
= new File(osgiInstanceAreaDefault
+ File
.separator
70 + DEFAULT_EXECUTION_RESOURCES_DIRNAME
);
71 } else {// outside OSGi
72 baseDir
= new File(DEFAULT_EXECUTION_RESOURCES_TMP_PATH
);
76 protected SimpleDateFormat
sdf() {
77 // Lazy init in case prefix has been externally set
79 sdf
= new SimpleDateFormat(prefixDatePattern
);
83 public Resource
getWritableResource(String relativePath
) {
84 File file
= getFile(relativePath
);
85 File parentDir
= file
.getParentFile();
87 if (!parentDir
.exists()) {
88 // Creates if necessary
89 if (log
.isTraceEnabled())
90 log
.trace("Creating parent directory " + parentDir
);
93 Resource resource
= new FileSystemResource(file
);
95 if (log
.isTraceEnabled())
96 log
.trace("Returns writable resource " + resource
);
100 public String
getWritableOsPath(String relativePath
) {
102 return getFile(relativePath
).getCanonicalPath();
103 } catch (IOException e
) {
104 throw new SlcException("Cannot find canonical path", e
);
108 public File
getWritableOsFile(String relativePath
) {
109 return getFile(relativePath
);
112 public String
getAsOsPath(Resource resource
, Boolean overwrite
) {
113 File file
= fileFromResource(resource
);
116 if (log
.isTraceEnabled())
117 log
.debug("Directly interpret " + resource
+ " as OS file "
119 return file
.getCanonicalPath();
120 } catch (IOException e1
) {
124 if (log
.isTraceEnabled())
125 log
.trace("Resource " + resource
126 + " is not available on the file system. Retrieving it...");
128 InputStream in
= null;
129 OutputStream out
= null;
131 String path
= resource
.getURL().getPath();
132 file
= getFile(path
);
133 if (file
.exists() && !overwrite
)
134 return file
.getCanonicalPath();
136 file
.getParentFile().mkdirs();
137 in
= resource
.getInputStream();
138 out
= new FileOutputStream(file
);
139 IOUtils
.copy(in
, out
);
140 if (log
.isDebugEnabled())
141 log
.debug("Retrieved " + resource
+ " to OS file " + file
);
142 return file
.getCanonicalPath();
143 } catch (IOException e
) {
144 throw new SlcException("Could not make resource " + resource
145 + " an OS file.", e
);
147 IOUtils
.closeQuietly(in
);
148 IOUtils
.closeQuietly(out
);
153 * Extract the underlying file from the resource.
155 * @return the file or null if no files support this resource.
157 protected File
fileFromResource(Resource resource
) {
159 return resource
.getFile();
160 } catch (IOException e
) {
166 protected File
getFile(String relativePath
) {
167 File writableBaseDir
= getWritableBaseDir();
168 return new File(writableBaseDir
.getPath() + File
.separator
169 + relativePath
.replace('/', File
.separatorChar
));
172 public File
getWritableBaseDir() {
173 if (withExecutionSubdirectory
) {
174 Date executionContextCreationDate
= (Date
) executionContext
175 .getVariable(ExecutionContext
.VAR_EXECUTION_CONTEXT_CREATION_DATE
);
176 Assert
.notNull(executionContext
, "execution context is null");
177 String path
= baseDir
.getPath() + File
.separator
178 + sdf().format(executionContextCreationDate
);
179 // TODO write execution id somewhere? like in a txt file
180 return new File(path
);
186 protected String
removeFilePrefix(String url
) {
187 if (url
.startsWith("file:"))
188 return url
.substring("file:".length());
189 else if (url
.startsWith("reference:file:"))
190 return url
.substring("reference:file:".length());
195 public void setBaseDir(File baseDir
) {
196 this.baseDir
= baseDir
;
199 public void setExecutionContext(ExecutionContext executionContext
) {
200 this.executionContext
= executionContext
;
203 public void setPrefixDatePattern(String prefixDatePattern
) {
204 this.prefixDatePattern
= prefixDatePattern
;
207 public File
getBaseDir() {
211 public ExecutionContext
getExecutionContext() {
212 return executionContext
;
215 public String
getPrefixDatePattern() {
216 return prefixDatePattern
;
219 /** Default is true. */
220 public void setWithExecutionSubdirectory(Boolean withExecutionSubdirectory
) {
221 this.withExecutionSubdirectory
= withExecutionSubdirectory
;