001/* 002 * Copyright (C) 2005 Christian Schulte <cs@schulte.it> 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without 006 * modification, are permitted provided that the following conditions 007 * are met: 008 * 009 * o Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 012 * o Redistributions in binary form must reproduce the above copyright 013 * notice, this list of conditions and the following disclaimer in 014 * the documentation and/or other materials provided with the 015 * distribution. 016 * 017 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 018 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 019 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 020 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, 021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 022 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 023 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 024 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 027 * 028 * $JOMC: DefaultModletProvider.java 5351 2016-09-05 04:22:17Z schulte $ 029 * 030 */ 031package org.jomc.modlet; 032 033import java.lang.reflect.UndeclaredThrowableException; 034import java.net.URL; 035import java.text.MessageFormat; 036import java.util.Enumeration; 037import java.util.LinkedList; 038import java.util.List; 039import java.util.ResourceBundle; 040import java.util.concurrent.Callable; 041import java.util.concurrent.CancellationException; 042import java.util.concurrent.ExecutionException; 043import java.util.concurrent.Future; 044import java.util.logging.Level; 045import javax.xml.bind.JAXBContext; 046import javax.xml.bind.JAXBElement; 047import javax.xml.bind.JAXBException; 048import javax.xml.bind.UnmarshalException; 049import javax.xml.bind.Unmarshaller; 050 051/** 052 * Default {@code ModletProvider} implementation. 053 * 054 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 055 * @version $JOMC: DefaultModletProvider.java 5351 2016-09-05 04:22:17Z schulte $ 056 * @see ModelContext#findModlets(org.jomc.modlet.Modlets) 057 */ 058public class DefaultModletProvider implements ModletProvider 059{ 060 061 /** 062 * Constant for the name of the model context attribute backing property {@code enabled}. 063 * 064 * @see #findModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets) 065 * @see ModelContext#getAttribute(java.lang.String) 066 * @since 1.2 067 */ 068 public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.modlet.DefaultModletProvider.enabledAttribute"; 069 070 /** 071 * Constant for the name of the system property controlling property {@code defaultEnabled}. 072 * 073 * @see #isDefaultEnabled() 074 * @since 1.2 075 */ 076 private static final String DEFAULT_ENABLED_PROPERTY_NAME = 077 "org.jomc.modlet.DefaultModletProvider.defaultEnabled"; 078 079 /** 080 * Default value of the flag indicating the provider is enabled by default. 081 * 082 * @see #isDefaultEnabled() 083 * @since 1.2 084 */ 085 private static final Boolean DEFAULT_ENABLED = Boolean.TRUE; 086 087 /** 088 * Flag indicating the provider is enabled by default. 089 */ 090 private static volatile Boolean defaultEnabled; 091 092 /** 093 * Flag indicating the provider is enabled. 094 */ 095 private volatile Boolean enabled; 096 097 /** 098 * Constant for the name of the model context attribute backing property {@code modletLocation}. 099 * 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}