1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
package at.ipsquare.commons.core.util; |
17 | |
|
18 | |
|
19 | |
import java.io.File; |
20 | |
import java.io.FileNotFoundException; |
21 | |
import java.io.IOException; |
22 | |
import java.io.InputStream; |
23 | |
import java.net.URL; |
24 | |
import java.net.URLClassLoader; |
25 | |
import java.net.URLDecoder; |
26 | |
import java.util.Collection; |
27 | |
import java.util.HashSet; |
28 | |
import java.util.List; |
29 | |
import java.util.Set; |
30 | |
import java.util.TreeSet; |
31 | |
|
32 | |
import org.apache.commons.collections.EnumerationUtils; |
33 | |
|
34 | |
|
35 | |
|
36 | |
|
37 | |
|
38 | |
|
39 | |
|
40 | |
public final class LocalResources |
41 | |
{ |
42 | |
|
43 | |
|
44 | |
|
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
|
50 | |
|
51 | |
public static File getFile(String path) throws IOException |
52 | |
{ |
53 | 56 | URL url = getUrl(path); |
54 | 42 | if("jar".equals(url.getProtocol())) |
55 | 6 | throw new IOException(url + " points to a file that lies within a JAR file. Please use getUrl() or getStream() instead."); |
56 | |
|
57 | 36 | File file = new File(URLDecoder.decode(url.getFile(), "UTF-8")); |
58 | 36 | if(!file.canRead()) |
59 | 0 | throw new IOException("Not readable: '" + file + "'."); |
60 | 36 | return file; |
61 | |
} |
62 | |
|
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
|
68 | |
public static InputStream getStream(String path) throws IOException |
69 | |
{ |
70 | 20 | return getUrl(path).openStream(); |
71 | |
} |
72 | |
|
73 | |
|
74 | |
|
75 | |
|
76 | |
public static URL getUrl(String path) throws IOException |
77 | |
{ |
78 | 80 | Set<ClassLoader> classLoaders = ClassLoaders.get(); |
79 | 80 | Set<String> urls = new HashSet<String>(2); |
80 | |
|
81 | 80 | for(ClassLoader cl : classLoaders) |
82 | |
{ |
83 | 92 | URL url = getUrl(path, cl); |
84 | 92 | if(url != null) |
85 | 72 | urls.add(url.toExternalForm()); |
86 | 92 | } |
87 | |
|
88 | 80 | if(urls.isEmpty()) |
89 | |
{ |
90 | 16 | StringBuilder sb = new StringBuilder("'"); |
91 | 16 | sb.append(path).append("'"); |
92 | |
|
93 | 16 | if(path.startsWith("/")) |
94 | 6 | sb.append("; try ommiting the leading '/'."); |
95 | |
|
96 | 16 | sb.append("\n").append(classLoaderInfo(classLoaders)); |
97 | 16 | throw new FileNotFoundException(sb.toString()); |
98 | |
} |
99 | |
|
100 | 64 | if(urls.size() > 1) |
101 | 0 | throw new IOException("'" + path + "' : Ambiguous path."); |
102 | |
|
103 | 64 | return new URL(urls.iterator().next()); |
104 | |
} |
105 | |
|
106 | |
private static String classLoaderInfo(Collection<ClassLoader> classLoaders) |
107 | |
{ |
108 | 16 | StringBuilder sb = new StringBuilder("ClassLoaders involved:"); |
109 | 16 | for(ClassLoader cl : classLoaders) |
110 | 20 | sb.append("\n").append(classLoaderInfo(cl)); |
111 | 16 | return sb.toString(); |
112 | |
} |
113 | |
|
114 | |
private static String classLoaderInfo(ClassLoader cl) |
115 | |
{ |
116 | 20 | StringBuilder sb = new StringBuilder("** "); |
117 | |
|
118 | 20 | if(cl instanceof URLClassLoader) |
119 | |
{ |
120 | 16 | URLClassLoader urlCl = (URLClassLoader) cl; |
121 | 16 | sb.append("URLClassLoader -- ").append(collectClassLoaderUrls(urlCl)); |
122 | 16 | } |
123 | |
else |
124 | 4 | sb.append(cl); |
125 | |
|
126 | 20 | return sb.toString(); |
127 | |
} |
128 | |
|
129 | |
private static URL getUrl(String path, ClassLoader cl) throws IOException |
130 | |
{ |
131 | |
@SuppressWarnings("unchecked") |
132 | 92 | List<URL> urls = EnumerationUtils.toList(cl.getResources(path)); |
133 | |
|
134 | 92 | if(urls.isEmpty()) |
135 | 20 | return null; |
136 | 72 | if(urls.size() > 1) |
137 | 0 | throw new IOException("'" + path + "' : Ambiguous path; URLs: " + urls); |
138 | 72 | return urls.get(0); |
139 | |
} |
140 | |
|
141 | |
private static Set<String> collectClassLoaderUrls(URLClassLoader cl) |
142 | |
{ |
143 | 16 | Set<String> urls = new TreeSet<String>(); |
144 | 16 | collectClassLoaderUrls(cl, urls); |
145 | 16 | return urls; |
146 | |
} |
147 | |
|
148 | |
private static void collectClassLoaderUrls(URLClassLoader cl, Set<String> accumulator) |
149 | |
{ |
150 | 144 | for(URL url : cl.getURLs()) |
151 | 112 | accumulator.add(url.toString()); |
152 | |
|
153 | 32 | ClassLoader parent = cl.getParent(); |
154 | 32 | if(parent instanceof URLClassLoader) |
155 | 16 | collectClassLoaderUrls((URLClassLoader) parent, accumulator); |
156 | 32 | } |
157 | |
|
158 | |
private LocalResources() |
159 | 0 | { |
160 | |
|
161 | 0 | } |
162 | |
} |