1 /*
2 * Copyright (C) 2005 Christian Schulte <cs@schulte.it>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * o Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * o Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $JOMC: DefaultModletProvider.java 5351 2016-09-05 04:22:17Z schulte $
29 *
30 */
31 package org.jomc.modlet;
32
33 import java.lang.reflect.UndeclaredThrowableException;
34 import java.net.URL;
35 import java.text.MessageFormat;
36 import java.util.Enumeration;
37 import java.util.LinkedList;
38 import java.util.List;
39 import java.util.ResourceBundle;
40 import java.util.concurrent.Callable;
41 import java.util.concurrent.CancellationException;
42 import java.util.concurrent.ExecutionException;
43 import java.util.concurrent.Future;
44 import java.util.logging.Level;
45 import javax.xml.bind.JAXBContext;
46 import javax.xml.bind.JAXBElement;
47 import javax.xml.bind.JAXBException;
48 import javax.xml.bind.UnmarshalException;
49 import javax.xml.bind.Unmarshaller;
50
51 /**
52 * Default {@code ModletProvider} implementation.
53 *
54 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
55 * @version $JOMC: DefaultModletProvider.java 5351 2016-09-05 04:22:17Z schulte $
56 * @see ModelContext#findModlets(org.jomc.modlet.Modlets)
57 */
58 public class DefaultModletProvider implements ModletProvider
59 {
60
61 /**
62 * Constant for the name of the model context attribute backing property {@code enabled}.
63 *
64 * @see #findModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets)
65 * @see ModelContext#getAttribute(java.lang.String)
66 * @since 1.2
67 */
68 public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.modlet.DefaultModletProvider.enabledAttribute";
69
70 /**
71 * Constant for the name of the system property controlling property {@code defaultEnabled}.
72 *
73 * @see #isDefaultEnabled()
74 * @since 1.2
75 */
76 private static final String DEFAULT_ENABLED_PROPERTY_NAME =
77 "org.jomc.modlet.DefaultModletProvider.defaultEnabled";
78
79 /**
80 * Default value of the flag indicating the provider is enabled by default.
81 *
82 * @see #isDefaultEnabled()
83 * @since 1.2
84 */
85 private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;
86
87 /**
88 * Flag indicating the provider is enabled by default.
89 */
90 private static volatile Boolean defaultEnabled;
91
92 /**
93 * Flag indicating the provider is enabled.
94 */
95 private volatile Boolean enabled;
96
97 /**
98 * Constant for the name of the model context attribute backing property {@code modletLocation}.
99 *
100 * @see #findModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets)
101 * @see ModelContext#getAttribute(java.lang.String)
102 * @since 1.2
103 */
104 public static final String MODLET_LOCATION_ATTRIBUTE_NAME =
105 "org.jomc.modlet.DefaultModletProvider.modletLocationAttribute";
106
107 /**
108 * Constant for the name of the system property controlling property {@code defaultModletLocation}.
109 *
110 * @see #getDefaultModletLocation()
111 * @since 1.2
112 */
113 private static final String DEFAULT_MODLET_LOCATION_PROPERTY_NAME =
114 "org.jomc.modlet.DefaultModletProvider.defaultModletLocation";
115
116 /**
117 * Class path location searched for {@code Modlets} by default.
118 *
119 * @see #getDefaultModletLocation()
120 */
121 private static final String DEFAULT_MODLET_LOCATION = "META-INF/jomc-modlet.xml";
122
123 /**
124 * Default {@code Modlet} location.
125 */
126 private static volatile String defaultModletLocation;
127
128 /**
129 * Modlet location of the instance.
130 */
131 private volatile String modletLocation;
132
133 /**
134 * Constant for the name of the model context attribute backing property {@code validating}.
135 *
136 * @see #findModlets(org.jomc.modlet.ModelContext, java.lang.String)
137 * @see ModelContext#getAttribute(java.lang.String)
138 * @since 1.2
139 */
140 public static final String VALIDATING_ATTRIBUTE_NAME =
141 "org.jomc.modlet.DefaultModletProvider.validatingAttribute";
142
143 /**
144 * Constant for the name of the system property controlling property {@code defaultValidating}.
145 *
146 * @see #isDefaultValidating()
147 * @since 1.2
148 */
149 private static final String DEFAULT_VALIDATING_PROPERTY_NAME =
150 "org.jomc.modlet.DefaultModletProvider.defaultValidating";
151
152 /**
153 * Default value of the flag indicating the provider is validating resources by default.
154 *
155 * @see #isDefaultValidating()
156 * @since 1.2
157 */
158 private static final Boolean DEFAULT_VALIDATING = Boolean.TRUE;
159
160 /**
161 * Flag indicating the provider is validating resources by default.
162 *
163 * @since 1.2
164 */
165 private static volatile Boolean defaultValidating;
166
167 /**
168 * Flag indicating the provider is validating resources.
169 *
170 * @since 1.2
171 */
172 private volatile Boolean validating;
173
174 /**
175 * Constant for the name of the system property controlling property {@code defaultOrdinal}.
176 *
177 * @see #getDefaultOrdinal()
178 * @since 1.6
179 */
180 private static final String DEFAULT_ORDINAL_PROPERTY_NAME =
181 "org.jomc.modlet.DefaultModletProvider.defaultOrdinal";
182
183 /**
184 * Default value of the ordinal number of the provider.
185 *
186 * @see #getDefaultOrdinal()
187 * @since 1.6
188 */
189 private static final Integer DEFAULT_ORDINAL = 0;
190
191 /**
192 * Default ordinal number of the provider.
193 *
194 * @since 1.6
195 */
196 private static volatile Integer defaultOrdinal;
197
198 /**
199 * Ordinal number of the provider.
200 *
201 * @since 1.6
202 */
203 private volatile Integer ordinal;
204
205 /**
206 * Creates a new {@code DefaultModletProvider} instance.
207 */
208 public DefaultModletProvider()
209 {
210 super();
211 }
212
213 /**
214 * Gets a flag indicating the provider is enabled by default.
215 * <p>
216 * The default enabled flag is controlled by system property
217 * {@code org.jomc.modlet.DefaultModletProvider.defaultEnabled} holding a value indicating the provider is
218 * enabled by default. If that property is not set, the {@code true} default is returned.
219 * </p>
220 *
221 * @return {@code true}, if the provider is enabled by default; {@code false}, if the provider is disabled by
222 * default.
223 *
224 * @see #isEnabled()
225 * @see #setDefaultEnabled(java.lang.Boolean)
226 */
227 public static boolean isDefaultEnabled()
228 {
229 if ( defaultEnabled == null )
230 {
231 defaultEnabled = Boolean.valueOf( System.getProperty(
232 DEFAULT_ENABLED_PROPERTY_NAME, Boolean.toString( DEFAULT_ENABLED ) ) );
233
234 }
235
236 return defaultEnabled;
237 }
238
239 /**
240 * Sets the flag indicating the provider is enabled by default.
241 *
242 * @param value The new value of the flag indicating the provider is enabled by default or {@code null}.
243 *
244 * @see #isDefaultEnabled()
245 */
246 public static void setDefaultEnabled( final Boolean value )
247 {
248 defaultEnabled = value;
249 }
250
251 /**
252 * Gets a flag indicating the provider is enabled.
253 *
254 * @return {@code true}, if the provider is enabled; {@code false}, if the provider is disabled.
255 *
256 * @see #isDefaultEnabled()
257 * @see #setEnabled(java.lang.Boolean)
258 */
259 public final boolean isEnabled()
260 {
261 if ( this.enabled == null )
262 {
263 this.enabled = isDefaultEnabled();
264 }
265
266 return this.enabled;
267 }
268
269 /**
270 * Sets the flag indicating the provider is enabled.
271 *
272 * @param value The new value of the flag indicating the provider is enabled or {@code null}.
273 *
274 * @see #isEnabled()
275 */
276 public final void setEnabled( final Boolean value )
277 {
278 this.enabled = value;
279 }
280
281 /**
282 * Gets the default location searched for {@code Modlet} resources.
283 * <p>
284 * The default {@code Modlet} location is controlled by system property
285 * {@code org.jomc.modlet.DefaultModletProvider.defaultModletLocation} holding the location to search for
286 * {@code Modlet} resources by default. If that property is not set, the {@code META-INF/jomc-modlet.xml} default is
287 * returned.
288 * </p>
289 *
290 * @return The location searched for {@code Modlet} resources by default.
291 *
292 * @see #setDefaultModletLocation(java.lang.String)
293 */
294 public static String getDefaultModletLocation()
295 {
296 if ( defaultModletLocation == null )
297 {
298 defaultModletLocation = System.getProperty(
299 DEFAULT_MODLET_LOCATION_PROPERTY_NAME, DEFAULT_MODLET_LOCATION );
300
301 }
302
303 return defaultModletLocation;
304 }
305
306 /**
307 * Sets the default location searched for {@code Modlet} resources.
308 *
309 * @param value The new default location to search for {@code Modlet} resources or {@code null}.
310 *
311 * @see #getDefaultModletLocation()
312 */
313 public static void setDefaultModletLocation( final String value )
314 {
315 defaultModletLocation = value;
316 }
317
318 /**
319 * Gets the location searched for {@code Modlet} resources.
320 *
321 * @return The location searched for {@code Modlet} resources.
322 *
323 * @see #getDefaultModletLocation()
324 * @see #setModletLocation(java.lang.String)
325 */
326 public final String getModletLocation()
327 {
328 if ( this.modletLocation == null )
329 {
330 this.modletLocation = getDefaultModletLocation();
331 }
332
333 return this.modletLocation;
334 }
335
336 /**
337 * Sets the location searched for {@code Modlet} resources.
338 *
339 * @param value The new location to search for {@code Modlet} resources or {@code null}.
340 *
341 * @see #getModletLocation()
342 */
343 public final void setModletLocation( final String value )
344 {
345 this.modletLocation = value;
346 }
347
348 /**
349 * Gets a flag indicating the provider is validating resources by default.
350 * <p>
351 * The default validating flag is controlled by system property
352 * {@code org.jomc.modlet.DefaultModletProvider.defaultValidating} holding a value indicating the provider is
353 * validating resources by default. If that property is not set, the {@code true} default is returned.
354 * </p>
355 *
356 * @return {@code true}, if the provider is validating resources by default; {@code false}, if the provider is not
357 * validating resources by default.
358 *
359 * @see #isValidating()
360 * @see #setDefaultValidating(java.lang.Boolean)
361 *
362 * @since 1.2
363 */
364 public static boolean isDefaultValidating()
365 {
366 if ( defaultValidating == null )
367 {
368 defaultValidating = Boolean.valueOf( System.getProperty(
369 DEFAULT_VALIDATING_PROPERTY_NAME, Boolean.toString( DEFAULT_VALIDATING ) ) );
370
371 }
372
373 return defaultValidating;
374 }
375
376 /**
377 * Sets the flag indicating the provider is validating resources by default.
378 *
379 * @param value The new value of the flag indicating the provider is validating resources by default or
380 * {@code null}.
381 *
382 * @see #isDefaultValidating()
383 *
384 * @since 1.2
385 */
386 public static void setDefaultValidating( final Boolean value )
387 {
388 defaultValidating = value;
389 }
390
391 /**
392 * Gets a flag indicating the provider is validating resources.
393 *
394 * @return {@code true}, if the provider is validating resources; {@code false}, if the provider is not validating
395 * resources.
396 *
397 * @see #isDefaultValidating()
398 * @see #setValidating(java.lang.Boolean)
399 *
400 * @since 1.2
401 */
402 public final boolean isValidating()
403 {
404 if ( this.validating == null )
405 {
406 this.validating = isDefaultValidating();
407 }
408
409 return this.validating;
410 }
411
412 /**
413 * Sets the flag indicating the provider is validating resources.
414 *
415 * @param value The new value of the flag indicating the provider is validating resources or {@code null}.
416 *
417 * @see #isValidating()
418 *
419 * @since 1.2
420 */
421 public final void setValidating( final Boolean value )
422 {
423 this.validating = value;
424 }
425
426 /**
427 * Gets the default ordinal number of the provider.
428 * <p>
429 * The default ordinal number is controlled by system property
430 * {@code org.jomc.modlet.DefaultModletProvider.defaultOrdinal} holding the default ordinal number of the provider.
431 * If that property is not set, the {@code 0} default is returned.
432 * </p>
433 *
434 * @return The default ordinal number of the provider.
435 *
436 * @see #setDefaultOrdinal(java.lang.Integer)
437 *
438 * @since 1.6
439 */
440 public static int getDefaultOrdinal()
441 {
442 if ( defaultOrdinal == null )
443 {
444 defaultOrdinal = Integer.getInteger( DEFAULT_ORDINAL_PROPERTY_NAME, DEFAULT_ORDINAL );
445 }
446
447 return defaultOrdinal;
448 }
449
450 /**
451 * Sets the default ordinal number of the provider.
452 *
453 * @param value The new default ordinal number of the provider or {@code null}.
454 *
455 * @see #getDefaultOrdinal()
456 *
457 * @since 1.6
458 */
459 public static void setDefaultOrdinal( final Integer value )
460 {
461 defaultOrdinal = value;
462 }
463
464 /**
465 * Gets the ordinal number of the provider.
466 *
467 * @return The ordinal number of the provider.
468 *
469 * @see #getDefaultOrdinal()
470 * @see #setOrdinal(java.lang.Integer)
471 *
472 * @since 1.6
473 */
474 public final int getOrdinal()
475 {
476 if ( this.ordinal == null )
477 {
478 this.ordinal = getDefaultOrdinal();
479 }
480
481 return this.ordinal;
482 }
483
484 /**
485 * Sets the ordinal number of the provider.
486 *
487 * @param value The new ordinal number of the provider or {@code null}.
488 *
489 * @see #getOrdinal()
490 *
491 * @since 1.6
492 */
493 public final void setOrdinal( final Integer value )
494 {
495 this.ordinal = value;
496 }
497
498 /**
499 * Searches a given context for {@code Modlets}.
500 *
501 * @param context The context to search for {@code Modlets}.
502 * @param location The location to search at.
503 *
504 * @return The {@code Modlets} found at {@code location} in {@code context} or {@code null}, if no {@code Modlets}
505 * are found.
506 *
507 * @throws NullPointerException if {@code context} or {@code location} is {@code null}.
508 * @throws ModelException if searching the context fails.
509 *
510 * @see #isValidating()
511 * @see #VALIDATING_ATTRIBUTE_NAME
512 */
513 public Modlets findModlets( final ModelContext context, final String location ) throws ModelException
514 {
515 if ( context == null )
516 {
517 throw new NullPointerException( "context" );
518 }
519 if ( location == null )
520 {
521 throw new NullPointerException( "location" );
522 }
523
524 URL url = null;
525 try
526 {
527 boolean contextValidating = this.isValidating();
528 if ( DEFAULT_VALIDATING == contextValidating
529 && context.getAttribute( VALIDATING_ATTRIBUTE_NAME ) instanceof Boolean )
530 {
531 contextValidating = (Boolean) context.getAttribute( VALIDATING_ATTRIBUTE_NAME );
532 }
533
534 final Modlets modlets = new Modlets();
535 final long t0 = System.nanoTime();
536 final Enumeration<URL> modletResourceEnumeration = context.findResources( location );
537 final JAXBContext ctx = context.createContext( ModletObject.MODEL_PUBLIC_ID );
538 final javax.xml.validation.Schema schema = contextValidating
539 ? context.createSchema( ModletObject.MODEL_PUBLIC_ID )
540 : null;
541
542 final ThreadLocal<Unmarshaller> threadLocalUnmarshaller = new ThreadLocal<Unmarshaller>();
543
544 class UnmarshalTask implements Callable<Modlets>
545 {
546
547 final URL resource;
548
549 final javax.xml.validation.Schema schema;
550
551 UnmarshalTask( final URL resource, final javax.xml.validation.Schema schema )
552 {
553 super();
554 this.resource = resource;
555 this.schema = schema;
556 }
557
558 public Modlets call() throws ModelException
559 {
560 try
561 {
562 final Modlets modlets = new Modlets();
563 Unmarshaller unmarshaller = threadLocalUnmarshaller.get();
564 if ( unmarshaller == null )
565 {
566 unmarshaller = ctx.createUnmarshaller();
567 unmarshaller.setSchema( this.schema );
568
569 threadLocalUnmarshaller.set( unmarshaller );
570 }
571
572 Object content = unmarshaller.unmarshal( this.resource );
573 if ( content instanceof JAXBElement<?> )
574 {
575 content = ( (JAXBElement<?>) content ).getValue();
576 }
577
578 if ( content instanceof Modlet )
579 {
580 modlets.getModlet().add( (Modlet) content );
581 }
582 else if ( content instanceof Modlets )
583 {
584 modlets.getModlet().addAll( ( (Modlets) content ).getModlet() );
585 }
586
587 return modlets;
588 }
589 catch ( final UnmarshalException e )
590 {
591 String message = getMessage( e );
592 if ( message == null && e.getLinkedException() != null )
593 {
594 message = getMessage( e.getLinkedException() );
595 }
596
597 message = getMessage( "unmarshalException", this.resource.toExternalForm(),
598 message != null ? " " + message : "" );
599
600 throw new ModelException( message, e );
601 }
602 catch ( final JAXBException e )
603 {
604 String message = getMessage( e );
605 if ( message == null && e.getLinkedException() != null )
606 {
607 message = getMessage( e.getLinkedException() );
608 }
609
610 throw new ModelException( message, e );
611 }
612 }
613
614 }
615
616 final List<UnmarshalTask> tasks = new LinkedList<UnmarshalTask>();
617
618 while ( modletResourceEnumeration.hasMoreElements() )
619 {
620 tasks.add( new UnmarshalTask( modletResourceEnumeration.nextElement(), schema ) );
621 }
622
623 if ( context.getExecutorService() != null && tasks.size() > 1 )
624 {
625 for ( final Future<Modlets> task : context.getExecutorService().invokeAll( tasks ) )
626 {
627 modlets.getModlet().addAll( task.get().getModlet() );
628 }
629 }
630 else
631 {
632 for ( final UnmarshalTask task : tasks )
633 {
634 modlets.getModlet().addAll( task.call().getModlet() );
635 }
636 }
637
638 if ( context.isLoggable( Level.FINE ) )
639 {
640 context.log( Level.FINE, getMessage( "contextReport",
641 modlets.getModlet().size(),
642 location, System.nanoTime() - t0 ), null );
643
644 }
645
646 return modlets.getModlet().isEmpty() ? null : modlets;
647 }
648 catch ( final CancellationException e )
649 {
650 throw new ModelException( getMessage( e ), e );
651 }
652 catch ( final InterruptedException e )
653 {
654 throw new ModelException( getMessage( e ), e );
655 }
656 catch ( final ExecutionException e )
657 {
658 if ( e.getCause() instanceof ModelException )
659 {
660 throw (ModelException) e.getCause();
661 }
662 else if ( e.getCause() instanceof RuntimeException )
663 {
664 // The fork-join framework breaks the exception handling contract of Callable by re-throwing any
665 // exception caught using a runtime exception.
666 if ( e.getCause().getCause() instanceof ModelException )
667 {
668 throw (ModelException) e.getCause().getCause();
669 }
670 else if ( e.getCause().getCause() instanceof RuntimeException )
671 {
672 throw (RuntimeException) e.getCause().getCause();
673 }
674 else if ( e.getCause().getCause() instanceof Error )
675 {
676 throw (Error) e.getCause().getCause();
677 }
678 else if ( e.getCause().getCause() instanceof Exception )
679 {
680 // Checked exception not declared to be thrown by the Callable's 'call' method.
681 throw new UndeclaredThrowableException( e.getCause().getCause() );
682 }
683 else
684 {
685 throw (RuntimeException) e.getCause();
686 }
687 }
688 else if ( e.getCause() instanceof Error )
689 {
690 throw (Error) e.getCause();
691 }
692 else
693 {
694 // Checked exception not declared to be thrown by the Callable's 'call' method.
695 throw new UndeclaredThrowableException( e.getCause() );
696 }
697 }
698 }
699
700 /**
701 * {@inheritDoc}
702 *
703 * @return The {@code Modlets} found in the context or {@code null}, if no {@code Modlets} are found or the provider
704 * is disabled.
705 *
706 * @see #isEnabled()
707 * @see #getModletLocation()
708 * @see #findModlets(org.jomc.modlet.ModelContext, java.lang.String)
709 * @see #ENABLED_ATTRIBUTE_NAME
710 * @see #MODLET_LOCATION_ATTRIBUTE_NAME
711 * @deprecated As of JOMC 1.6, this method has been replaced by {@link #findModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets)}.
712 * This method will be removed in JOMC 2.0.
713 */
714 @Deprecated
715 public Modlets findModlets( final ModelContext context ) throws ModelException
716 {
717 if ( context == null )
718 {
719 throw new NullPointerException( "context" );
720 }
721
722 return this.findModlets( context, new Modlets() );
723 }
724
725 /**
726 * {@inheritDoc}
727 *
728 * @return The {@code Modlets} found in the context or {@code null}, if no {@code Modlets} are found or the provider
729 * is disabled.
730 *
731 * @see #isEnabled()
732 * @see #getModletLocation()
733 * @see #findModlets(org.jomc.modlet.ModelContext, java.lang.String)
734 * @see #ENABLED_ATTRIBUTE_NAME
735 * @see #MODLET_LOCATION_ATTRIBUTE_NAME
736 * @since 1.6
737 */
738 public Modlets findModlets( final ModelContext context, final Modlets modlets ) throws ModelException
739 {
740 if ( context == null )
741 {
742 throw new NullPointerException( "context" );
743 }
744 if ( modlets == null )
745 {
746 throw new NullPointerException( "context" );
747 }
748
749 Modlets provided = null;
750
751 boolean contextEnabled = this.isEnabled();
752 if ( DEFAULT_ENABLED == contextEnabled && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
753 {
754 contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
755 }
756
757 String contextModletLocation = this.getModletLocation();
758 if ( DEFAULT_MODLET_LOCATION.equals( contextModletLocation )
759 && context.getAttribute( MODLET_LOCATION_ATTRIBUTE_NAME ) instanceof String )
760 {
761 contextModletLocation = (String) context.getAttribute( MODLET_LOCATION_ATTRIBUTE_NAME );
762 }
763
764 if ( contextEnabled )
765 {
766 final Modlets found = this.findModlets( context, contextModletLocation );
767
768 if ( found != null )
769 {
770 provided = modlets.clone();
771 provided.getModlet().addAll( found.getModlet() );
772 }
773 }
774 else if ( context.isLoggable( Level.FINER ) )
775 {
776 context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName() ), null );
777 }
778
779 return provided;
780 }
781
782 private static String getMessage( final String key, final Object... arguments )
783 {
784 return MessageFormat.format( ResourceBundle.getBundle(
785 DefaultModletProvider.class.getName().replace( '.', '/' ) ).getString( key ), arguments );
786
787 }
788
789 private static String getMessage( final Throwable t )
790 {
791 return t != null
792 ? t.getMessage() != null && t.getMessage().trim().length() > 0
793 ? t.getMessage()
794 : getMessage( t.getCause() )
795 : null;
796
797 }
798
799 }