1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.util.lang;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.net.URISyntaxException;
21 import java.net.URL;
22 import java.net.URLDecoder;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Enumeration;
26 import java.util.List;
27 import java.util.jar.JarEntry;
28 import java.util.jar.JarFile;
29
30 import org.apache.commons.lang.StringUtils;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 @Deprecated
48 public class ClassPathDirectoryListing
49 {
50
51
52
53
54
55
56
57
58
59 private final ClassPathContext context;
60
61
62
63
64
65
66
67
68
69
70
71 public ClassPathDirectoryListing(final ClassLoader classLoader)
72 throws NullPointerException
73 {
74 this(new ClassPathContext(classLoader, null));
75 }
76
77
78
79
80
81
82
83 public ClassPathDirectoryListing(final ClassPathContext context)
84 throws NullPointerException
85 {
86 Arg.checkNotNull("context", context);
87 this.context = context;
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 public final ClassPathContext getClassPathContext()
104 {
105 return context;
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 public List<String> list(final String resourcePath)
128 throws NullPointerException, IllegalArgumentException
129 {
130 Arg.checkNotNull("resourcePath", resourcePath);
131
132 final URL resourcePathUrl = context.getResource(resourcePath);
133 if (resourcePathUrl == null)
134 {
135 throw new IllegalArgumentException("Cannot find resource '"
136 + resourcePath + "' on class path.");
137 }
138
139 final String protocol = resourcePathUrl.getProtocol();
140 if ("file".equals(protocol))
141 {
142 return handleFile(resourcePath, resourcePathUrl);
143 }
144 else if ("jar".equals(protocol))
145 {
146 return handleJar(resourcePath, resourcePathUrl);
147 }
148
149 throw new IllegalArgumentException(
150 "Protocol '" + protocol + "' is not supported to resolve resource '"
151 + resourcePath + "'.");
152 }
153
154 private List<String> handleFile(final String resourcePath,
155 final URL resourcePathUrl) throws IllegalArgumentException
156 {
157 try
158 {
159 final String[] contentsArray = new File(resourcePathUrl.toURI()).list();
160 return Arrays.asList(contentsArray);
161 }
162 catch (final URISyntaxException e)
163 {
164 throw new IllegalArgumentException(
165 "Cannot read URL derived from resource '" + resourcePath
166 + "' on the class path.", e);
167 }
168 }
169
170 private List<String> handleJar(final String resourcePath,
171 final URL resourcePathUrl) throws IllegalArgumentException
172 {
173 try
174 {
175 final List<String> contents = new ArrayList<String>();
176
177 final int separatorIndex = resourcePathUrl.getPath().indexOf('!');
178 final String jarPath =
179 resourcePathUrl.getPath().substring(5, separatorIndex);
180 final JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"));
181 traverseJarEntries(resourcePath, contents, jar);
182
183 return contents;
184 }
185 catch (final IOException e)
186 {
187 throw new IllegalArgumentException("Read from JAR '" + resourcePath
188 + "'.", e);
189 }
190 }
191
192 private void traverseJarEntries(final String resourcePath,
193 final List<String> contents, final JarFile jar)
194 {
195 final int resourcePathLength = resourcePath.length();
196
197 final Enumeration<JarEntry> entries = jar.entries();
198 while (entries.hasMoreElements())
199 {
200 final String name = entries.nextElement().getName();
201 if (name.startsWith(resourcePath))
202 {
203 final String entry = name.substring(resourcePathLength);
204 final String normalized = normalize(entry);
205
206 if (normalized != null && !contents.contains(normalized))
207 {
208 contents.add(normalized);
209 }
210 }
211 }
212 }
213
214 private static String normalize(final String entry)
215 {
216 if (StringUtils.isBlank(entry))
217 {
218 return null;
219 }
220
221 String normalized = entry;
222 if (normalized.charAt(0) == '/')
223 {
224 if (entry.length() == 1)
225 {
226 return null;
227 }
228 normalized = normalized.substring(1);
229 }
230
231 final int subDirIndex = normalized.indexOf('/');
232 if (subDirIndex != -1)
233 {
234 normalized = normalized.substring(0, subDirIndex);
235 }
236
237 return normalized;
238 }
239
240
241
242 }