1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.jdtaus.core.sax.ri.resolver;
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.net.URI;
26 import java.net.URISyntaxException;
27 import java.net.URL;
28 import java.util.Enumeration;
29 import java.util.HashSet;
30 import java.util.Iterator;
31 import java.util.Locale;
32 import java.util.Map;
33 import java.util.Set;
34 import java.util.jar.Manifest;
35 import org.jdtaus.core.container.ContainerFactory;
36 import org.jdtaus.core.logging.spi.Logger;
37 import org.xml.sax.EntityResolver;
38 import org.xml.sax.InputSource;
39 import org.xml.sax.SAXException;
40
41
42
43
44
45
46
47
48 public class ClasspathEntityResolver implements EntityResolver
49 {
50
51
52
53
54
55
56 public ClasspathEntityResolver()
57 {
58 super();
59 }
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 private Logger getLogger()
75 {
76 return (Logger) ContainerFactory.getContainer().
77 getDependency( this, "Logger" );
78
79 }
80
81
82
83
84
85
86 private Locale getLocale()
87 {
88 return (Locale) ContainerFactory.getContainer().
89 getDependency( this, "Locale" );
90
91 }
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 private java.lang.String getDefaultSchemaExtensions()
107 {
108 return (java.lang.String) ContainerFactory.getContainer().
109 getProperty( this, "defaultSchemaExtensions" );
110
111 }
112
113
114
115
116
117
118 public InputSource resolveEntity( final String publicId,
119 final String systemId )
120 throws SAXException, IOException
121 {
122 if ( systemId == null )
123 {
124 throw new NullPointerException( "systemId" );
125 }
126
127 InputSource schemaSource = null;
128
129 try
130 {
131 final URI systemUri = new URI( systemId );
132 String schemaName = systemUri.getPath();
133 if ( schemaName != null )
134 {
135 final int lastIndexOfSlash = schemaName.lastIndexOf( '/' );
136 if ( lastIndexOfSlash != -1 &&
137 lastIndexOfSlash < schemaName.length() )
138 {
139 schemaName =
140 schemaName.substring( lastIndexOfSlash + 1 );
141
142 }
143
144 final URL[] urls = this.getSchemaUrls();
145 for ( int i = urls.length - 1; i >= 0; i-- )
146 {
147 if ( urls[i].getPath().endsWith( schemaName ) )
148 {
149 schemaSource = new InputSource();
150 schemaSource.setPublicId( publicId );
151 schemaSource.setSystemId( urls[i].toExternalForm() );
152
153 if ( this.getLogger().isDebugEnabled() )
154 {
155 this.getLogger().debug(
156 this.getResolvedSystemIdMessage(
157 this.getLocale(), systemId,
158 schemaSource.getSystemId() ) );
159
160 }
161
162 break;
163 }
164 }
165 }
166 else
167 {
168 this.getLogger().warn( this.getUnsupportedSystemIdUriMessage(
169 this.getLocale(), systemId, systemUri.toASCIIString() ) );
170
171 }
172 }
173 catch ( URISyntaxException e )
174 {
175 this.getLogger().warn( this.getUnsupportedSystemIdUriMessage(
176 this.getLocale(), systemId, e.getMessage() ) );
177
178 schemaSource = null;
179 }
180
181 return schemaSource;
182 }
183
184
185
186
187
188 private String[] schemaExtensions;
189
190
191 private URL[] schemaUrls;
192
193
194
195
196
197
198
199 public ClasspathEntityResolver( final String[] schemaExtensions )
200 {
201 if ( schemaExtensions != null && schemaExtensions.length > 0 )
202 {
203 this.schemaExtensions = schemaExtensions;
204 }
205 }
206
207
208
209
210
211
212 private String[] getSchemaExtensions()
213 {
214 if ( this.schemaExtensions == null )
215 {
216 this.schemaExtensions =
217 this.getDefaultSchemaExtensions().split( "," );
218
219 }
220
221 return this.schemaExtensions;
222 }
223
224
225
226
227
228
229 private URL[] getSchemaUrls()
230 {
231 if ( this.schemaUrls == null )
232 {
233 try
234 {
235 this.schemaUrls = this.getSchemaResources();
236 }
237 catch ( IOException e )
238 {
239 this.getLogger().error( this.getDisabledMessage(
240 this.getLocale(), e.getMessage() ) );
241
242 this.schemaUrls = null;
243 }
244 }
245
246 return this.schemaUrls != null ? this.schemaUrls : new URL[ 0 ];
247 }
248
249
250
251
252
253
254
255
256
257
258 private URL[] getSchemaResources() throws IOException
259 {
260 final ClassLoader cl = this.getClass().getClassLoader();
261 final Set schemaResources = new HashSet();
262
263 for ( Enumeration e = cl.getResources( "META-INF/MANIFEST.MF" );
264 e.hasMoreElements(); )
265 {
266 final String[] extensions = this.getSchemaExtensions();
267 final URL manifestUrl = (URL) e.nextElement();
268 final String externalForm = manifestUrl.toExternalForm();
269 final String baseUrl =
270 externalForm.substring( 0, externalForm.indexOf( "META-INF" ) );
271
272 final InputStream manifestStream = manifestUrl.openStream();
273 final Manifest mf = new Manifest( manifestStream );
274
275 manifestStream.close();
276
277 for ( Iterator it = mf.getEntries().entrySet().iterator();
278 it.hasNext(); )
279 {
280 final Map.Entry entry = (Map.Entry) it.next();
281 for ( int i = extensions.length - 1; i >= 0; i-- )
282 {
283 if ( entry.getKey().toString().toLowerCase().
284 endsWith( '.' + extensions[i].toLowerCase() ) )
285 {
286 final URL schemaUrl =
287 new URL( baseUrl + entry.getKey().toString() );
288
289 schemaResources.add( schemaUrl );
290
291 if ( this.getLogger().isDebugEnabled() )
292 {
293 this.getLogger().debug(
294 this.getCandidateSchemaMessage(
295 this.getLocale(),
296 schemaUrl.toExternalForm() ) );
297
298 }
299 }
300 }
301 }
302 }
303
304 return (URL[]) schemaResources.toArray(
305 new URL[ schemaResources.size() ] );
306
307 }
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325 private String getCandidateSchemaMessage( final Locale locale,
326 final java.lang.String schemaLocation )
327 {
328 return ContainerFactory.getContainer().
329 getMessage( this, "candidateSchema", locale,
330 new Object[]
331 {
332 schemaLocation
333 });
334
335 }
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350 private String getResolvedSystemIdMessage( final Locale locale,
351 final java.lang.String systemId,
352 final java.lang.String resolvedSystemId )
353 {
354 return ContainerFactory.getContainer().
355 getMessage( this, "resolvedSystemId", locale,
356 new Object[]
357 {
358 systemId,
359 resolvedSystemId
360 });
361
362 }
363
364
365
366
367
368
369
370
371
372
373
374
375 private String getUnsupportedSystemIdUriMessage( final Locale locale,
376 final java.lang.String systemIdUri,
377 final java.lang.String cause )
378 {
379 return ContainerFactory.getContainer().
380 getMessage( this, "unsupportedSystemIdUri", locale,
381 new Object[]
382 {
383 systemIdUri,
384 cause
385 });
386
387 }
388
389
390
391
392
393
394
395
396
397
398
399 private String getDisabledMessage( final Locale locale,
400 final java.lang.String cause )
401 {
402 return ContainerFactory.getContainer().
403 getMessage( this, "disabled", locale,
404 new Object[]
405 {
406 cause
407 });
408
409 }
410
411
412
413
414 }