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 ( final 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 ( final IOException e )
238 {
239 this.getLogger().error( this.getDisabledMessage(
240 this.getLocale(), e.getMessage() ) );
241
242 this.schemaUrls = null;
243 }
244 catch ( final URISyntaxException e )
245 {
246 this.getLogger().error( this.getDisabledMessage(
247 this.getLocale(), e.getMessage() ) );
248
249 this.schemaUrls = null;
250 }
251 }
252
253 return this.schemaUrls != null ? this.schemaUrls : new URL[ 0 ];
254 }
255
256
257
258
259
260
261
262
263
264
265
266 private URL[] getSchemaResources() throws IOException, URISyntaxException
267 {
268 final ClassLoader cl = this.getClass().getClassLoader();
269 final Set
270
271 for ( final Enumeration e = cl.getResources( "META-INF/MANIFEST.MF" );
272 e.hasMoreElements(); )
273 {
274 final String[] extensions = this.getSchemaExtensions();
275 final URL manifestUrl = (URL) e.nextElement();
276 final String externalForm = manifestUrl.toExternalForm();
277 final String baseUrl =
278 externalForm.substring( 0, externalForm.indexOf( "META-INF" ) );
279
280 final InputStream manifestStream = manifestUrl.openStream();
281 final Manifest mf = new Manifest( manifestStream );
282
283 manifestStream.close();
284
285 for ( final Iterator it = mf.getEntries().entrySet().iterator();
286 it.hasNext(); )
287 {
288 final Map.Entry entry = (Map.Entry) it.next();
289 for ( int i = extensions.length - 1; i >= 0; i-- )
290 {
291 if ( entry.getKey().toString().toLowerCase().
292 endsWith( '.' + extensions[i].toLowerCase() ) )
293 {
294 final URL schemaUrl =
295 new URL( baseUrl + entry.getKey().toString() );
296
297 schemaResources.add( new URI( schemaUrl.toString() ) );
298
299 if ( this.getLogger().isDebugEnabled() )
300 {
301 this.getLogger().debug(
302 this.getCandidateSchemaMessage(
303 this.getLocale(),
304 schemaUrl.toExternalForm() ) );
305
306 }
307 }
308 }
309 }
310 }
311
312 final URL[] urls = new URL[ schemaResources.size() ];
313 final Iterator it = schemaResources.iterator();
314 for ( int i = 0; it.hasNext(); i++ )
315 {
316 urls[i] = ( (URI) it.next() ).toURL();
317 }
318
319 return urls;
320 }
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338 private String getCandidateSchemaMessage( final Locale locale,
339 final java.lang.String schemaLocation )
340 {
341 return ContainerFactory.getContainer().
342 getMessage( this, "candidateSchema", locale,
343 new Object[]
344 {
345 schemaLocation
346 });
347
348 }
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363 private String getResolvedSystemIdMessage( final Locale locale,
364 final java.lang.String systemId,
365 final java.lang.String resolvedSystemId )
366 {
367 return ContainerFactory.getContainer().
368 getMessage( this, "resolvedSystemId", locale,
369 new Object[]
370 {
371 systemId,
372 resolvedSystemId
373 });
374
375 }
376
377
378
379
380
381
382
383
384
385
386
387
388 private String getUnsupportedSystemIdUriMessage( final Locale locale,
389 final java.lang.String systemIdUri,
390 final java.lang.String cause )
391 {
392 return ContainerFactory.getContainer().
393 getMessage( this, "unsupportedSystemIdUri", locale,
394 new Object[]
395 {
396 systemIdUri,
397 cause
398 });
399
400 }
401
402
403
404
405
406
407
408
409
410
411
412 private String getDisabledMessage( final Locale locale,
413 final java.lang.String cause )
414 {
415 return ContainerFactory.getContainer().
416 getMessage( this, "disabled", locale,
417 new Object[]
418 {
419 cause
420 });
421
422 }
423
424
425
426
427 }