1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.common.util;
17
18 import java.io.BufferedReader;
19 import java.io.BufferedWriter;
20 import java.io.File;
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.io.OutputStream;
26 import java.io.OutputStreamWriter;
27 import java.io.PrintStream;
28 import java.io.Reader;
29 import java.io.StringReader;
30 import java.io.Writer;
31 import java.net.MalformedURLException;
32 import java.net.URI;
33 import java.net.URISyntaxException;
34 import java.net.URL;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.Collections;
38 import java.util.List;
39
40 import org.apache.commons.io.FileUtils;
41 import org.apache.commons.io.IOUtils;
42 import org.apache.commons.lang3.StringUtils;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import org.springframework.core.io.DefaultResourceLoader;
46 import org.springframework.core.io.Resource;
47 import org.springframework.core.io.ResourceLoader;
48
49 public class LocationUtils {
50
51 private static final Logger logger = LoggerFactory.getLogger(LocationUtils.class);
52
53 private static final String FILE_PREFIX = "file:";
54 private static final String BACK_SLASH = "\\";
55 private static final String FORWARD_SLASH = "/";
56 private static final String SLASH_DOT_SLASH = "/./";
57 private static final String DOT_DOT_SLASH = "../";
58 private static final String SLASH_DOT_DOT = "/..";
59 private static final String CLASSPATH = "classpath:";
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 public static final PrintStream openPrintStream(File file) throws IOException {
83 return new PrintStream(FileUtils.openOutputStream(file));
84 }
85
86 public static final void copyLocationsToFiles(List<String> locations, List<File> files) {
87 Assert.isTrue(locations.size() == files.size());
88 for (int i = 0; i < locations.size(); i++) {
89 String location = locations.get(i);
90 File destination = files.get(i);
91 LocationUtils.copyLocationToFile(location, destination);
92 }
93 }
94
95
96
97
98
99 public static final String getClasspathFilename(String location) {
100 return getClasspathFilenames(Arrays.asList(location)).get(0);
101 }
102
103
104
105
106
107 public static final List<String> getClasspathFilenames(List<String> locations) {
108 List<String> classpathFilenames = new ArrayList<String>();
109 for (String location : locations) {
110 if (!isClasspathLocation(location)) {
111 throw new IllegalArgumentException(location + " must start with " + CLASSPATH);
112 } else {
113 classpathFilenames.add(StringUtils.substring(location, CLASSPATH.length()));
114 }
115 }
116 return classpathFilenames;
117 }
118
119
120
121
122 public static final boolean isClasspathLocation(String location) {
123 return StringUtils.startsWith(location, CLASSPATH);
124 }
125
126 public static final List<String> getNormalizedPathFragments(String absolutePath, boolean directory) {
127 String normalized = getNormalizedAbsolutePath(absolutePath);
128 String[] tokens = StringUtils.split(normalized, FORWARD_SLASH);
129 List<String> fragments = new ArrayList<String>();
130 StringBuilder sb = new StringBuilder();
131 sb.append(FORWARD_SLASH);
132 int length = directory ? tokens.length : tokens.length - 1;
133 for (int i = 0; i < length; i++) {
134 if (i != 0) {
135 sb.append(FORWARD_SLASH);
136 }
137 sb.append(tokens[i]);
138 fragments.add(sb.toString());
139 }
140 return fragments;
141 }
142
143 public static final List<String> getLocations(String location, LocationType type, String encoding) {
144 switch (type) {
145 case LOCATION:
146 return Collections.singletonList(location);
147 case LOCATIONLIST:
148 return getLocations(location, encoding);
149 default:
150 throw new IllegalArgumentException("Location type '" + type + "' is unknown");
151 }
152 }
153
154 public static final List<String> getLocations(String location, LocationType type) {
155 return getLocations(location, type, null);
156 }
157
158 public static final List<String> getLocations(String locationListing) {
159 return getLocations(Collections.singletonList(locationListing), null);
160 }
161
162 public static final List<String> getLocations(String locationListing, String encoding) {
163 return getLocations(Collections.singletonList(locationListing), encoding);
164 }
165
166 public static final List<String> getLocations(List<String> locationListings) {
167 return getLocations(locationListings, null);
168 }
169
170 public static final void copyLocationToFile(String location, File destination) {
171 Assert.notNull(location);
172 Assert.notNull(destination);
173 logger.debug("Copying [{}]->[{}]", location, destination);
174 InputStream in = null;
175 try {
176 in = getInputStream(location);
177 FileUtils.copyInputStreamToFile(in, destination);
178 } catch (IOException e) {
179 throw new IllegalStateException(e);
180 } finally {
181 IOUtils.closeQuietly(in);
182 }
183 }
184
185 public static final List<File> getFiles(File dir, List<String> filenames) {
186 List<File> files = new ArrayList<File>();
187 for (String filename : filenames) {
188 File file = new File(dir, filename);
189 files.add(file);
190 }
191 return files;
192 }
193
194 public static final List<String> getFilenames(List<String> locations) {
195 Assert.notNull(locations);
196 List<String> filenames = new ArrayList<String>();
197 for (String location : locations) {
198 filenames.add(getFilename(location));
199 }
200 return filenames;
201 }
202
203 public static final List<String> getLocations(List<String> locationListings, String encoding) {
204 List<String> locations = new ArrayList<String>();
205 for (String locationListing : locationListings) {
206 List<String> lines = readLines(locationListing, encoding);
207 locations.addAll(lines);
208 }
209 return locations;
210 }
211
212 public static final String getCanonicalURLString(File file) {
213 if (file == null) {
214 return null;
215 }
216 String path = getCanonicalPath(file);
217 File canonical = new File(path);
218 return getURLString(canonical);
219 }
220
221 public static final void validateNormalizedPath(String originalPath, String normalizedPath) {
222 if (CollectionUtils.containsAny(normalizedPath, Arrays.asList(SLASH_DOT_DOT, SLASH_DOT_SLASH, DOT_DOT_SLASH))) {
223 throw new IllegalArgumentException("[" + originalPath + "] could not be normalized. Normalized path [" + normalizedPath + "]");
224 }
225 }
226
227
228
229
230
231 public static final String getNormalizedAbsolutePath(String absolutePath) {
232 if (absolutePath == null) {
233 return null;
234 }
235 String replaced = StringUtils.replace(absolutePath, BACK_SLASH, FORWARD_SLASH);
236 boolean absolute = StringUtils.startsWith(replaced, FORWARD_SLASH);
237 if (!absolute) {
238 throw new IllegalArgumentException("[" + absolutePath + "] is not an absolute path.");
239 }
240 String prefixed = FILE_PREFIX + replaced;
241 try {
242 URI rawURI = new URI(prefixed);
243 URI normalizedURI = rawURI.normalize();
244 URL normalizedURL = normalizedURI.toURL();
245 String externalForm = normalizedURL.toExternalForm();
246 String trimmed = StringUtils.substring(externalForm, FILE_PREFIX.length());
247 validateNormalizedPath(absolutePath, trimmed);
248 return trimmed;
249 } catch (MalformedURLException e) {
250 throw new IllegalArgumentException(e);
251 } catch (URISyntaxException e) {
252 throw new IllegalArgumentException(e);
253 }
254 }
255
256 public static final String getURLString(File file) {
257 if (file == null) {
258 return null;
259 }
260 try {
261 URI uri = file.toURI();
262 URL url = uri.toURL();
263 return url.toExternalForm();
264 } catch (MalformedURLException e) {
265 throw new IllegalArgumentException(e);
266 }
267 }
268
269 public static final void forceMkdir(File file) {
270 try {
271 FileUtils.forceMkdir(file);
272 } catch (IOException e) {
273 throw new IllegalArgumentException("Unexpected IO error", e);
274 }
275 }
276
277 public static final void touch(File file) {
278 try {
279 FileUtils.touch(file);
280 } catch (IOException e) {
281 throw new IllegalArgumentException("Unexpected IO error", e);
282 }
283 }
284
285 public static final String getCanonicalPath(File file) {
286 try {
287 return file.getCanonicalPath();
288 } catch (IOException e) {
289 throw new IllegalArgumentException("Unexpected IO error", e);
290 }
291 }
292
293
294
295
296
297 public static final boolean deleteFileQuietly(String filename) {
298 File file = getFileQuietly(filename);
299 return FileUtils.deleteQuietly(file);
300 }
301
302
303
304
305
306 public static final File getFileQuietly(String filename) {
307 if (filename == null) {
308 return null;
309 } else {
310 return new File(filename);
311 }
312 }
313
314
315
316
317 public static final String toString(String location) {
318 return toString(location, null);
319 }
320
321
322
323
324 public static final String toString(String location, String encoding) {
325 InputStream in = null;
326 try {
327 in = getInputStream(location);
328 if (encoding == null) {
329 return IOUtils.toString(in);
330 } else {
331 return IOUtils.toString(in, encoding);
332 }
333 } catch (IOException e) {
334 throw new IllegalStateException("Unexpected IO error", e);
335 } finally {
336 IOUtils.closeQuietly(in);
337 }
338 }
339
340
341
342
343 public static final List<String> readLinesFromString(String s) {
344 Reader reader = getBufferedReaderFromString(s);
345 return readLinesAndClose(reader);
346 }
347
348 public static final List<String> readLinesAndClose(InputStream in) {
349 return readLinesAndClose(in, null);
350 }
351
352 public static final List<String> readLinesAndClose(InputStream in, String encoding) {
353 Reader reader = null;
354 try {
355 reader = getBufferedReader(in, encoding);
356 return readLinesAndClose(reader);
357 } catch (IOException e) {
358 throw new IllegalStateException("Unexpected IO error", e);
359 } finally {
360 IOUtils.closeQuietly(reader);
361 }
362 }
363
364 public static final List<String> readLinesAndClose(Reader reader) {
365 try {
366 return IOUtils.readLines(reader);
367 } catch (IOException e) {
368 throw new IllegalStateException("Unexpected IO error", e);
369 } finally {
370 IOUtils.closeQuietly(reader);
371 }
372 }
373
374
375
376
377 public static final List<String> readLines(File file) {
378 return readLines(getCanonicalPath(file));
379 }
380
381
382
383
384 public static final List<String> readLines(String location) {
385 return readLines(location, null);
386 }
387
388
389
390
391 public static final List<String> readLines(String location, String encoding) {
392 Reader reader = null;
393 try {
394 reader = getBufferedReader(location, encoding);
395 return readLinesAndClose(reader);
396 } catch (IOException e) {
397 throw new IllegalStateException("Unexpected IO error", e);
398 } finally {
399 IOUtils.closeQuietly(reader);
400 }
401 }
402
403
404
405
406 public static final BufferedReader getBufferedReader(String location) throws IOException {
407 return getBufferedReader(location, null);
408 }
409
410
411
412
413 public static final BufferedReader getBufferedReader(String location, String encoding) throws IOException {
414 try {
415 InputStream in = getInputStream(location);
416 return getBufferedReader(in, encoding);
417 } catch (IOException e) {
418 throw new IOException("Unexpected IO error", e);
419 }
420 }
421
422
423
424
425 public static final BufferedReader getBufferedReaderFromString(String s) {
426 return new BufferedReader(new StringReader(s));
427 }
428
429
430
431
432
433 public static final Writer getWriter(OutputStream out, String encoding) throws IOException {
434 if (encoding == null) {
435 return new BufferedWriter(new OutputStreamWriter(out));
436 } else {
437 return new BufferedWriter(new OutputStreamWriter(out, encoding));
438 }
439 }
440
441
442
443
444
445 public static final BufferedReader getBufferedReader(File file, String encoding) throws IOException {
446 return getBufferedReader(FileUtils.openInputStream(file), encoding);
447 }
448
449
450
451
452
453 public static final BufferedReader getBufferedReader(InputStream in, String encoding) throws IOException {
454 if (encoding == null) {
455 return new BufferedReader(new InputStreamReader(in));
456 } else {
457 return new BufferedReader(new InputStreamReader(in, encoding));
458 }
459 }
460
461
462
463
464 public static final boolean isExistingFile(String location) {
465 if (location == null) {
466 return false;
467 }
468 File file = new File(location);
469 return file.exists();
470 }
471
472
473
474
475 public static final boolean exists(File file) {
476 if (file == null) {
477 return false;
478 }
479 String location = getCanonicalPath(file);
480 if (isExistingFile(location)) {
481 return true;
482 } else {
483 Resource resource = getResource(location);
484 return resource.exists();
485 }
486 }
487
488
489
490
491 public static final boolean exists(String location) {
492 if (location == null) {
493 return false;
494 }
495 if (isExistingFile(location)) {
496 return true;
497 } else {
498 Resource resource = getResource(location);
499 return resource.exists();
500 }
501 }
502
503
504
505
506
507
508 public static final InputStream getInputStream(String location) throws IOException {
509 if (isExistingFile(location)) {
510 return FileUtils.openInputStream(new File(location));
511 }
512 Resource resource = getResource(location);
513 return resource.getInputStream();
514 }
515
516 public static final Resource getResource(String location) {
517 if (location == null) {
518 return null;
519 }
520 ResourceLoader loader = new DefaultResourceLoader();
521 return loader.getResource(location);
522 }
523
524 public static final String getFilename(String location) {
525 if (location == null) {
526 return null;
527 }
528 if (isExistingFile(location)) {
529 return getFileQuietly(location).getName();
530 } else {
531 Resource resource = getResource(location);
532 return resource.getFilename();
533 }
534 }
535
536 }