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 ContainedClassClasspathUrlLocator implements Locator<URL> {
36
37 private final List<String> paths;
38
39 private final ClassLoader[] classLoaders;
40
41 public ContainedClassClasspathUrlLocator(Class<?> clazz, ClassLoader... classLoaders) {
42 this.paths = new ArrayList<String>(1);
43 paths.add(asNormalizedName(clazz));
44
45 this.classLoaders = ClassLoaderUtils.getClassLoaders(classLoaders);
46 }
47
48 public ContainedClassClasspathUrlLocator(List<Class<?>> classes, ClassLoader... classLoaders) {
49 this.paths = new ArrayList<String>(classes.size());
50 for (Class<?> next : classes) {
51 paths.add(asNormalizedName(next));
52 }
53
54 this.classLoaders = ClassLoaderUtils.getClassLoaders(classLoaders);
55 }
56
57 @Override
58 public List<URL> locate() {
59
60 List<URL> list = new ArrayList<URL>();
61
62 for (ClassLoader classLoader : classLoaders) {
63 try {
64 for (String nextPath : paths) {
65 for (URL nextResourceMatchedUrl : new IterableEnumeration<URL>(classLoader.getResources(nextPath))) {
66
67 String deploymentArchiveRoot = determineClasspathRootForResource(nextPath, nextResourceMatchedUrl);
68
69 File fp = new File(deploymentArchiveRoot);
70
71 if (!fp.exists()) {
72 throw new FileAccessException("File unexpectedly does not exist: " + fp);
73 }
74
75 try {
76 list.add(fp.toURI().toURL());
77 } catch (MalformedURLException e) {
78 throw new FileAccessException("Filepath unexpectedly malformed: " + fp.getPath(), e);
79 }
80 }
81 }
82 } catch (IOException e) {
83 throw new FileAccessException("Problem resolving deployment archives: " + e.getMessage(), e);
84 }
85 }
86
87 return list;
88 }
89
90 private String determineClasspathRootForResource(String nextResource, URL nextResourceMatchedUrl) {
91
92 String nextResourceMatchedPathName = nextResourceMatchedUrl.getFile();
93 try {
94 nextResourceMatchedPathName = URLDecoder.decode(nextResourceMatchedPathName, "UTF-8");
95 } catch (UnsupportedEncodingException e) {
96
97 throw new FileAccessException("Exception thrown for Encoding when not expected: " + e.getMessage(), e);
98 }
99
100
101 if (nextResourceMatchedPathName.startsWith("file:")) {
102 nextResourceMatchedPathName = nextResourceMatchedPathName.substring(5);
103 }
104
105
106 if (nextResourceMatchedPathName.indexOf('!') > 0) {
107 nextResourceMatchedPathName = nextResourceMatchedPathName.substring(0, nextResourceMatchedPathName.indexOf('!'));
108 } else {
109 File indicatedResource = new File(nextResourceMatchedPathName);
110
111
112 int pathDepth = nextResource.replaceAll("[^/]", "").length();
113 for (int i = 0; i < pathDepth; i++) {
114 indicatedResource = indicatedResource.getParentFile();
115 }
116 nextResourceMatchedPathName = indicatedResource.getParent();
117 }
118
119 return nextResourceMatchedPathName;
120 }
121
122
123 private static String asNormalizedName(Class<?> clazz) {
124
125 String result = clazz.getName().replace(".", "/") + ".class";
126 return result;
127 }
128 }