1 package org.nuiton.eugene.writer;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import org.apache.commons.collections4.CollectionUtils;
26 import org.apache.commons.io.IOUtils;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.nuiton.util.FileUtil;
30 import org.nuiton.util.Resource;
31
32 import java.io.File;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.net.URI;
37 import java.net.URL;
38 import java.net.URLClassLoader;
39 import java.util.ArrayList;
40 import java.util.Collections;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Set;
44
45
46
47
48
49
50
51 public class FileGrabberFromClassPath implements FileGrabber {
52
53
54 private static final Log log = LogFactory.getLog(FileGrabberFromClassPath.class);
55
56 private final ChainedFileWriterConfiguration configuration;
57
58 public FileGrabberFromClassPath(ChainedFileWriterConfiguration configuration) {
59 this.configuration = configuration;
60 }
61
62 @Override
63 public void addFilesToTreate(File extractDirectory,
64 String inputDirectory,
65 Set<String> includePatterns,
66 ChainedFileWriterData result) throws IOException {
67
68 Map<File, List<File>> filesByRoot = result.getFilesByRoot();
69 Map<File, List<File>> resourcesByFile = result.getResourcesByFile();
70
71
72
73 File realInputDirectory;
74
75
76
77
78
79 String inputPath = inputDirectory;
80 if (inputPath.equals("/")) {
81 realInputDirectory = extractDirectory;
82 } else {
83 realInputDirectory = new File(extractDirectory, inputPath.substring(1));
84 }
85
86 List<URL> newUrls = getFiles(inputDirectory, includePatterns);
87
88 List<File> files = filesByRoot.get(realInputDirectory);
89 if (files == null) {
90 files = new ArrayList<>();
91 filesByRoot.put(realInputDirectory, files);
92 }
93
94 for (URL url : newUrls) {
95
96
97 File file = extractFileFromClassPath(extractDirectory, url);
98
99
100 files.add(file);
101
102
103 URL resourceFileUrl = getAssociatedResource(url);
104
105 if (resourceFileUrl == null) {
106
107
108 if (log.isDebugEnabled()) {
109 log.debug("[" + file + "] No resource associated.");
110 }
111
112 } else {
113
114
115 File resourceFile = extractFileFromClassPath(extractDirectory, resourceFileUrl);
116 if (log.isDebugEnabled()) {
117 log.debug("[" + file + "] Detected resource " + resourceFile);
118 }
119 resourcesByFile.put(file, Collections.singletonList(resourceFile));
120
121 }
122
123 }
124
125 if (CollectionUtils.isNotEmpty(files)) {
126
127
128 boolean b = extractDirectory.exists() || extractDirectory.mkdirs();
129 if (!b) {
130 throw new IOException("Could not create directory " + extractDirectory);
131 }
132
133 }
134
135 }
136
137 protected List<URL> getFiles(String inputPath, Set<String> includePattern) {
138
139 if (CollectionUtils.isEmpty(includePattern)) {
140 throw new IllegalArgumentException("Must have at least one include pattern");
141 }
142
143 List<URL> result = new ArrayList<>();
144
145
146
147 ClassLoader loader = configuration.getClassLoader();
148
149 for (String pattern : includePattern) {
150
151 String path = inputPath;
152
153
154 if (!path.endsWith("/")) {
155 path += "/";
156 }
157 path += pattern;
158
159 if (path.startsWith("/")) {
160 path = path.substring(1);
161 }
162
163 if (log.isDebugEnabled()) {
164 log.debug("Try to seek class-path file " + path);
165 }
166
167 if (pattern.contains("*")) {
168
169
170 List<URL> urlList = Resource.getURLs(path, (URLClassLoader) loader);
171 if (CollectionUtils.isEmpty(urlList)) {
172
173 log.warn("Could not find in class-path files " + path);
174 } else {
175 for (URL url : urlList) {
176
177 if (configuration.isVerbose()) {
178 log.info("Detected class-path file " + url);
179 }
180 result.add(url);
181 }
182 }
183 } else {
184
185
186
187 URL url = loader.getResource(path);
188 if (url == null) {
189
190 log.warn("Could not find in class-path the file " + path);
191 } else {
192
193 if (configuration.isVerbose()) {
194 log.info("Detected class-path file " + url);
195 }
196 result.add(url);
197 }
198 }
199 }
200 return result;
201 }
202
203 protected URL getAssociatedResource(URL file) throws IOException {
204
205
206 String path = file.toString();
207
208 String extension = "." + FileUtil.extension(path);
209
210 String filename = FileUtil.basename(path, extension).concat(".properties");
211
212 if (log.isDebugEnabled()) {
213 log.info("path of file : " + path);
214 log.info("path of resource : " + filename);
215 }
216
217 URL result;
218
219 URL propertiesFile = URI.create(filename).toURL();
220
221 if (path.startsWith("file:")) {
222
223
224
225
226 File file1 = new File(propertiesFile.getFile());
227 if (file1.exists()) {
228
229
230 result = propertiesFile;
231
232 } else {
233
234 result = null;
235
236 }
237
238 } else {
239
240 InputStream in = null;
241 try {
242 in = propertiesFile.openStream();
243
244
245 result = propertiesFile;
246
247 } catch (IOException eee) {
248
249
250 log.warn("Could not find resource " + propertiesFile);
251 result = null;
252
253 } finally {
254
255 if (in != null) {
256 in.close();
257 }
258
259 }
260
261 }
262
263 return result;
264
265 }
266
267 protected File extractFileFromClassPath(File extractDirectory, URL url) throws IOException {
268
269 String path = url.getPath();
270
271
272
273
274
275
276
277
278
279 int index = path.indexOf("!");
280 if (index == -1) {
281
282 index = path.lastIndexOf("/") - 1;
283 }
284 String relativePath = path.substring(index + 1);
285
286 File f = new File(extractDirectory, relativePath);
287 if (log.isDebugEnabled()) {
288 log.debug("extract " + url + " to " + f);
289 }
290 File parentFile = f.getParentFile();
291
292 boolean b = parentFile.exists() || parentFile.mkdirs();
293 if (!b) {
294 throw new IOException("Could not create directory " + f);
295 }
296
297 try (FileOutputStream out = new FileOutputStream(f)) {
298 IOUtils.copy(url.openStream(), out);
299 }
300 return f;
301
302 }
303
304 }