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 5293 2016-08-29 17:41:51Z schulte $ 029 * 030 */ 031package org.jomc.modlet; 032 033import java.lang.reflect.UndeclaredThrowableException; 034import java.net.MalformedURLException; 035import java.net.URI; 036import java.net.URISyntaxException; 037import java.net.URL; 038import java.text.MessageFormat; 039import java.util.ArrayList; 040import java.util.Enumeration; 041import java.util.HashSet; 042import java.util.List; 043import java.util.ResourceBundle; 044import java.util.Set; 045import java.util.concurrent.Callable; 046import java.util.concurrent.CancellationException; 047import java.util.concurrent.ExecutionException; 048import java.util.concurrent.Future; 049import java.util.logging.Level; 050import javax.xml.bind.JAXBContext; 051import javax.xml.bind.JAXBElement; 052import javax.xml.bind.JAXBException; 053import javax.xml.bind.UnmarshalException; 054import javax.xml.bind.Unmarshaller; 055 056/** 057 * Default {@code ModletProvider} implementation. 058 * 059 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 060 * @version $JOMC: DefaultModletProvider.java 5293 2016-08-29 17:41:51Z schulte $ 061 * @see ModelContext#findModlets(org.jomc.modlet.Modlets) 062 */ 063public class DefaultModletProvider implements ModletProvider 064{ 065 066 /** 067 * Constant for the name of the model context attribute backing property {@code enabled}. 068 * 069 * @see #findModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets) 070 * @see ModelContext#getAttribute(java.lang.String) 071 * @since 1.2 072 */ 073 public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.modlet.DefaultModletProvider.enabledAttribute"; 074 075 /** 076 * Constant for the name of the system property controlling property {@code defaultEnabled}. 077 * 078 * @see #isDefaultEnabled() 079 * @since 1.2 080 */ 081 private static final String DEFAULT_ENABLED_PROPERTY_NAME = 082 "org.jomc.modlet.DefaultModletProvider.defaultEnabled"; 083 084 /** 085 * Default value of the flag indicating the provider is enabled by default. 086 * 087 * @see #isDefaultEnabled() 088 * @since 1.2 089 */ 090 private static final Boolean DEFAULT_ENABLED = Boolean.TRUE; 091 092 /** 093 * Flag indicating the provider is enabled by default. 094 */ 095 private static volatile Boolean defaultEnabled; 096 097 /** 098 * Flag indicating the provider is enabled. 099 */ 100 private volatile Boolean enabled; 101 102 /** 103 * Constant for the name of the model context attribute backing property {@code modletLocation}. 104 * 105 * @see #findModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets) 106 * @see ModelContext#getAttribute(java.lang.String) 107 * @since 1.2 108 */ 109 public static final String MODLET_LOCATION_ATTRIBUTE_NAME = 110 "org.jomc.modlet.DefaultModletProvider.modletLocationAttribute"; 111 112 /** 113 * Constant for the name of the system property controlling property {@code defaultModletLocation}. 114 * 115 * @see #getDefaultModletLocation() 116 * @since 1.2 117 */ 118 private static final String DEFAULT_MODLET_LOCATION_PROPERTY_NAME = 119 "org.jomc.modlet.DefaultModletProvider.defaultModletLocation"; 120 121 /** 122 * Class path location searched for {@code Modlets} by default. 123 * 124 * @see #getDefaultModletLocation() 125 */ 126 private static final String DEFAULT_MODLET_LOCATION = "META-INF/jomc-modlet.xml"; 127 128 /** 129 * Default {@code Modlet} location. 130 */ 131 private static volatile String defaultModletLocation; 132 133 /** 134 * Modlet location of the instance. 135 */ 136 private volatile String modletLocation; 137 138 /** 139 * Constant for the name of the model context attribute backing property {@code validating}. 140 * 141 * @see #findModlets(org.jomc.modlet.ModelContext, java.lang.String) 142 * @see ModelContext#getAttribute(java.lang.String) 143 * @since 1.2 144 */ 145 public static final String VALIDATING_ATTRIBUTE_NAME = 146 "org.jomc.modlet.DefaultModletProvider.validatingAttribute"; 147 148 /** 149 * Constant for the name of the system property controlling property {@code defaultValidating}. 150 * 151 * @see #isDefaultValidating() 152 * @since 1.2 153 */ 154 private static final String DEFAULT_VALIDATING_PROPERTY_NAME = 155 "org.jomc.modlet.DefaultModletProvider.defaultValidating"; 156 157 /** 158 * Default value of the flag indicating the provider is validating resources by default. 159 * 160 * @see #isDefaultValidating() 161 * @since 1.2 162 */ 163 private static final Boolean DEFAULT_VALIDATING = Boolean.TRUE; 164 165 /** 166 * Flag indicating the provider is validating resources by default. 167 * 168 * @since 1.2 169 */ 170 private static volatile Boolean defaultValidating; 171 172 /** 173 * Flag indicating the provider is validating resources. 174 * 175 * @since 1.2 176 */ 177 private volatile Boolean validating; 178 179 /** 180 * Constant for the name of the system property controlling property {@code defaultOrdinal}. 181 * 182 * @see #getDefaultOrdinal() 183 * @since 1.6 184 */ 185 private static final String DEFAULT_ORDINAL_PROPERTY_NAME = 186 "org.jomc.modlet.DefaultModletProvider.defaultOrdinal"; 187 188 /** 189 * Default value of the ordinal number of the provider. 190 * 191 * @see #getDefaultOrdinal() 192 * @since 1.6 193 */ 194 private static final Integer DEFAULT_ORDINAL = 0; 195 196 /** 197 * Default ordinal number of the provider. 198 * 199 * @since 1.6 200 */ 201 private static volatile Integer defaultOrdinal; 202 203 /** 204 * Ordinal number of the provider. 205 * 206 * @since 1.6 207 */ 208 private volatile Integer ordinal; 209 210 /** 211 * Creates a new {@code DefaultModletProvider} instance. 212 */ 213 public DefaultModletProvider() 214 { 215 super(); 216 } 217 218 /** 219 * Gets a flag indicating the provider is enabled by default. 220 * <p> 221 * The default enabled flag is controlled by system property 222 * {@code org.jomc.modlet.DefaultModletProvider.defaultEnabled} holding a value indicating the provider is 223 * enabled by default. If that property is not set, the {@code true} default is returned. 224 * </p> 225 * 226 * @return {@code true}, if the provider is enabled by default; {@code false}, if the provider is disabled by 227 * default. 228 * 229 * @see #isEnabled() 230 * @see #setDefaultEnabled(java.lang.Boolean) 231 */ 232 public static boolean isDefaultEnabled() 233 { 234 if ( defaultEnabled == null ) 235 { 236 defaultEnabled = Boolean.valueOf( System.getProperty( 237 DEFAULT_ENABLED_PROPERTY_NAME, Boolean.toString( DEFAULT_ENABLED ) ) ); 238 239 } 240 241 return defaultEnabled; 242 } 243 244 /** 245 * Sets the flag indicating the provider is enabled by default. 246 * 247 * @param value The new value of the flag indicating the provider is enabled by default or {@code null}. 248 * 249 * @see #isDefaultEnabled() 250 */ 251 public static void setDefaultEnabled( final Boolean value ) 252 { 253 defaultEnabled = value; 254 } 255 256 /** 257 * Gets a flag indicating the provider is enabled. 258 * 259 * @return {@code true}, if the provider is enabled; {@code false}, if the provider is disabled. 260 * 261 * @see #isDefaultEnabled() 262 * @see #setEnabled(java.lang.Boolean) 263 */ 264 public final boolean isEnabled() 265 { 266 if ( this.enabled == null ) 267 { 268 this.enabled = isDefaultEnabled(); 269 } 270 271 return this.enabled; 272 } 273 274 /** 275 * Sets the flag indicating the provider is enabled. 276 * 277 * @param value The new value of the flag indicating the provider is enabled or {@code null}. 278 * 279 * @see #isEnabled() 280 */ 281 public final void setEnabled( final Boolean value ) 282 { 283 this.enabled = value; 284 } 285 286 /** 287 * Gets the default location searched for {@code Modlet} resources. 288 * <p> 289 * The default {@code Modlet} location is controlled by system property 290 * {@code org.jomc.modlet.DefaultModletProvider.defaultModletLocation} holding the location to search for 291 * {@code Modlet} resources by default. If that property is not set, the {@code META-INF/jomc-modlet.xml} default is 292 * returned. 293 * </p> 294 * 295 * @return The location searched for {@code Modlet} resources by default. 296 * 297 * @see #setDefaultModletLocation(java.lang.String) 298 */ 299 public static String getDefaultModletLocation() 300 { 301 if ( defaultModletLocation == null ) 302 { 303 defaultModletLocation = System.getProperty( 304 DEFAULT_MODLET_LOCATION_PROPERTY_NAME, DEFAULT_MODLET_LOCATION ); 305 306 } 307 308 return defaultModletLocation; 309 } 310 311 /** 312 * Sets the default location searched for {@code Modlet} resources. 313 * 314 * @param value The new default location to search for {@code Modlet} resources or {@code null}. 315 * 316 * @see #getDefaultModletLocation() 317 */ 318 public static void setDefaultModletLocation( final String value ) 319 { 320 defaultModletLocation = value; 321 } 322 323 /** 324 * Gets the location searched for {@code Modlet} resources. 325 * 326 * @return The location searched for {@code Modlet} resources. 327 * 328 * @see #getDefaultModletLocation() 329 * @see #setModletLocation(java.lang.String) 330 */ 331 public final String getModletLocation() 332 { 333 if ( this.modletLocation == null ) 334 { 335 this.modletLocation = getDefaultModletLocation(); 336 } 337 338 return this.modletLocation; 339 } 340 341 /** 342 * Sets the location searched for {@code Modlet} resources. 343 * 344 * @param value The new location to search for {@code Modlet} resources or {@code null}. 345 * 346 * @see #getModletLocation() 347 */ 348 public final void setModletLocation( final String value ) 349 { 350 this.modletLocation = value; 351 } 352 353 /** 354 * Gets a flag indicating the provider is validating resources by default. 355 * <p> 356 * The default validating flag is controlled by system property 357 * {@code org.jomc.modlet.DefaultModletProvider.defaultValidating} holding a value indicating the provider is 358 * validating resources by default. If that property is not set, the {@code true} default is returned. 359 * </p> 360 * 361 * @return {@code true}, if the provider is validating resources by default; {@code false}, if the provider is not 362 * validating resources by default. 363 * 364 * @see #isValidating() 365 * @see #setDefaultValidating(java.lang.Boolean) 366 * 367 * @since 1.2 368 */ 369 public static boolean isDefaultValidating() 370 { 371 if ( defaultValidating == null ) 372 { 373 defaultValidating = Boolean.valueOf( System.getProperty( 374 DEFAULT_VALIDATING_PROPERTY_NAME, Boolean.toString( DEFAULT_VALIDATING ) ) ); 375 376 } 377 378 return defaultValidating; 379 } 380 381 /** 382 * Sets the flag indicating the provider is validating resources by default. 383 * 384 * @param value The new value of the flag indicating the provider is validating resources by default or 385 * {@code null}. 386 * 387 * @see #isDefaultValidating() 388 * 389 * @since 1.2 390 */ 391 public static void setDefaultValidating( final Boolean value ) 392 { 393 defaultValidating = value; 394 } 395 396 /** 397 * Gets a flag indicating the provider is validating resources. 398 * 399 * @return {@code true}, if the provider is validating resources; {@code false}, if the provider is not validating 400 * resources. 401 * 402 * @see #isDefaultValidating() 403 * @see #setValidating(java.lang.Boolean) 404 * 405 * @since 1.2 406 */ 407 public final boolean isValidating() 408 { 409 if ( this.validating == null ) 410 { 411 this.validating = isDefaultValidating(); 412 } 413 414 return this.validating; 415 } 416 417 /** 418 * Sets the flag indicating the provider is validating resources. 419 * 420 * @param value The new value of the flag indicating the provider is validating resources or {@code null}. 421 * 422 * @see #isValidating() 423 * 424 * @since 1.2 425 */ 426 public final void setValidating( final Boolean value ) 427 { 428 this.validating = value; 429 } 430 431 /** 432 * Gets the default ordinal number of the provider. 433 * <p> 434 * The default ordinal number is controlled by system property 435 * {@code org.jomc.modlet.DefaultModletProvider.defaultOrdinal} holding the default ordinal number of the provider. 436 * If that property is not set, the {@code 0} default is returned. 437 * </p> 438 * 439 * @return The default ordinal number of the provider. 440 * 441 * @see #setDefaultOrdinal(java.lang.Integer) 442 * 443 * @since 1.6 444 */ 445 public static int getDefaultOrdinal() 446 { 447 if ( defaultOrdinal == null ) 448 { 449 defaultOrdinal = Integer.getInteger( DEFAULT_ORDINAL_PROPERTY_NAME, DEFAULT_ORDINAL ); 450 } 451 452 return defaultOrdinal; 453 } 454 455 /** 456 * Sets the default ordinal number of the provider. 457 * 458 * @param value The new default ordinal number of the provider or {@code null}. 459 * 460 * @see #getDefaultOrdinal() 461 * 462 * @since 1.6 463 */ 464 public static void setDefaultOrdinal( final Integer value ) 465 { 466 defaultOrdinal = value; 467 } 468 469 /** 470 * Gets the ordinal number of the provider. 471 * 472 * @return The ordinal number of the provider. 473 * 474 * @see #getDefaultOrdinal() 475 * @see #setOrdinal(java.lang.Integer) 476 * 477 * @since 1.6 478 */ 479 public final int getOrdinal() 480 { 481 if ( this.ordinal == null ) 482 { 483 this.ordinal = getDefaultOrdinal(); 484 } 485 486 return this.ordinal; 487 } 488 489 /** 490 * Sets the ordinal number of the provider. 491 * 492 * @param value The new ordinal number of the provider or {@code null}. 493 * 494 * @see #getOrdinal() 495 * 496 * @since 1.6 497 */ 498 public final void setOrdinal( final Integer value ) 499 { 500 this.ordinal = value; 501 } 502 503 /** 504 * Searches a given context for {@code Modlets}. 505 * 506 * @param context The context to search for {@code Modlets}. 507 * @param location The location to search at. 508 * 509 * @return The {@code Modlets} found at {@code location} in {@code context} or {@code null}, if no {@code Modlets} 510 * are found. 511 * 512 * @throws NullPointerException if {@code context} or {@code location} is {@code null}. 513 * @throws ModelException if searching the context fails. 514 * 515 * @see #isValidating() 516 * @see #VALIDATING_ATTRIBUTE_NAME 517 */ 518 public Modlets findModlets( final ModelContext context, final String location ) throws ModelException 519 { 520 if ( context == null ) 521 { 522 throw new NullPointerException( "context" ); 523 } 524 if ( location == null ) 525 { 526 throw new NullPointerException( "location" ); 527 } 528 529 URL url = null; 530 try 531 { 532 boolean contextValidating = this.isValidating(); 533 if ( DEFAULT_VALIDATING == contextValidating 534 && context.getAttribute( VALIDATING_ATTRIBUTE_NAME ) instanceof Boolean ) 535 { 536 contextValidating = (Boolean) context.getAttribute( VALIDATING_ATTRIBUTE_NAME ); 537 } 538 539 final Modlets modlets = new Modlets(); 540 final long t0 = System.nanoTime(); 541 final Enumeration<URL> modletResourceEnumeration = context.findResources( location ); 542 final Set<URI> modletResources = new HashSet<URI>(); 543 while ( modletResourceEnumeration.hasMoreElements() ) 544 { 545 modletResources.add( modletResourceEnumeration.nextElement().toURI() ); 546 } 547 548 if ( !modletResources.isEmpty() ) 549 { 550 if ( context.getExecutorService() != null && modletResources.size() > 1 ) 551 { 552 final JAXBContext ctx = context.createContext( ModletObject.MODEL_PUBLIC_ID ); 553 final javax.xml.validation.Schema schema = context.createSchema( ModletObject.MODEL_PUBLIC_ID ); 554 final ThreadLocal<Unmarshaller> threadLocalUnmarshaller = new ThreadLocal<Unmarshaller>(); 555 final List<Callable<Object>> tasks = new ArrayList<Callable<Object>>( modletResources.size() ); 556 557 class UnmarshalTask implements Callable<Object> 558 { 559 560 final URI resource; 561 562 final boolean validating; 563 564 UnmarshalTask( final URI resource, final boolean validating ) 565 { 566 super(); 567 this.resource = resource; 568 this.validating = validating; 569 } 570 571 public Object call() throws ModelException, JAXBException, MalformedURLException 572 { 573 Unmarshaller unmarshaller = threadLocalUnmarshaller.get(); 574 if ( unmarshaller == null ) 575 { 576 unmarshaller = ctx.createUnmarshaller(); 577 578 if ( this.validating ) 579 { 580 unmarshaller.setSchema( schema ); 581 } 582 583 threadLocalUnmarshaller.set( unmarshaller ); 584 } 585 586 return unmarshaller.unmarshal( this.resource.toURL() ); 587 } 588 589 } 590 591 for ( final URI modletResoure : modletResources ) 592 { 593 tasks.add( new UnmarshalTask( modletResoure, contextValidating ) ); 594 } 595 596 for ( final Future<Object> task : context.getExecutorService().invokeAll( tasks ) ) 597 { 598 Object content = task.get(); 599 if ( content instanceof JAXBElement<?> ) 600 { 601 content = ( (JAXBElement<?>) content ).getValue(); 602 } 603 604 if ( content instanceof Modlet ) 605 { 606 modlets.getModlet().add( (Modlet) content ); 607 } 608 else if ( content instanceof Modlets ) 609 { 610 modlets.getModlet().addAll( ( (Modlets) content ).getModlet() ); 611 } 612 } 613 } 614 else 615 { 616 final JAXBContext ctx = context.createContext( ModletObject.MODEL_PUBLIC_ID ); 617 final Unmarshaller u = ctx.createUnmarshaller(); 618 619 if ( contextValidating ) 620 { 621 u.setSchema( context.createSchema( ModletObject.MODEL_PUBLIC_ID ) ); 622 } 623 624 for ( final URI modletResource : modletResources ) 625 { 626 url = modletResource.toURL(); 627 Object content = u.unmarshal( url ); 628 if ( content instanceof JAXBElement<?> ) 629 { 630 content = ( (JAXBElement<?>) content ).getValue(); 631 } 632 633 if ( content instanceof Modlet ) 634 { 635 modlets.getModlet().add( (Modlet) content ); 636 } 637 else if ( content instanceof Modlets ) 638 { 639 modlets.getModlet().addAll( ( (Modlets) content ).getModlet() ); 640 } 641 } 642 } 643 } 644 645 if ( context.isLoggable( Level.FINE ) ) 646 { 647 context.log( Level.FINE, getMessage( "contextReport", 648 modlets.getModlet().size(), 649 location, System.nanoTime() - t0 ), null ); 650 651 } 652 653 return modlets.getModlet().isEmpty() ? null : modlets; 654 } 655 catch ( final CancellationException e ) 656 { 657 throw new ModelException( getMessage( e ), e ); 658 } 659 catch ( final InterruptedException e ) 660 { 661 throw new ModelException( getMessage( e ), e ); 662 } 663 catch ( final URISyntaxException e ) 664 { 665 throw new ModelException( getMessage( e ), e ); 666 } 667 catch ( final MalformedURLException e ) 668 { 669 throw new ModelException( getMessage( e ), e ); 670 } 671 catch ( final UnmarshalException e ) 672 { 673 String message = getMessage( e ); 674 if ( message == null && e.getLinkedException() != null ) 675 { 676 message = getMessage( e.getLinkedException() ); 677 } 678 679 if ( url != null ) 680 { 681 message = getMessage( "unmarshalException", url.toExternalForm(), 682 message != null ? " " + message : "" ); 683 684 } 685 686 throw new ModelException( message, e ); 687 } 688 catch ( final JAXBException e ) 689 { 690 String message = getMessage( e ); 691 if ( message == null && e.getLinkedException() != null ) 692 { 693 message = getMessage( e.getLinkedException() ); 694 } 695 696 throw new ModelException( message, e ); 697 } 698 catch ( final ExecutionException e ) 699 { 700 if ( e.getCause() instanceof ModelException ) 701 { 702 throw (ModelException) e.getCause(); 703 } 704 else if ( e.getCause() instanceof JAXBException ) 705 { 706 String message = getMessage( e.getCause() ); 707 if ( message == null && ( (JAXBException) e.getCause() ).getLinkedException() != null ) 708 { 709 message = getMessage( ( (JAXBException) e.getCause() ).getLinkedException() ); 710 } 711 712 throw new ModelException( message, e.getCause() ); 713 } 714 else if ( e.getCause() instanceof RuntimeException ) 715 { 716 // The fork-join framework breaks the exception handling contract of Callable by re-throwing any 717 // exception caught using a runtime exception. 718 if ( e.getCause().getCause() instanceof ModelException ) 719 { 720 throw (ModelException) e.getCause().getCause(); 721 } 722 else if ( e.getCause().getCause() instanceof JAXBException ) 723 { 724 String message = getMessage( e.getCause().getCause() ); 725 if ( message == null && ( (JAXBException) e.getCause().getCause() ).getLinkedException() != null ) 726 { 727 message = getMessage( ( (JAXBException) e.getCause().getCause() ).getLinkedException() ); 728 } 729 730 throw new ModelException( message, e.getCause().getCause() ); 731 } 732 else if ( e.getCause().getCause() instanceof MalformedURLException ) 733 { 734 throw new ModelException( getMessage( e.getCause().getCause() ), e.getCause().getCause() ); 735 } 736 else if ( e.getCause().getCause() instanceof RuntimeException ) 737 { 738 throw (RuntimeException) e.getCause().getCause(); 739 } 740 else if ( e.getCause().getCause() instanceof Error ) 741 { 742 throw (Error) e.getCause().getCause(); 743 } 744 else if ( e.getCause().getCause() instanceof Exception ) 745 { 746 // Checked exception not declared to be thrown by the Callable's 'call' method. 747 throw new UndeclaredThrowableException( e.getCause().getCause() ); 748 } 749 else 750 { 751 throw (RuntimeException) e.getCause(); 752 } 753 } 754 else if ( e.getCause() instanceof Error ) 755 { 756 throw (Error) e.getCause(); 757 } 758 else 759 { 760 // Checked exception not declared to be thrown by the Callable's 'call' method. 761 throw new UndeclaredThrowableException( e.getCause() ); 762 } 763 } 764 } 765 766 /** 767 * {@inheritDoc} 768 * 769 * @return The {@code Modlets} found in the context or {@code null}, if no {@code Modlets} are found or the provider 770 * is disabled. 771 * 772 * @see #isEnabled() 773 * @see #getModletLocation() 774 * @see #findModlets(org.jomc.modlet.ModelContext, java.lang.String) 775 * @see #ENABLED_ATTRIBUTE_NAME 776 * @see #MODLET_LOCATION_ATTRIBUTE_NAME 777 * @deprecated As of JOMC 1.6, this method has been replaced by {@link #findModlets(org.jomc.modlet.ModelContext, org.jomc.modlet.Modlets)}. 778 * This method will be removed in JOMC 2.0. 779 */ 780 @Deprecated 781 public Modlets findModlets( final ModelContext context ) throws ModelException 782 { 783 if ( context == null ) 784 { 785 throw new NullPointerException( "context" ); 786 } 787 788 return this.findModlets( context, new Modlets() ); 789 } 790 791 /** 792 * {@inheritDoc} 793 * 794 * @return The {@code Modlets} found in the context or {@code null}, if no {@code Modlets} are found or the provider 795 * is disabled. 796 * 797 * @see #isEnabled() 798 * @see #getModletLocation() 799 * @see #findModlets(org.jomc.modlet.ModelContext, java.lang.String) 800 * @see #ENABLED_ATTRIBUTE_NAME 801 * @see #MODLET_LOCATION_ATTRIBUTE_NAME 802 * @since 1.6 803 */ 804 public Modlets findModlets( final ModelContext context, final Modlets modlets ) throws ModelException 805 { 806 if ( context == null ) 807 { 808 throw new NullPointerException( "context" ); 809 } 810 if ( modlets == null ) 811 { 812 throw new NullPointerException( "context" ); 813 } 814 815 Modlets provided = null; 816 817 boolean contextEnabled = this.isEnabled(); 818 if ( DEFAULT_ENABLED == contextEnabled && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean ) 819 { 820 contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME ); 821 } 822 823 String contextModletLocation = this.getModletLocation(); 824 if ( DEFAULT_MODLET_LOCATION.equals( contextModletLocation ) 825 && context.getAttribute( MODLET_LOCATION_ATTRIBUTE_NAME ) instanceof String ) 826 { 827 contextModletLocation = (String) context.getAttribute( MODLET_LOCATION_ATTRIBUTE_NAME ); 828 } 829 830 if ( contextEnabled ) 831 { 832 final Modlets found = this.findModlets( context, contextModletLocation ); 833 834 if ( found != null ) 835 { 836 provided = modlets.clone(); 837 provided.getModlet().addAll( found.getModlet() ); 838 } 839 } 840 else if ( context.isLoggable( Level.FINER ) ) 841 { 842 context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName() ), null ); 843 } 844 845 return provided; 846 } 847 848 private static String getMessage( final String key, final Object... arguments ) 849 { 850 return MessageFormat.format( ResourceBundle.getBundle( 851 DefaultModletProvider.class.getName().replace( '.', '/' ) ).getString( key ), arguments ); 852 853 } 854 855 private static String getMessage( final Throwable t ) 856 { 857 return t != null 858 ? t.getMessage() != null && t.getMessage().trim().length() > 0 859 ? t.getMessage() 860 : getMessage( t.getCause() ) 861 : null; 862 863 } 864 865}