2222 */
2323package com .sun .org .apache .xml .internal .security ;
2424
25+ import java .io .IOException ;
2526import java .io .InputStream ;
27+ import java .net .URL ;
2628import java .security .AccessController ;
2729import java .security .PrivilegedAction ;
2830import java .security .PrivilegedActionException ;
2931import java .security .PrivilegedExceptionAction ;
3032import java .util .ArrayList ;
33+ import java .util .Enumeration ;
3134import java .util .List ;
3235
3336import com .sun .org .apache .xml .internal .security .algorithms .JCEMapper ;
@@ -89,13 +92,18 @@ public static synchronized void init() {
8992 if (cfile == null ) {
9093 return null ;
9194 }
92- return Init . class . getResourceAsStream (cfile );
95+ return getResourceAsStream (cfile , Init . class );
9396 }
9497 );
9598 if (is == null ) {
9699 dynamicInit ();
97100 } else {
98101 fileInit (is );
102+ try {
103+ is .close ();
104+ } catch (IOException ex ) {
105+ LOG .warn (ex .getMessage ());
106+ }
99107 }
100108
101109 alreadyInitialized = true ;
@@ -168,7 +176,7 @@ private static void dynamicInit() {
168176 private static void fileInit (InputStream is ) {
169177 try {
170178 /* read library configuration file */
171- Document doc = XMLUtils .read (is , false );
179+ Document doc = XMLUtils .read (is , true );
172180 Node config = doc .getFirstChild ();
173181 for (; config != null ; config = config .getNextSibling ()) {
174182 if ("Configuration" .equals (config .getLocalName ())) {
@@ -208,7 +216,7 @@ private static void fileInit(InputStream is) {
208216 Canonicalizer .register (uri , javaClass );
209217 LOG .debug ("Canonicalizer.register({}, {})" , uri , javaClass );
210218 } catch (ClassNotFoundException e ) {
211- Object exArgs [] = { uri , javaClass };
219+ Object [] exArgs = { uri , javaClass };
212220 LOG .error (I18n .translate ("algorithm.classDoesNotExist" , exArgs ));
213221 }
214222 }
@@ -226,7 +234,7 @@ private static void fileInit(InputStream is) {
226234 Transform .register (uri , javaClass );
227235 LOG .debug ("Transform.register({}, {})" , uri , javaClass );
228236 } catch (ClassNotFoundException e ) {
229- Object exArgs [] = { uri , javaClass };
237+ Object [] exArgs = { uri , javaClass };
230238
231239 LOG .error (I18n .translate ("algorithm.classDoesNotExist" , exArgs ));
232240 } catch (NoClassDefFoundError ex ) {
@@ -262,7 +270,7 @@ private static void fileInit(InputStream is) {
262270 SignatureAlgorithm .register (uri , javaClass );
263271 LOG .debug ("SignatureAlgorithm.register({}, {})" , uri , javaClass );
264272 } catch (ClassNotFoundException e ) {
265- Object exArgs [] = { uri , javaClass };
273+ Object [] exArgs = { uri , javaClass };
266274
267275 LOG .error (I18n .translate ("algorithm.classDoesNotExist" , exArgs ));
268276 }
@@ -272,7 +280,7 @@ private static void fileInit(InputStream is) {
272280 if ("ResourceResolvers" .equals (tag )) {
273281 Element [] resolverElem =
274282 XMLUtils .selectNodes (el .getFirstChild (), CONF_NS , "Resolver" );
275-
283+ List < String > classNames = new ArrayList <>( resolverElem . length );
276284 for (Element element : resolverElem ) {
277285 String javaClass =
278286 element .getAttributeNS (null , "JAVACLASS" );
@@ -284,16 +292,9 @@ private static void fileInit(InputStream is) {
284292 } else {
285293 LOG .debug ("Register Resolver: {}: For unknown purposes" , javaClass );
286294 }
287- try {
288- ResourceResolver .register (javaClass );
289- } catch (Throwable e ) {
290- LOG .warn (
291- "Cannot register:" + javaClass
292- + " perhaps some needed jars are not installed" ,
293- e
294- );
295- }
295+ classNames .add (javaClass );
296296 }
297+ ResourceResolver .registerClassNames (classNames );
297298 }
298299
299300 if ("KeyResolver" .equals (tag )){
@@ -335,6 +336,170 @@ private static void fileInit(InputStream is) {
335336 LOG .error ("Bad: " , e );
336337 }
337338 }
339+ /**
340+ * Load a given resource. <p></p> This method will try to load the resource
341+ * using the following methods (in order):
342+ * <ul>
343+ * <li>From Thread.currentThread().getContextClassLoader()
344+ * <li>From ClassLoaderUtil.class.getClassLoader()
345+ * <li>callingClass.getClassLoader()
346+ * </ul>
347+ *
348+ * @param resourceName The name of the resource to load
349+ * @param callingClass The Class object of the calling object
350+ */
351+ public static URL getResource (String resourceName , Class <?> callingClass ) {
352+ URL url = Thread .currentThread ().getContextClassLoader ().getResource (resourceName );
353+ if (url == null && resourceName .charAt (0 ) == '/' ) {
354+ //certain classloaders need it without the leading /
355+ url =
356+ Thread .currentThread ().getContextClassLoader ().getResource (
357+ resourceName .substring (1 )
358+ );
359+ }
360+
361+ ClassLoader cluClassloader = Init .class .getClassLoader ();
362+ if (cluClassloader == null ) {
363+ cluClassloader = ClassLoader .getSystemClassLoader ();
364+ }
365+ if (url == null ) {
366+ url = cluClassloader .getResource (resourceName );
367+ }
368+ if (url == null && resourceName .charAt (0 ) == '/' ) {
369+ //certain classloaders need it without the leading /
370+ url = cluClassloader .getResource (resourceName .substring (1 ));
371+ }
372+
373+ if (url == null ) {
374+ ClassLoader cl = callingClass .getClassLoader ();
375+
376+ if (cl != null ) {
377+ url = cl .getResource (resourceName );
378+ }
379+ }
380+
381+ if (url == null ) {
382+ url = callingClass .getResource (resourceName );
383+ }
384+
385+ if (url == null && resourceName .charAt (0 ) != '/' ) {
386+ return getResource ('/' + resourceName , callingClass );
387+ }
388+
389+ return url ;
390+ }
391+
392+ /**
393+ * Load a given resources. <p></p> This method will try to load the resources
394+ * using the following methods (in order):
395+ * <ul>
396+ * <li>From Thread.currentThread().getContextClassLoader()
397+ * <li>From ClassLoaderUtil.class.getClassLoader()
398+ * <li>callingClass.getClassLoader()
399+ * </ul>
400+ *
401+ * @param resourceName The name of the resource to load
402+ * @param callingClass The Class object of the calling object
403+ */
404+ private static List <URL > getResources (String resourceName , Class <?> callingClass ) {
405+ List <URL > ret = new ArrayList <>();
406+ Enumeration <URL > urls = new Enumeration <URL >() {
407+ public boolean hasMoreElements () {
408+ return false ;
409+ }
410+ public URL nextElement () {
411+ return null ;
412+ }
413+
414+ };
415+ try {
416+ urls = Thread .currentThread ().getContextClassLoader ().getResources (resourceName );
417+ } catch (IOException e ) {
418+ LOG .debug (e .getMessage (), e );
419+ //ignore
420+ }
421+ if (!urls .hasMoreElements () && resourceName .charAt (0 ) == '/' ) {
422+ //certain classloaders need it without the leading /
423+ try {
424+ urls =
425+ Thread .currentThread ().getContextClassLoader ().getResources (
426+ resourceName .substring (1 )
427+ );
428+ } catch (IOException e ) {
429+ LOG .debug (e .getMessage (), e );
430+ // ignore
431+ }
432+ }
433+
434+ ClassLoader cluClassloader = Init .class .getClassLoader ();
435+ if (cluClassloader == null ) {
436+ cluClassloader = ClassLoader .getSystemClassLoader ();
437+ }
438+ if (!urls .hasMoreElements ()) {
439+ try {
440+ urls = cluClassloader .getResources (resourceName );
441+ } catch (IOException e ) {
442+ LOG .debug (e .getMessage (), e );
443+ // ignore
444+ }
445+ }
446+ if (!urls .hasMoreElements () && resourceName .charAt (0 ) == '/' ) {
447+ //certain classloaders need it without the leading /
448+ try {
449+ urls = cluClassloader .getResources (resourceName .substring (1 ));
450+ } catch (IOException e ) {
451+ LOG .debug (e .getMessage (), e );
452+ // ignore
453+ }
454+ }
455+
456+ if (!urls .hasMoreElements ()) {
457+ ClassLoader cl = callingClass .getClassLoader ();
458+
459+ if (cl != null ) {
460+ try {
461+ urls = cl .getResources (resourceName );
462+ } catch (IOException e ) {
463+ LOG .debug (e .getMessage (), e );
464+ // ignore
465+ }
466+ }
467+ }
468+
469+ if (!urls .hasMoreElements ()) {
470+ URL url = callingClass .getResource (resourceName );
471+ if (url != null ) {
472+ ret .add (url );
473+ }
474+ }
475+ while (urls .hasMoreElements ()) {
476+ ret .add (urls .nextElement ());
477+ }
478+
479+
480+ if (ret .isEmpty () && resourceName != null && resourceName .charAt (0 ) != '/' ) {
481+ return getResources ('/' + resourceName , callingClass );
482+ }
483+ return ret ;
484+ }
485+
338486
487+ /**
488+ * This is a convenience method to load a resource as a stream. <p></p> The
489+ * algorithm used to find the resource is given in getResource()
490+ *
491+ * @param resourceName The name of the resource to load
492+ * @param callingClass The Class object of the calling object
493+ */
494+ private static InputStream getResourceAsStream (String resourceName , Class <?> callingClass ) {
495+ URL url = getResource (resourceName , callingClass );
496+
497+ try {
498+ return (url != null ) ? url .openStream () : null ;
499+ } catch (IOException e ) {
500+ LOG .debug (e .getMessage (), e );
501+ return null ;
502+ }
503+ }
339504}
340505
0 commit comments