1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jadira.scanner.file.locator;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.io.UnsupportedEncodingException;
21 import java.net.MalformedURLException;
22 import java.net.URL;
23 import java.net.URLDecoder;
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import org.jadira.scanner.core.api.Locator;
28 import org.jadira.scanner.core.exception.FileAccessException;
29 import org.jadira.scanner.core.utils.lang.IterableEnumeration;
30 import org.jadira.scanner.core.utils.reflection.ClassLoaderUtils;
31
32
33
34
35 public class PackagesClasspathUrlLocator implements Locator<URL> {
36
37 private List<String> paths;
38
39 private final ClassLoader[] classLoaders;
40
41 public PackagesClasspathUrlLocator(String markerFilePath, ClassLoader... classLoaders) {
42 this.paths = new ArrayList<String>(1);
43 paths.add(asNormalizedName(markerFilePath));
44 this.classLoaders = ClassLoaderUtils.getClassLoaders(classLoaders);
45 }
46
47 public PackagesClasspathUrlLocator(List<String> markerFilePaths, ClassLoader... classLoaders) {
48 this.paths = new ArrayList<String>(markerFilePaths.size());
49 for (String next : markerFilePaths) {
50 paths.add(asNormalizedName(next));
51 }
52 this.classLoaders = ClassLoaderUtils.getClassLoaders(classLoaders);
53 }
54
55 @Override
56 public List<URL> locate() {
57
58 List<URL> list = new ArrayList<URL>();
59
60 for (ClassLoader classLoader : classLoaders) {
61 try {
62 for (String nextPath : paths) {
63 for (URL nextResourceMatchedUrl : new IterableEnumeration<URL>(classLoader.getResources(nextPath))) {
64
65 String deploymentArchiveRoot = determineClasspathRootForResource(nextPath, nextResourceMatchedUrl);
66
67 File fp = new File(deploymentArchiveRoot);
68
69 if (!fp.exists()) {
70 throw new FileAccessException("File unexpectedly does not exist: " + fp);
71 }
72
73 try {
74 list.add(fp.toURI().toURL());
75 } catch (MalformedURLException e) {
76 throw new FileAccessException("Filepath unexpectedly malformed: " + fp.getPath(), e);
77 }
78 }
79 }
80 } catch (IOException e) {
81 throw new FileAccessException("Problem resolving deployment archives: " + e.getMessage(), e);
82 }
83 }
84
85 return list;
86 }
87
88 private String determineClasspathRootForResource(String nextResource, URL nextResourceMatchedUrl) {
89
90 String nextResourceMatchedPathName = nextResourceMatchedUrl.getFile();
91 try {
92 nextResourceMatchedPathName = URLDecoder.decode(nextResourceMatchedPathName, "UTF-8");
93 } catch (UnsupportedEncodingException e) {
94
95 throw new FileAccessException("Exception thrown for Encoding when not expected: " + e.getMessage(), e);
96 }
97
98
99 if (nextResourceMatchedPathName.startsWith("file:")) {
100 nextResourceMatchedPathName = nextResourceMatchedPathName.substring(5);
101 }
102
103
104 if (nextResourceMatchedPathName.indexOf('!') > 0) {
105 nextResourceMatchedPathName = nextResourceMatchedPathName.substring(0, nextResourceMatchedPathName.indexOf('!'));
106 } else {
107 File indicatedResource = new File(nextResourceMatchedPathName);
108
109
110 int pathDepth = nextResource.replaceAll("[^/]", "").length();
111 for (int i = 0; i < pathDepth; i++) {
112 indicatedResource = indicatedResource.getParentFile();
113 }
114 nextResourceMatchedPathName = indicatedResource.getParent();
115 }
116
117 return nextResourceMatchedPathName;
118 }
119
120 private static String asNormalizedName(String name) {
121
122 String result = name;
123 if (result != null) {
124 result = result.replace(".", "/");
125 result = result.replace("\\", "/");
126 if (result.startsWith("/")) {
127 result = result.substring(1);
128 }
129 }
130 return result;
131 }
132 }