001 // SECTION-START[License Header] 002 // <editor-fold defaultstate="collapsed" desc=" Generated License "> 003 /* 004 * Copyright (c) 2009 The JOMC Project 005 * Copyright (c) 2005 Christian Schulte <cs@jomc.org> 006 * All rights reserved. 007 * 008 * Redistribution and use in source and binary forms, with or without 009 * modification, are permitted provided that the following conditions 010 * are met: 011 * 012 * o Redistributions of source code must retain the above copyright 013 * notice, this list of conditions and the following disclaimer. 014 * 015 * o Redistributions in binary form must reproduce the above copyright 016 * notice, this list of conditions and the following disclaimer in 017 * the documentation and/or other materials provided with the 018 * distribution. 019 * 020 * THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS" 021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 022 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 023 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR 024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 027 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 028 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 029 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 030 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 031 * 032 * $Id: DefaultObjectManager.java 1102 2009-12-07 03:01:58Z schulte2005 $ 033 * 034 */ 035 // </editor-fold> 036 // SECTION-END 037 package org.jomc.ri; 038 039 import java.io.BufferedReader; 040 import java.io.File; 041 import java.io.FileInputStream; 042 import java.io.IOException; 043 import java.io.InputStream; 044 import java.io.InputStreamReader; 045 import java.lang.reflect.Array; 046 import java.lang.reflect.Method; 047 import java.lang.reflect.Proxy; 048 import java.net.URI; 049 import java.net.URL; 050 import java.text.MessageFormat; 051 import java.util.ArrayList; 052 import java.util.Comparator; 053 import java.util.Enumeration; 054 import java.util.HashMap; 055 import java.util.HashSet; 056 import java.util.LinkedList; 057 import java.util.List; 058 import java.util.Locale; 059 import java.util.Map; 060 import java.util.ResourceBundle; 061 import java.util.Set; 062 import java.util.TreeMap; 063 import java.util.logging.Level; 064 import java.util.logging.LogRecord; 065 import javax.xml.bind.JAXBContext; 066 import javax.xml.bind.JAXBElement; 067 import javax.xml.bind.JAXBException; 068 import javax.xml.bind.util.JAXBResult; 069 import javax.xml.bind.util.JAXBSource; 070 import javax.xml.transform.Transformer; 071 import javax.xml.transform.TransformerException; 072 import javax.xml.validation.Schema; 073 import org.jomc.ObjectManagementException; 074 import org.jomc.ObjectManager; 075 import org.jomc.ObjectManagerFactory; 076 import org.jomc.model.DefaultModelManager; 077 import org.jomc.model.DefaultModelObjectValidator; 078 import org.jomc.model.Dependency; 079 import org.jomc.model.Implementation; 080 import org.jomc.model.ImplementationReference; 081 import org.jomc.model.Implementations; 082 import org.jomc.model.Instance; 083 import org.jomc.model.Message; 084 import org.jomc.model.ModelObjectValidationReport; 085 import org.jomc.model.ModelObjectValidator; 086 import org.jomc.model.ModelProvider; 087 import org.jomc.model.Module; 088 import org.jomc.model.Modules; 089 import org.jomc.model.Multiplicity; 090 import org.jomc.model.ObjectFactory; 091 import org.jomc.model.Property; 092 import org.jomc.model.Specification; 093 import org.jomc.model.SpecificationReference; 094 import org.jomc.spi.Invocation; 095 import org.jomc.spi.Invoker; 096 import org.jomc.spi.Listener; 097 import org.jomc.spi.Locator; 098 import org.jomc.spi.Scope; 099 import org.jomc.util.WeakIdentityHashMap; 100 import org.xml.sax.SAXException; 101 102 // SECTION-START[Documentation] 103 // <editor-fold defaultstate="collapsed" desc=" Generated Documentation "> 104 /** 105 * Object management and configuration reference implementation. 106 * <p><b>Specifications</b><ul> 107 * <li>{@code org.jomc.ObjectManager} {@code 1.0} {@code Singleton}</li> 108 * </ul></p> 109 * 110 * @author <a href="mailto:cs@jomc.org">Christian Schulte</a> 1.0 111 * @version $Id: DefaultObjectManager.java 1102 2009-12-07 03:01:58Z schulte2005 $ 112 */ 113 // </editor-fold> 114 // SECTION-END 115 // SECTION-START[Annotations] 116 // <editor-fold defaultstate="collapsed" desc=" Generated Annotations "> 117 @javax.annotation.Generated( value = "org.jomc.tools.JavaSources", 118 comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-11/jomc-tools" ) 119 // </editor-fold> 120 // SECTION-END 121 public class DefaultObjectManager implements ObjectManager 122 { 123 // SECTION-START[Constructors] 124 // <editor-fold defaultstate="collapsed" desc=" Generated Constructors "> 125 126 /** Creates a new {@code DefaultObjectManager} instance. */ 127 @javax.annotation.Generated( value = "org.jomc.tools.JavaSources", 128 comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-11/jomc-tools" ) 129 public DefaultObjectManager() 130 { 131 // SECTION-START[Default Constructor] 132 super(); 133 // SECTION-END 134 } 135 // </editor-fold> 136 // SECTION-END 137 // SECTION-START[ObjectManager] 138 139 public Object getObject( final Class specification ) 140 { 141 if ( specification == null ) 142 { 143 throw new NullPointerException( "specification" ); 144 } 145 146 try 147 { 148 this.initialize(); 149 150 final ClassLoader classLoader = getClassLoader( specification ); 151 final Modules model = this.getModules( classLoader ); 152 final Specification s = model.getSpecification( specification ); 153 154 if ( s == null ) 155 { 156 if ( this.isLoggable( Level.WARNING ) ) 157 { 158 this.log( Level.WARNING, this.getMissingSpecificationMessage( 159 specification.getName() ), new Exception() ); 160 161 } 162 163 return null; 164 } 165 166 Scope scope = null; 167 if ( s.getScope() != null ) 168 { 169 scope = this.getScope( classLoader, s.getScope() ); 170 171 if ( scope == null ) 172 { 173 if ( this.isLoggable( Level.WARNING ) ) 174 { 175 this.log( Level.WARNING, this.getMissingScopeMessage( s.getScope() ), null ); 176 } 177 178 return null; 179 } 180 } 181 182 final Implementations available = model.getImplementations( s.getIdentifier() ); 183 if ( available == null || available.getImplementation().isEmpty() ) 184 { 185 if ( this.isLoggable( Level.WARNING ) ) 186 { 187 this.log( Level.WARNING, this.getMissingImplementationsMessage( 188 specification.getName() ), new Exception() ); 189 190 } 191 192 return null; 193 } 194 195 if ( s.getMultiplicity() == Multiplicity.ONE ) 196 { 197 final Implementation i = available.getImplementation().get( 0 ); 198 199 if ( i.getLocation() != null ) 200 { 201 if ( s.getClazz() == null ) 202 { 203 if ( this.isLoggable( Level.WARNING ) ) 204 { 205 this.log( Level.WARNING, this.getMissingSpecificationClassMessage( s ), new Exception() ); 206 } 207 208 return null; 209 } 210 211 final Object object = this.getObject( 212 Class.forName( s.getClazz(), true, classLoader ), i.getLocationUri(), classLoader ); 213 214 if ( object == null ) 215 { 216 if ( this.isLoggable( Level.WARNING ) ) 217 { 218 this.log( Level.WARNING, this.getMissingObjectMessage( 219 i.getIdentifier(), i.getName() ), new Exception() ); 220 221 } 222 223 return null; 224 } 225 226 return object; 227 } 228 else if ( !i.isAbstract() ) 229 { 230 final Instance instance = model.getInstance( i.getIdentifier() ); 231 if ( instance == null ) 232 { 233 if ( this.isLoggable( Level.WARNING ) ) 234 { 235 this.log( Level.WARNING, this.getMissingInstanceMessage( 236 i.getIdentifier(), i.getName() ), new Exception() ); 237 238 } 239 240 return null; 241 } 242 243 final Object object = this.getObject( scope, instance, classLoader ); 244 if ( object == null ) 245 { 246 if ( this.isLoggable( Level.WARNING ) ) 247 { 248 this.log( Level.WARNING, this.getMissingObjectMessage( 249 i.getIdentifier(), i.getName() ), new Exception() ); 250 251 } 252 253 return null; 254 } 255 256 return object; 257 } 258 } 259 else if ( s.getMultiplicity() == Multiplicity.MANY ) 260 { 261 final List<Object> list = new ArrayList<Object>( available.getImplementation().size() ); 262 263 for ( Implementation i : available.getImplementation() ) 264 { 265 if ( i.getLocation() != null ) 266 { 267 if ( s.getClazz() == null ) 268 { 269 if ( this.isLoggable( Level.WARNING ) ) 270 { 271 this.log( Level.WARNING, this.getMissingSpecificationClassMessage( s ), 272 new Exception() ); 273 274 } 275 276 return null; 277 } 278 279 final Object o = this.getObject( 280 Class.forName( s.getClazz(), true, classLoader ), i.getLocationUri(), classLoader ); 281 282 if ( o == null ) 283 { 284 if ( this.isLoggable( Level.WARNING ) ) 285 { 286 this.log( Level.WARNING, this.getMissingObjectMessage( 287 i.getIdentifier(), i.getName() ), new Exception() ); 288 289 } 290 } 291 else 292 { 293 list.add( o ); 294 } 295 } 296 else if ( !i.isAbstract() ) 297 { 298 final Instance instance = model.getInstance( i.getIdentifier() ); 299 if ( instance == null ) 300 { 301 if ( this.isLoggable( Level.WARNING ) ) 302 { 303 this.log( Level.WARNING, this.getMissingInstanceMessage( 304 i.getIdentifier(), i.getName() ), new Exception() ); 305 306 } 307 308 return null; 309 } 310 311 final Object o = this.getObject( scope, instance, classLoader ); 312 if ( o == null ) 313 { 314 if ( this.isLoggable( Level.WARNING ) ) 315 { 316 this.log( Level.WARNING, this.getMissingObjectMessage( 317 i.getIdentifier(), i.getName() ), new Exception() ); 318 319 } 320 } 321 else 322 { 323 list.add( o ); 324 } 325 } 326 } 327 328 return list.isEmpty() 329 ? null : list.toArray( (Object[]) Array.newInstance( specification, list.size() ) ); 330 331 } 332 else if ( this.isLoggable( Level.WARNING ) ) 333 { 334 this.log( Level.WARNING, this.getUnsupportedMultiplicityMessage( 335 s.getMultiplicity() ), new Exception() ); 336 337 } 338 339 return null; 340 } 341 catch ( final Exception e ) 342 { 343 throw new ObjectManagementException( e.getMessage(), e ); 344 } 345 } 346 347 public Object getObject( final Class specification, final String implementationName ) 348 { 349 if ( specification == null ) 350 { 351 throw new NullPointerException( "specification" ); 352 } 353 if ( implementationName == null ) 354 { 355 throw new NullPointerException( "implementationName" ); 356 } 357 358 try 359 { 360 this.initialize(); 361 362 final ClassLoader classLoader = getClassLoader( specification ); 363 final Modules model = this.getModules( classLoader ); 364 final Specification s = model.getSpecification( specification ); 365 366 if ( s == null ) 367 { 368 if ( this.isLoggable( Level.WARNING ) ) 369 { 370 this.log( Level.WARNING, this.getMissingSpecificationMessage( 371 specification.getName() ), new Exception() ); 372 373 } 374 375 return null; 376 } 377 378 Scope scope = null; 379 if ( s.getScope() != null ) 380 { 381 scope = this.getScope( classLoader, s.getScope() ); 382 383 if ( scope == null ) 384 { 385 if ( this.isLoggable( Level.WARNING ) ) 386 { 387 this.log( Level.WARNING, this.getMissingScopeMessage( s.getScope() ), null ); 388 } 389 390 return null; 391 } 392 } 393 394 final Implementations available = model.getImplementations( s.getIdentifier() ); 395 if ( available == null || available.getImplementation().isEmpty() ) 396 { 397 if ( this.isLoggable( Level.WARNING ) ) 398 { 399 this.log( Level.WARNING, this.getMissingImplementationsMessage( 400 specification.getName() ), new Exception() ); 401 402 } 403 404 return null; 405 } 406 407 final Implementation i = available.getImplementationByName( implementationName ); 408 if ( i == null ) 409 { 410 if ( this.isLoggable( Level.WARNING ) ) 411 { 412 this.log( Level.WARNING, this.getMissingImplementationMessage( 413 implementationName, s.getIdentifier() ), new Exception() ); 414 415 } 416 417 return null; 418 } 419 420 if ( i.getLocation() != null ) 421 { 422 if ( s.getClazz() == null ) 423 { 424 if ( this.isLoggable( Level.WARNING ) ) 425 { 426 this.log( Level.WARNING, this.getMissingSpecificationClassMessage( s ), new Exception() ); 427 } 428 429 return null; 430 } 431 432 final Object object = this.getObject( 433 Class.forName( s.getClazz(), true, classLoader ), i.getLocationUri(), classLoader ); 434 435 if ( object == null ) 436 { 437 if ( this.isLoggable( Level.WARNING ) ) 438 { 439 this.log( Level.WARNING, this.getMissingObjectMessage( 440 i.getIdentifier(), i.getName() ), new Exception() ); 441 442 } 443 444 return null; 445 } 446 447 return object; 448 } 449 else if ( !i.isAbstract() ) 450 { 451 final Instance instance = model.getInstance( i.getIdentifier() ); 452 if ( instance == null ) 453 { 454 if ( this.isLoggable( Level.WARNING ) ) 455 { 456 this.log( Level.WARNING, this.getMissingInstanceMessage( 457 i.getIdentifier(), i.getName() ), new Exception() ); 458 459 } 460 461 return null; 462 } 463 464 final Object object = this.getObject( scope, instance, classLoader ); 465 if ( object == null ) 466 { 467 if ( this.isLoggable( Level.WARNING ) ) 468 { 469 this.log( Level.WARNING, this.getMissingObjectMessage( 470 i.getIdentifier(), i.getName() ), new Exception() ); 471 472 } 473 474 return null; 475 } 476 477 return object; 478 } 479 480 return null; 481 } 482 catch ( final Exception e ) 483 { 484 throw new ObjectManagementException( e.getMessage(), e ); 485 } 486 } 487 488 public Object getDependency( final Object object, final String dependencyName ) 489 { 490 if ( object == null ) 491 { 492 throw new NullPointerException( "object" ); 493 } 494 if ( dependencyName == null ) 495 { 496 throw new NullPointerException( "dependencyName" ); 497 } 498 499 try 500 { 501 this.initialize(); 502 503 final ClassLoader classLoader = getClassLoader( object.getClass() ); 504 final Modules model = this.getModules( classLoader ); 505 final Instance instance = model.getInstance( object ); 506 507 if ( instance == null ) 508 { 509 if ( this.isLoggable( Level.WARNING ) ) 510 { 511 this.log( Level.WARNING, this.getMissingObjectInstanceMessage( object ), new Exception() ); 512 } 513 514 return null; 515 } 516 517 synchronized ( instance ) 518 { 519 final Dependency dependency = instance.getDependencies() != null 520 ? instance.getDependencies().getDependency( dependencyName ) : null; 521 522 if ( dependency == null ) 523 { 524 if ( this.isLoggable( Level.WARNING ) ) 525 { 526 this.log( Level.WARNING, this.getMissingDependencyMessage( 527 dependencyName, instance.getIdentifier() ), new Exception() ); 528 529 } 530 531 return null; 532 } 533 534 Object o = instance.getDependencyObjects().get( dependencyName ); 535 if ( o == null ) 536 { 537 final Specification ds = model.getSpecification( dependency.getIdentifier() ); 538 if ( ds == null ) 539 { 540 if ( this.isLoggable( Level.WARNING ) ) 541 { 542 this.log( Level.WARNING, this.getMissingSpecificationMessage( 543 dependency.getIdentifier() ), new Exception() ); 544 545 } 546 547 return null; 548 } 549 550 Scope scope = null; 551 if ( ds.getScope() != null ) 552 { 553 scope = this.getScope( classLoader, ds.getScope() ); 554 555 if ( scope == null ) 556 { 557 if ( this.isLoggable( Level.WARNING ) ) 558 { 559 this.log( Level.WARNING, this.getMissingScopeMessage( ds.getScope() ), null ); 560 } 561 562 return null; 563 } 564 } 565 566 final Implementations available = model.getImplementations( ds.getIdentifier() ); 567 if ( available == null || available.getImplementation().isEmpty() ) 568 { 569 if ( !dependency.isOptional() && this.isLoggable( Level.WARNING ) ) 570 { 571 this.log( Level.WARNING, this.getMissingImplementationsMessage( 572 dependency.getIdentifier() ), new Exception() ); 573 574 } 575 576 return null; 577 } 578 579 if ( dependency.getImplementationName() != null ) 580 { 581 final Implementation i = 582 available.getImplementationByName( dependency.getImplementationName() ); 583 584 if ( i == null ) 585 { 586 if ( !dependency.isOptional() && this.isLoggable( Level.WARNING ) ) 587 { 588 this.log( Level.WARNING, this.getMissingImplementationMessage( 589 dependency.getImplementationName(), dependency.getIdentifier() ), new Exception() ); 590 591 } 592 593 return null; 594 } 595 596 if ( i.getLocation() != null ) 597 { 598 if ( ds.getClazz() == null ) 599 { 600 if ( this.isLoggable( Level.WARNING ) ) 601 { 602 this.log( Level.WARNING, this.getMissingSpecificationClassMessage( ds ), 603 new Exception() ); 604 605 } 606 607 return null; 608 } 609 610 o = this.getObject( 611 Class.forName( ds.getClazz(), true, classLoader ), i.getLocationUri(), classLoader ); 612 613 if ( o == null ) 614 { 615 if ( this.isLoggable( Level.WARNING ) ) 616 { 617 this.log( Level.WARNING, this.getMissingObjectMessage( 618 i.getIdentifier(), i.getName() ), new Exception() ); 619 620 } 621 622 return null; 623 } 624 } 625 else if ( !i.isAbstract() ) 626 { 627 final Instance di = model.getInstance( i.getIdentifier(), dependency ); 628 if ( di == null ) 629 { 630 if ( this.isLoggable( Level.WARNING ) ) 631 { 632 this.log( Level.WARNING, this.getMissingInstanceMessage( 633 i.getIdentifier(), i.getName() ), new Exception() ); 634 635 } 636 637 return null; 638 } 639 640 o = this.getObject( scope, di, classLoader ); 641 if ( o == null ) 642 { 643 if ( this.isLoggable( Level.WARNING ) ) 644 { 645 this.log( Level.WARNING, this.getMissingObjectMessage( 646 i.getIdentifier(), i.getName() ), new Exception() ); 647 648 } 649 650 return null; 651 } 652 } 653 } 654 else if ( ds.getMultiplicity() == Multiplicity.ONE ) 655 { 656 final Implementation ref = available.getImplementation().get( 0 ); 657 if ( ref.getLocation() != null ) 658 { 659 if ( ds.getClazz() == null ) 660 { 661 if ( this.isLoggable( Level.WARNING ) ) 662 { 663 this.log( Level.WARNING, this.getMissingSpecificationClassMessage( ds ), 664 new Exception() ); 665 } 666 667 return null; 668 } 669 670 o = this.getObject( 671 Class.forName( ds.getClazz(), true, classLoader ), ref.getLocationUri(), classLoader ); 672 673 if ( o == null ) 674 { 675 if ( this.isLoggable( Level.WARNING ) ) 676 { 677 this.log( Level.WARNING, this.getMissingObjectMessage( 678 ref.getIdentifier(), ref.getName() ), new Exception() ); 679 680 } 681 682 return null; 683 } 684 } 685 else if ( !ref.isAbstract() ) 686 { 687 final Instance di = model.getInstance( ref.getIdentifier(), dependency ); 688 if ( di == null ) 689 { 690 if ( this.isLoggable( Level.WARNING ) ) 691 { 692 this.log( Level.WARNING, this.getMissingInstanceMessage( 693 ref.getIdentifier(), ref.getName() ), new Exception() ); 694 695 } 696 697 return null; 698 } 699 700 o = this.getObject( scope, di, classLoader ); 701 if ( o == null ) 702 { 703 if ( this.isLoggable( Level.WARNING ) ) 704 { 705 this.log( Level.WARNING, this.getMissingObjectMessage( 706 ref.getIdentifier(), ref.getName() ), new Exception() ); 707 708 } 709 710 return null; 711 } 712 } 713 } 714 else 715 { 716 final List<Object> list = new ArrayList<Object>( available.getImplementation().size() ); 717 718 if ( !available.getImplementation().isEmpty() && ds.getClazz() == null ) 719 { 720 if ( this.isLoggable( Level.WARNING ) ) 721 { 722 this.log( Level.WARNING, this.getMissingSpecificationClassMessage( ds ), 723 new Exception() ); 724 725 } 726 727 return null; 728 } 729 730 for ( Implementation a : available.getImplementation() ) 731 { 732 if ( a.getLocation() != null ) 733 { 734 final Object o2 = this.getObject( Class.forName( ds.getClazz(), true, classLoader ), 735 a.getLocationUri(), classLoader ); 736 737 if ( o2 == null ) 738 { 739 if ( this.isLoggable( Level.WARNING ) ) 740 { 741 this.log( Level.WARNING, this.getMissingObjectMessage( 742 a.getIdentifier(), a.getName() ), new Exception() ); 743 744 } 745 } 746 else 747 { 748 list.add( o2 ); 749 } 750 } 751 else if ( !a.isAbstract() ) 752 { 753 final Instance di = model.getInstance( a.getIdentifier(), dependency ); 754 if ( di == null ) 755 { 756 if ( this.isLoggable( Level.WARNING ) ) 757 { 758 this.log( Level.WARNING, this.getMissingInstanceMessage( 759 a.getIdentifier(), a.getName() ), new Exception() ); 760 761 } 762 763 return null; 764 } 765 766 final Object o2 = this.getObject( scope, di, classLoader ); 767 if ( o2 == null ) 768 { 769 if ( this.isLoggable( Level.WARNING ) ) 770 { 771 this.log( Level.WARNING, this.getMissingObjectMessage( 772 a.getIdentifier(), a.getName() ), new Exception() ); 773 774 } 775 } 776 else 777 { 778 list.add( o2 ); 779 } 780 } 781 } 782 783 o = list.isEmpty() ? null : list.toArray( (Object[]) Array.newInstance( Class.forName( 784 ds.getClazz(), true, classLoader ), list.size() ) ); 785 786 } 787 } 788 789 if ( o != null && dependency.isBound() ) 790 { 791 instance.getDependencyObjects().put( dependencyName, o ); 792 } 793 794 return o; 795 } 796 } 797 catch ( final Exception e ) 798 { 799 throw new ObjectManagementException( e.getMessage(), e ); 800 } 801 } 802 803 public Object getProperty( final Object object, final String propertyName ) 804 { 805 if ( object == null ) 806 { 807 throw new NullPointerException( "object" ); 808 } 809 if ( propertyName == null ) 810 { 811 throw new NullPointerException( "propertyName" ); 812 } 813 814 try 815 { 816 this.initialize(); 817 818 final ClassLoader classLoader = getClassLoader( object.getClass() ); 819 final Modules model = this.getModules( classLoader ); 820 final Instance instance = model.getInstance( object ); 821 822 if ( instance == null ) 823 { 824 if ( this.isLoggable( Level.WARNING ) ) 825 { 826 this.log( Level.WARNING, this.getMissingObjectInstanceMessage( object ), new Exception() ); 827 } 828 829 return null; 830 } 831 832 synchronized ( instance ) 833 { 834 Object value = instance.getPropertyObjects().get( propertyName ); 835 if ( value == null ) 836 { 837 final Property property = 838 instance.getProperties() != null ? instance.getProperties().getProperty( propertyName ) : null; 839 840 if ( property == null ) 841 { 842 if ( this.isLoggable( Level.WARNING ) ) 843 { 844 this.log( Level.WARNING, this.getMissingPropertyMessage( 845 propertyName, object.getClass().getName() ), new Exception() ); 846 847 } 848 849 return null; 850 } 851 852 value = property.getJavaValue( classLoader ); 853 if ( value != null ) 854 { 855 instance.getPropertyObjects().put( propertyName, value ); 856 } 857 } 858 859 return value; 860 } 861 } 862 catch ( final Exception e ) 863 { 864 throw new ObjectManagementException( e.getMessage(), e ); 865 } 866 } 867 868 public String getMessage( final Object object, final String messageName, final Locale locale, 869 final Object arguments ) 870 { 871 if ( object == null ) 872 { 873 throw new NullPointerException( "object" ); 874 } 875 if ( messageName == null ) 876 { 877 throw new NullPointerException( "messageName" ); 878 } 879 if ( locale == null ) 880 { 881 throw new NullPointerException( "locale" ); 882 } 883 884 try 885 { 886 this.initialize(); 887 888 final ClassLoader classLoader = getClassLoader( object.getClass() ); 889 final Modules model = this.getModules( classLoader ); 890 final Instance instance = model.getInstance( object ); 891 892 if ( instance == null ) 893 { 894 if ( this.isLoggable( Level.WARNING ) ) 895 { 896 this.log( Level.WARNING, this.getMissingObjectInstanceMessage( object ), new Exception() ); 897 } 898 899 return null; 900 } 901 902 synchronized ( instance ) 903 { 904 final Message message = 905 instance.getMessages() != null ? instance.getMessages().getMessage( messageName ) : null; 906 907 if ( message == null || message.getTemplate() == null ) 908 { 909 if ( this.isLoggable( Level.WARNING ) ) 910 { 911 this.log( Level.WARNING, this.getMissingMessageMessage( 912 messageName, object.getClass().getName() ), new Exception() ); 913 914 } 915 916 return null; 917 } 918 919 final MessageFormat fmt = new MessageFormat( message.getTemplate().getText( 920 locale.getLanguage().toLowerCase( Locale.ENGLISH ) ).getValue(), locale ); 921 922 return fmt.format( arguments ); 923 } 924 } 925 catch ( final Exception e ) 926 { 927 throw new ObjectManagementException( e.getMessage(), e ); 928 } 929 } 930 931 // SECTION-END 932 // SECTION-START[DefaultObjectManager] 933 /** Constant for the {@code Singleton} scope identifier. */ 934 protected static final String SINGLETON_SCOPE_IDENTIFIER = "Singleton"; 935 936 /** 937 * Log level events are logged at by default. 938 * @see #getDefaultLogLevel() 939 */ 940 private static final Level DEFAULT_LOG_LEVEL = Level.WARNING; 941 942 /** Default log level. */ 943 private static volatile Level defaultLogLevel; 944 945 /** Name of the platform's bootstrap class loader class. */ 946 private static volatile String bootstrapClassLoaderClassName; 947 948 private static volatile boolean bootstrapClassLoaderClassNameInitialized; 949 950 /** {@code ClassLoader} instance representing the bootstrap class loader. */ 951 private static final ClassLoader BOOTSTRAP_CLASSLOADER = new ClassLoader( null ) 952 { 953 }; 954 955 /** Listeners of the instance. */ 956 private List<Listener> listeners; 957 958 /** Flag indicating that initialization has been performed. */ 959 private boolean initialized; 960 961 /** Log level of the instance. */ 962 private Level logLevel; 963 964 /** Modules of the instance. */ 965 private final Map<ClassLoader, Modules> modules = new WeakIdentityHashMap(); 966 967 /** Invokers of the instance. */ 968 private final Map<ClassLoader, Invoker> invokers = new WeakIdentityHashMap(); 969 970 /** Scopes of the instance. */ 971 private final Map<ClassLoader, Map<String, Scope>> scopes = new WeakIdentityHashMap(); 972 973 /** Locators of the instance. */ 974 private final Map<ClassLoader, Map<String, Locator>> locators = new WeakIdentityHashMap(); 975 976 /** Objects of the instance. */ 977 private final Map<ClassLoader, Map<Object, Instance>> objects = new WeakIdentityHashMap(); 978 979 /** {@code ObjectManager} singletons. */ 980 private static final Map<ClassLoader, ObjectManager> singletons = new WeakIdentityHashMap(); 981 982 /** 983 * Default {@link ObjectManagerFactory#getObjectManager(ClassLoader)} implementation. 984 * 985 * @return The default {@code ObjectManager} singleton instance. 986 * 987 * @see ObjectManagerFactory#getObjectManager(ClassLoader) 988 */ 989 public static ObjectManager getObjectManager( final ClassLoader classLoader ) 990 { 991 synchronized ( singletons ) 992 { 993 final ClassLoader singletonsLoader = getClassLoader( classLoader ); 994 ObjectManager manager = singletons.get( singletonsLoader ); 995 if ( manager == null ) 996 { 997 manager = ObjectManagerFactory.newObjectManager( classLoader ); 998 singletons.put( singletonsLoader, manager ); 999 } 1000 1001 return (ObjectManager) manager.getObject( ObjectManager.class ); 1002 } 1003 } 1004 1005 /** 1006 * Gets the list of registered listeners. 1007 * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make 1008 * to the returned list will be present inside the object. This is why there is no {@code set} method for the 1009 * listeners property.</p> 1010 * 1011 * @return The list of registered listeners. 1012 */ 1013 public List<Listener> getListeners() 1014 { 1015 if ( this.listeners == null ) 1016 { 1017 this.listeners = new LinkedList<Listener>(); 1018 } 1019 1020 return this.listeners; 1021 } 1022 1023 /** 1024 * Gets the default log level events are logged at. 1025 * <p>The default log level is controlled by system property 1026 * {@code org.jomc.ri.DefaultObjectManager.defaultLogLevel} holding the log level to log events at by default. 1027 * If that property is not set, the {@code WARNING} default is returned.</p> 1028 * 1029 * @return The log level events are logged at by default. 1030 * 1031 * @see #getLogLevel() 1032 * @see Level#parse(java.lang.String) 1033 */ 1034 public static Level getDefaultLogLevel() 1035 { 1036 if ( defaultLogLevel == null ) 1037 { 1038 defaultLogLevel = Level.parse( System.getProperty( "org.jomc.ri.DefaultObjectManager.defaultLogLevel", 1039 DEFAULT_LOG_LEVEL.getName() ) ); 1040 1041 } 1042 1043 return defaultLogLevel; 1044 } 1045 1046 /** 1047 * Sets the default log level events are logged at. 1048 * 1049 * @param value The new default level events are logged at or {@code null}. 1050 * 1051 * @see #getDefaultLogLevel() 1052 */ 1053 public static void setDefaultLogLevel( final Level value ) 1054 { 1055 defaultLogLevel = value; 1056 } 1057 1058 /** 1059 * Gets the log level of the instance. 1060 * 1061 * @return The log level of the instance. 1062 * 1063 * @see #getDefaultLogLevel() 1064 * @see #setLogLevel(java.util.logging.Level) 1065 * @see #isLoggable(java.util.logging.Level) 1066 */ 1067 public Level getLogLevel() 1068 { 1069 if ( this.logLevel == null ) 1070 { 1071 this.logLevel = getDefaultLogLevel(); 1072 this.log( Level.CONFIG, this.getMessage( "defaultLogLevelInfo", new Object[] 1073 { 1074 this.getClass().getCanonicalName(), this.logLevel.getLocalizedName() 1075 } ), null ); 1076 1077 } 1078 1079 return this.logLevel; 1080 } 1081 1082 /** 1083 * Sets the log level of the instance. 1084 * 1085 * @param value The new log level of the instance or {@code null}. 1086 * 1087 * @see #getLogLevel() 1088 * @see #isLoggable(java.util.logging.Level) 1089 */ 1090 public void setLogLevel( final Level value ) 1091 { 1092 this.logLevel = value; 1093 } 1094 1095 /** 1096 * Checks if a message at a given level is provided to the listeners of the instance. 1097 * 1098 * @param level The level to test. 1099 * 1100 * @return {@code true} if messages at {@code level} are provided to the listeners of the instance; 1101 * {@code false} if messages at {@code level} are not provided to the listeners of the instance. 1102 * 1103 * @throws NullPointerException if {@code level} is {@code null}. 1104 * 1105 * @see #getLogLevel() 1106 * @see #setLogLevel(java.util.logging.Level) 1107 * @see #log(java.util.logging.Level, java.lang.String, java.lang.Throwable) 1108 */ 1109 public boolean isLoggable( final Level level ) 1110 { 1111 if ( level == null ) 1112 { 1113 throw new NullPointerException( "level" ); 1114 } 1115 1116 return level.intValue() >= this.getLogLevel().intValue(); 1117 } 1118 1119 /** 1120 * Gets the name of the platform's bootstrap class loader class. 1121 * <p>The name of the platform's bootstrap class loader class is controlled by system property 1122 * {@code org.jomc.ri.DefaultObjectManager.bootstrapClassLoaderClassName} holding the name of the platform's 1123 * bootstrap class loader class. If that property is not set, the bootstrap class loader is assumed to be 1124 * represented by a {@code null} parent class loader.</p> 1125 * 1126 * @return The name of the platform's bootstrap class loader class or {@code null}. 1127 * 1128 * @see #getClassLoader(java.lang.ClassLoader) 1129 */ 1130 public static String getBootstrapClassLoaderClassName() 1131 { 1132 if ( bootstrapClassLoaderClassName == null && !bootstrapClassLoaderClassNameInitialized ) 1133 { 1134 bootstrapClassLoaderClassName = 1135 System.getProperty( "org.jomc.ri.DefaultObjectManager.bootstrapClassLoaderClassName" ); 1136 1137 bootstrapClassLoaderClassNameInitialized = true; 1138 } 1139 1140 return bootstrapClassLoaderClassName; 1141 } 1142 1143 /** 1144 * Sets the name of the platform's bootstrap class loader class. 1145 * 1146 * @param value The new name of the platform's bootstrap class loader class or {@code null}. 1147 * 1148 * @see #getBootstrapClassLoaderClassName() 1149 */ 1150 public static void setBootstrapClassLoaderClassName( final String value ) 1151 { 1152 bootstrapClassLoaderClassName = value; 1153 bootstrapClassLoaderClassNameInitialized = false; 1154 } 1155 1156 /** 1157 * Gets the modules of a given class loader. 1158 * 1159 * @param classLoader The class loader to get the modules of. 1160 * 1161 * @return The modules of the given class loader. 1162 * 1163 * @throws NullPointerException if {@code classLoader} is {@code null}, 1164 */ 1165 public Modules getModules( final ClassLoader classLoader ) 1166 { 1167 if ( classLoader == null ) 1168 { 1169 throw new NullPointerException( "classLoader" ); 1170 } 1171 1172 synchronized ( this.modules ) 1173 { 1174 Modules cachedModules = this.modules.get( classLoader ); 1175 1176 if ( cachedModules == null ) 1177 { 1178 try 1179 { 1180 final DefaultModelManager defaultModelManager = new DefaultModelManager(); 1181 defaultModelManager.setLogLevel( this.getLogLevel() ); 1182 defaultModelManager.getListeners().add( new DefaultModelManager.Listener() 1183 { 1184 1185 public void onLog( final Level level, final String message, final Throwable t ) 1186 { 1187 log( level, message, t ); 1188 } 1189 1190 } ); 1191 1192 final ObjectFactory objectFactory = new ObjectFactory(); 1193 final JAXBContext context = defaultModelManager.getContext( classLoader ); 1194 final Schema schema = defaultModelManager.getSchema( classLoader ); 1195 1196 cachedModules = defaultModelManager.getClasspathModules( 1197 classLoader, DefaultModelManager.getDefaultModuleLocation() ); 1198 1199 final Map<String, Class<ModelProvider>> providers = 1200 new TreeMap<String, Class<ModelProvider>>( new Comparator<String>() 1201 { 1202 1203 public int compare( final String key1, final String key2 ) 1204 { 1205 return key1.compareTo( key2 ); 1206 } 1207 1208 } ); 1209 1210 final File platformProviders = new File( new StringBuilder().append( 1211 System.getProperty( "java.home" ) ).append( File.separator ).append( "jre" ). 1212 append( File.separator ).append( "lib" ).append( File.separator ).append( "jomc.properties" ). 1213 toString() ); 1214 1215 if ( platformProviders.exists() ) 1216 { 1217 if ( this.isLoggable( Level.CONFIG ) ) 1218 { 1219 this.log( Level.CONFIG, this.getMessage( "processing", new Object[] 1220 { 1221 platformProviders.getAbsolutePath() 1222 } ), null ); 1223 1224 } 1225 1226 InputStream in = null; 1227 final java.util.Properties p = new java.util.Properties(); 1228 1229 try 1230 { 1231 in = new FileInputStream( platformProviders ); 1232 p.load( in ); 1233 } 1234 finally 1235 { 1236 if ( in != null ) 1237 { 1238 in.close(); 1239 } 1240 } 1241 1242 for ( Map.Entry e : p.entrySet() ) 1243 { 1244 if ( e.getKey().toString().startsWith( "org.jomc.model.ModelProvider." ) ) 1245 { 1246 providers.put( e.getKey().toString(), (Class<ModelProvider>) Class.forName( 1247 e.getValue().toString(), true, classLoader ) ); 1248 1249 } 1250 } 1251 } 1252 1253 final Enumeration<URL> serviceProviders = 1254 classLoader.getResources( "META-INF/services/org.jomc.model.ModelProvider" ); 1255 1256 if ( serviceProviders != null ) 1257 { 1258 while ( serviceProviders.hasMoreElements() ) 1259 { 1260 String line; 1261 final URL serviceProvider = serviceProviders.nextElement(); 1262 1263 if ( this.isLoggable( Level.CONFIG ) ) 1264 { 1265 this.log( Level.CONFIG, this.getMessage( "processing", new Object[] 1266 { 1267 serviceProvider.toExternalForm() 1268 } ), null ); 1269 1270 } 1271 1272 BufferedReader reader = null; 1273 try 1274 { 1275 reader = new BufferedReader( new InputStreamReader( 1276 serviceProvider.openStream(), "UTF-8" ) ); 1277 1278 while ( ( line = reader.readLine() ) != null ) 1279 { 1280 if ( line.contains( "#" ) ) 1281 { 1282 continue; 1283 } 1284 1285 providers.put( "org.jomc.model.ModelProvider." + providers.size(), 1286 (Class<ModelProvider>) Class.forName( line, true, classLoader ) ); 1287 1288 } 1289 } 1290 finally 1291 { 1292 if ( reader != null ) 1293 { 1294 reader.close(); 1295 } 1296 } 1297 } 1298 } 1299 1300 for ( Class<ModelProvider> provider : providers.values() ) 1301 { 1302 if ( this.isLoggable( Level.CONFIG ) ) 1303 { 1304 this.log( Level.CONFIG, this.getMessage( "modelProviderInfo", new Object[] 1305 { 1306 provider.getName() 1307 } ), null ); 1308 1309 } 1310 1311 final ModelProvider modelProvider = provider.newInstance(); 1312 final Modules providerModules = 1313 modelProvider.getModules( classLoader, new Modules( cachedModules ) ); 1314 1315 if ( providerModules != null ) 1316 { 1317 cachedModules.getModule().addAll( providerModules.getModule() ); 1318 } 1319 } 1320 1321 final Module classpathModule = 1322 cachedModules.getClasspathModule( Modules.getDefaultClasspathModuleName(), classLoader ); 1323 1324 if ( classpathModule != null ) 1325 { 1326 cachedModules.getModule().add( classpathModule ); 1327 } 1328 1329 final List<Transformer> defaultTransformers = defaultModelManager.getClasspathTransformers( 1330 classLoader, DefaultModelManager.getDefaultTransformerLocation() ); 1331 1332 for ( Transformer t : defaultTransformers ) 1333 { 1334 final JAXBElement<Modules> e = objectFactory.createModules( cachedModules ); 1335 final JAXBSource source = new JAXBSource( context, e ); 1336 final JAXBResult result = new JAXBResult( context ); 1337 t.transform( source, result ); 1338 cachedModules = ( (JAXBElement<Modules>) result.getResult() ).getValue(); 1339 } 1340 1341 final ModelObjectValidator modelObjectValidator = new DefaultModelObjectValidator(); 1342 final ModelObjectValidationReport validationReport = modelObjectValidator.validateModules( 1343 objectFactory.createModules( cachedModules ), context, schema ); 1344 1345 for ( ModelObjectValidationReport.Detail d : validationReport.getDetails() ) 1346 { 1347 if ( this.isLoggable( d.getLevel() ) ) 1348 { 1349 this.log( d.getLevel(), d.getMessage(), null ); 1350 } 1351 } 1352 1353 if ( validationReport.isModelObjectValid() ) 1354 { 1355 final ClassLoader objectsLoader = getClassLoader( classLoader ); 1356 Map<Object, Instance> objectMap = this.objects.get( objectsLoader ); 1357 if ( objectMap == null ) 1358 { 1359 objectMap = new WeakIdentityHashMap(); 1360 this.objects.put( objectsLoader, objectMap ); 1361 } 1362 1363 this.modules.put( classLoader, new Modules( cachedModules, objectMap ) ); 1364 1365 if ( this.isLoggable( Level.FINE ) ) 1366 { 1367 this.log( Level.FINE, this.getModulesReport( cachedModules, classLoader ), null ); 1368 } 1369 } 1370 else 1371 { 1372 cachedModules = null; 1373 } 1374 } 1375 catch ( final ClassNotFoundException e ) 1376 { 1377 if ( this.isLoggable( Level.SEVERE ) ) 1378 { 1379 this.log( Level.SEVERE, e.getMessage(), e ); 1380 } 1381 1382 cachedModules = null; 1383 } 1384 catch ( final InstantiationException e ) 1385 { 1386 if ( this.isLoggable( Level.SEVERE ) ) 1387 { 1388 this.log( Level.SEVERE, e.getMessage(), e ); 1389 } 1390 1391 cachedModules = null; 1392 } 1393 catch ( final IllegalAccessException e ) 1394 { 1395 if ( this.isLoggable( Level.SEVERE ) ) 1396 { 1397 this.log( Level.SEVERE, e.getMessage(), e ); 1398 } 1399 1400 cachedModules = null; 1401 } 1402 catch ( final TransformerException e ) 1403 { 1404 if ( this.isLoggable( Level.SEVERE ) ) 1405 { 1406 this.log( Level.SEVERE, e.getMessage(), e ); 1407 } 1408 1409 cachedModules = null; 1410 } 1411 catch ( final IOException e ) 1412 { 1413 if ( this.isLoggable( Level.SEVERE ) ) 1414 { 1415 this.log( Level.SEVERE, e.getMessage(), e ); 1416 } 1417 1418 cachedModules = null; 1419 } 1420 catch ( final SAXException e ) 1421 { 1422 if ( this.isLoggable( Level.SEVERE ) ) 1423 { 1424 this.log( Level.SEVERE, e.getMessage(), e ); 1425 } 1426 1427 cachedModules = null; 1428 } 1429 catch ( final JAXBException e ) 1430 { 1431 if ( this.isLoggable( Level.SEVERE ) ) 1432 { 1433 this.log( Level.SEVERE, e.getMessage(), e ); 1434 } 1435 1436 cachedModules = null; 1437 } 1438 finally 1439 { 1440 if ( cachedModules == null ) 1441 { 1442 cachedModules = new Modules(); 1443 } 1444 } 1445 } 1446 1447 return cachedModules; 1448 } 1449 } 1450 1451 /** 1452 * Gets the class loader of a given class. 1453 * 1454 * @param clazz The class whose class loader to return. 1455 * 1456 * @return The class loader of {@code clazz}. 1457 * 1458 * @throws NullPointerException if {@code clazz} is {@code null}. 1459 */ 1460 public static ClassLoader getClassLoader( final Class clazz ) 1461 { 1462 if ( clazz == null ) 1463 { 1464 throw new NullPointerException( "clazz" ); 1465 } 1466 1467 ClassLoader cl = clazz.getClassLoader(); 1468 if ( cl == null ) 1469 { 1470 cl = BOOTSTRAP_CLASSLOADER; 1471 } 1472 1473 return cl; 1474 } 1475 1476 /** 1477 * Gets the parent class loader of a given class loader recursively. 1478 * <p>This method recursively finds the parent class loader of the given class loader. Recursion stops at the 1479 * platform's bootstrap class loader. That class loader is detected when either the current class loader has no 1480 * parent (a call to the {@code getParent()} method returns {@code null}) or when the class name of the 1481 * current class loader's parent class loader is equal to the name returned by method 1482 * {@code getBootstrapClassLoaderClassName()}. Configuration of the name of the platform's bootstrap class loader 1483 * class is needed when the platform's {@code getParent()} method of the {@code ClassLoader} class does not return 1484 * {@code null} to indicate the bootstrap class loader but instead returns an instance of {@code ClassLoader}.</p> 1485 * 1486 * @param classLoader The class loader whose parent class loader to return or {@code null} to return a 1487 * {@code ClassLoader} instance representing the platform's bootstrap class loader. 1488 * 1489 * @return The parent class loader of {@code classLoader}. 1490 * 1491 * @throws NullPointerException if {@code classLoader} is {@code null}. 1492 * 1493 * @see #getBootstrapClassLoaderClassName() 1494 * @see ClassLoader#getParent() 1495 */ 1496 public static ClassLoader getClassLoader( final ClassLoader classLoader ) 1497 { 1498 if ( classLoader == null ) 1499 { 1500 return BOOTSTRAP_CLASSLOADER; 1501 } 1502 1503 if ( classLoader.getParent() != null && 1504 !classLoader.getParent().getClass().getName().equals( getBootstrapClassLoaderClassName() ) ) 1505 { 1506 return getClassLoader( classLoader.getParent() ); 1507 } 1508 1509 return classLoader; 1510 } 1511 1512 /** 1513 * Gets an object of a given instance from a given scope. 1514 * 1515 * @param scope The scope to get the object from or {@code null}. 1516 * @param instance The instance of the object to get. 1517 * @param classLoader The class loader to use for creating the object. 1518 * 1519 * @return An object of {@code instance} from {@code scope} or {@code null} if no such object is found. 1520 * 1521 * @throws NullPointerException if {@code instance} or {@code classLoader} is {@code null}. 1522 * @throws InstantiationException if creating an object fails. 1523 */ 1524 public Object getObject( final Scope scope, final Instance instance, final ClassLoader classLoader ) 1525 throws InstantiationException 1526 { 1527 if ( instance == null ) 1528 { 1529 throw new NullPointerException( "instance" ); 1530 } 1531 if ( classLoader == null ) 1532 { 1533 throw new NullPointerException( "classLoader" ); 1534 } 1535 1536 Object object = null; 1537 final Modules model = this.getModules( classLoader ); 1538 1539 if ( scope != null ) 1540 { 1541 synchronized ( scope ) 1542 { 1543 object = scope.getObject( instance.getIdentifier() ); 1544 1545 if ( object == null ) 1546 { 1547 scope.putObject( instance.getIdentifier(), instance ); 1548 1549 try 1550 { 1551 object = model.createObject( instance, classLoader ); 1552 } 1553 finally 1554 { 1555 if ( object != null ) 1556 { 1557 object = this.createProxy( instance, object ); 1558 } 1559 1560 scope.putObject( instance.getIdentifier(), object ); 1561 } 1562 } 1563 else if ( object instanceof Instance ) 1564 { 1565 throw new ObjectManagementException( this.getDependencyCycleMessage( 1566 ( (Instance) object ).getIdentifier() ) ); 1567 1568 } 1569 } 1570 } 1571 else 1572 { 1573 try 1574 { 1575 object = model.createObject( instance, classLoader ); 1576 } 1577 finally 1578 { 1579 if ( object != null ) 1580 { 1581 object = this.createProxy( instance, object ); 1582 } 1583 } 1584 } 1585 1586 return object; 1587 } 1588 1589 /** 1590 * Gets an object for a given location URI. 1591 * 1592 * @param specification The specification class of the object to locate. 1593 * @param location The location URI of the object to locate. 1594 * @param classLoader The class loader to use for loading locator classes. 1595 * @param <T> The type of the object. 1596 * 1597 * @return An object located at {@code location} or {@code null} if no such object is found. 1598 * 1599 * @throws NullPointerException if {@code specification}, {@code location} or {@code classLoader} is {@code null}. 1600 * @throws InstantiationException if instantiating a locator fails. 1601 * @throws ClassNotFoundException if the class of {@code specification} is not found. 1602 * @throws IOException if locating the object fails. 1603 */ 1604 public <T> T getObject( final Class<T> specification, final URI location, final ClassLoader classLoader ) 1605 throws InstantiationException, ClassNotFoundException, IOException 1606 { 1607 if ( specification == null ) 1608 { 1609 throw new NullPointerException( "specification" ); 1610 } 1611 if ( location == null ) 1612 { 1613 throw new NullPointerException( "location" ); 1614 } 1615 if ( classLoader == null ) 1616 { 1617 throw new NullPointerException( "classLoader" ); 1618 } 1619 1620 T object = null; 1621 final Locator locator = this.getLocator( classLoader, location ); 1622 1623 if ( locator != null ) 1624 { 1625 object = locator.getObject( specification, location ); 1626 } 1627 else if ( this.isLoggable( Level.WARNING ) ) 1628 { 1629 this.log( Level.WARNING, this.getMissingLocatorMessage( location ), new Exception() ); 1630 } 1631 1632 return object; 1633 } 1634 1635 /** 1636 * Gets the scope implementation for a given scope identifier. 1637 * 1638 * @param classLoader The class loader to use for loading scope implementations. 1639 * @param identifier The identifier of the scope to get an implementation of. 1640 * 1641 * @return The implementation of the scope identified by {@code identifier} or {@code null} if no such 1642 * scope implementation is found. 1643 * 1644 * @throws NullPointerException if {@code classLoader} or {@code identifier} is {@code null}. 1645 * @throws InstantiationException if instantiating a scope fails. 1646 * 1647 * @see #getDefaultScope(java.lang.String) 1648 */ 1649 public Scope getScope( final ClassLoader classLoader, final String identifier ) throws InstantiationException 1650 { 1651 if ( classLoader == null ) 1652 { 1653 throw new NullPointerException( "classLoader" ); 1654 } 1655 if ( identifier == null ) 1656 { 1657 throw new NullPointerException( "identifier" ); 1658 } 1659 1660 final Modules model = this.getModules( classLoader ); 1661 final ClassLoader scopesLoader = getClassLoader( classLoader ); 1662 1663 synchronized ( this.scopes ) 1664 { 1665 Map<String, Scope> cachedScopes = this.scopes.get( scopesLoader ); 1666 if ( cachedScopes == null ) 1667 { 1668 cachedScopes = new HashMap(); 1669 this.scopes.put( scopesLoader, cachedScopes ); 1670 } 1671 1672 Scope scope = cachedScopes.get( identifier ); 1673 1674 if ( scope == null ) 1675 { 1676 // Bootstrap scope loading. 1677 final Specification scopeSpecification = model.getSpecification( Scope.class ); 1678 1679 if ( scopeSpecification != null ) 1680 { 1681 final Implementations implementations = 1682 model.getImplementations( scopeSpecification.getIdentifier() ); 1683 1684 if ( implementations != null ) 1685 { 1686 for ( Implementation i : implementations.getImplementation() ) 1687 { 1688 if ( identifier.equals( i.getName() ) ) 1689 { 1690 final Instance instance = model.getInstance( i.getIdentifier() ); 1691 1692 if ( instance != null ) 1693 { 1694 scope = (Scope) model.createObject( instance, classLoader ); 1695 cachedScopes.put( identifier, scope ); 1696 if ( this.isLoggable( Level.CONFIG ) ) 1697 { 1698 this.log( Level.CONFIG, this.getMessage( "scopeInfo", new Object[] 1699 { 1700 i.getIdentifier(), identifier, scopesLoader.toString() 1701 } ), null ); 1702 1703 } 1704 break; 1705 } 1706 else if ( this.isLoggable( Level.WARNING ) ) 1707 { 1708 this.log( Level.WARNING, this.getMissingInstanceMessage( 1709 i.getIdentifier(), i.getName() ), new Exception() ); 1710 1711 } 1712 } 1713 } 1714 } 1715 } 1716 else if ( this.isLoggable( Level.WARNING ) ) 1717 { 1718 this.log( Level.WARNING, this.getMissingSpecificationMessage( Scope.class.getName() ), 1719 new Exception() ); 1720 1721 } 1722 } 1723 1724 if ( scope == null ) 1725 { 1726 scope = this.getDefaultScope( identifier ); 1727 if ( scope != null ) 1728 { 1729 cachedScopes.put( identifier, scope ); 1730 if ( this.isLoggable( Level.FINE ) ) 1731 { 1732 this.log( Level.FINE, this.getDefaultScopeInfoMessage( identifier, scopesLoader ), null ); 1733 } 1734 } 1735 } 1736 1737 return scope; 1738 } 1739 } 1740 1741 /** 1742 * Gets the default scope implementation for a given identifier. 1743 * 1744 * @param identifier The identifier of the scope to get a default implementation of. 1745 * 1746 * @return The default implementation of the scope identified by {@code identifier} or {@code null} if no such 1747 * default implementation is available. 1748 * 1749 * @throws NullPointerException if {@code identifier} is {@code null}. 1750 * 1751 * @see #getScope(java.lang.ClassLoader, java.lang.String) 1752 */ 1753 public Scope getDefaultScope( final String identifier ) 1754 { 1755 if ( identifier == null ) 1756 { 1757 throw new NullPointerException( "identifier" ); 1758 } 1759 1760 DefaultScope defaultScope = null; 1761 1762 if ( identifier.equals( SINGLETON_SCOPE_IDENTIFIER ) ) 1763 { 1764 defaultScope = new DefaultScope( new HashMap<String, Object>() ); 1765 } 1766 1767 return defaultScope; 1768 } 1769 1770 /** 1771 * Gets a locator to use with a given location URI. 1772 * 1773 * @param classLoader The class loader to use for loading locator implementations. 1774 * @param location The location URI to get a locator for. 1775 * 1776 * @return The locator to use for locating objects at {@code location} or {@code null} if no such locator is 1777 * available. 1778 * 1779 * @throws NullPointerException if {@code classLoader} or {@code location} is {@code null}. 1780 * @throws InstantiationException if instantiating a locator fails. 1781 * 1782 * @see #getDefaultLocator(java.net.URI) 1783 */ 1784 public Locator getLocator( final ClassLoader classLoader, final URI location ) throws InstantiationException 1785 { 1786 if ( classLoader == null ) 1787 { 1788 throw new NullPointerException( "classLoader" ); 1789 } 1790 if ( location == null ) 1791 { 1792 throw new NullPointerException( "location" ); 1793 } 1794 1795 final String scheme = location.getScheme(); 1796 1797 if ( scheme != null ) 1798 { 1799 final Modules model = this.getModules( classLoader ); 1800 final ClassLoader locatorsLoader = getClassLoader( classLoader ); 1801 1802 synchronized ( this.locators ) 1803 { 1804 Map<String, Locator> cachedLocators = this.locators.get( locatorsLoader ); 1805 if ( cachedLocators == null ) 1806 { 1807 cachedLocators = new HashMap(); 1808 this.locators.put( locatorsLoader, cachedLocators ); 1809 } 1810 1811 Locator locator = cachedLocators.get( scheme ); 1812 1813 if ( locator == null ) 1814 { 1815 // Bootstrap locator loading. 1816 final Specification locatorSpecification = model.getSpecification( Locator.class ); 1817 1818 if ( locatorSpecification != null ) 1819 { 1820 final Implementations implementations = 1821 model.getImplementations( locatorSpecification.getIdentifier() ); 1822 1823 if ( implementations != null ) 1824 { 1825 for ( Implementation i : implementations.getImplementation() ) 1826 { 1827 if ( scheme.equals( i.getName() ) ) 1828 { 1829 final Instance instance = model.getInstance( i.getIdentifier() ); 1830 1831 if ( instance != null ) 1832 { 1833 locator = (Locator) model.createObject( instance, classLoader ); 1834 cachedLocators.put( scheme, locator ); 1835 1836 if ( this.isLoggable( Level.CONFIG ) ) 1837 { 1838 this.log( Level.CONFIG, this.getMessage( "locatorInfo", new Object[] 1839 { 1840 i.getIdentifier(), scheme, locatorsLoader.toString() 1841 } ), null ); 1842 1843 } 1844 1845 break; 1846 } 1847 else if ( this.isLoggable( Level.WARNING ) ) 1848 { 1849 this.log( Level.WARNING, this.getMissingInstanceMessage( 1850 i.getIdentifier(), i.getName() ), new Exception() ); 1851 1852 } 1853 } 1854 } 1855 } 1856 } 1857 else if ( this.isLoggable( Level.WARNING ) ) 1858 { 1859 this.log( Level.WARNING, this.getMissingSpecificationMessage( Locator.class.getName() ), 1860 new Exception() ); 1861 1862 } 1863 } 1864 1865 if ( locator == null ) 1866 { 1867 locator = this.getDefaultLocator( location ); 1868 if ( locator != null ) 1869 { 1870 cachedLocators.put( scheme, locator ); 1871 if ( this.isLoggable( Level.FINE ) ) 1872 { 1873 this.log( Level.FINE, this.getDefaultLocatorInfoMessage( scheme, locatorsLoader ), null ); 1874 } 1875 } 1876 } 1877 1878 return locator; 1879 } 1880 } 1881 1882 return null; 1883 } 1884 1885 /** 1886 * Gets the default locator implementation for a given location URI. 1887 * 1888 * @param location The location URI to get a default locator implementation for. 1889 * 1890 * @return The default locator implementation for {@code location} or {@code null} if no default implementation is 1891 * available for {@code location}. 1892 * 1893 * @throws NullPointerException if {@code location} is {@code null}. 1894 * 1895 * @see #getLocator(java.lang.ClassLoader, java.net.URI) 1896 */ 1897 public Locator getDefaultLocator( final URI location ) 1898 { 1899 if ( location == null ) 1900 { 1901 throw new NullPointerException( "location" ); 1902 } 1903 1904 Locator locator = null; 1905 final DefaultLocator defaultLocator = new DefaultLocator(); 1906 1907 if ( defaultLocator.isLocationSupported( location ) ) 1908 { 1909 locator = defaultLocator; 1910 } 1911 1912 return locator; 1913 } 1914 1915 /** 1916 * Gets the invoker of the given class loader. 1917 * 1918 * @param classLoader The class loader to use for loading invoker implementations. 1919 * 1920 * @return The invoker of the given class loader. 1921 * 1922 * @throws NullPointerException if {@code classLoader} is {@code null}. 1923 * @throws InstantiationException if instantiating a new invoker fails. 1924 */ 1925 public Invoker getInvoker( final ClassLoader classLoader ) throws InstantiationException 1926 { 1927 if ( classLoader == null ) 1928 { 1929 throw new NullPointerException( "classLoader" ); 1930 } 1931 1932 final Modules model = this.getModules( classLoader ); 1933 final ClassLoader invokersLoader = getClassLoader( classLoader ); 1934 1935 synchronized ( this.invokers ) 1936 { 1937 Invoker invoker = this.invokers.get( invokersLoader ); 1938 1939 if ( invoker == null ) 1940 { 1941 final Specification invokerSpecification = model.getSpecification( Invoker.class ); 1942 1943 if ( invokerSpecification != null ) 1944 { 1945 final Implementations implementations = 1946 model.getImplementations( invokerSpecification.getIdentifier() ); 1947 1948 if ( implementations != null && !implementations.getImplementation().isEmpty() ) 1949 { 1950 for ( Implementation i : implementations.getImplementation() ) 1951 { 1952 if ( invoker == null ) 1953 { 1954 final Instance invokerInstance = model.getInstance( i.getIdentifier() ); 1955 1956 if ( invokerInstance != null ) 1957 { 1958 invoker = (Invoker) model.createObject( invokerInstance, classLoader ); 1959 this.invokers.put( invokersLoader, invoker ); 1960 1961 if ( this.isLoggable( Level.CONFIG ) ) 1962 { 1963 this.log( Level.CONFIG, this.getMessage( "invokerInfo", new Object[] 1964 { 1965 i.getIdentifier(), invokersLoader.toString() 1966 } ), null ); 1967 1968 } 1969 } 1970 else if ( this.isLoggable( Level.WARNING ) ) 1971 { 1972 this.log( Level.WARNING, this.getMissingInstanceMessage( 1973 i.getIdentifier(), i.getName() ), new Exception() ); 1974 1975 } 1976 } 1977 else if ( this.isLoggable( Level.FINE ) ) 1978 { 1979 this.log( Level.FINE, this.getMessage( "ignoredInvoker", new Object[] 1980 { 1981 i.getIdentifier() 1982 } ), null ); 1983 1984 } 1985 } 1986 } 1987 } 1988 else if ( this.isLoggable( Level.WARNING ) ) 1989 { 1990 this.log( Level.WARNING, this.getMissingSpecificationMessage( Invoker.class.getName() ), 1991 new Exception() ); 1992 1993 } 1994 1995 if ( invoker == null ) 1996 { 1997 invoker = new DefaultInvoker(); 1998 this.invokers.put( invokersLoader, invoker ); 1999 if ( this.isLoggable( Level.FINE ) ) 2000 { 2001 this.log( Level.FINE, this.getMessage( "defaultInvokerInfo", new Object[] 2002 { 2003 invokersLoader.toString() 2004 } ), null ); 2005 2006 } 2007 } 2008 } 2009 2010 return invoker; 2011 } 2012 } 2013 2014 /** 2015 * Gets an invocation for a given object, instance, method and arguments. 2016 * 2017 * @param object The object to invoke. 2018 * @param instance The instance of the object to invoke. 2019 * @param method The method to invoke on {@code object}. 2020 * @param arguments The arguments of the invocation or {@code null}. 2021 * 2022 * @return An invocation with {@code object}, {@code instance}, {@code method} and {@code arguments}. 2023 * 2024 * @throws NullPointerException if {@code object}, {@code instance} or {@code method} is {@code null}. 2025 * @throws InstantiationException if instantiating a new invocation fails. 2026 */ 2027 public Invocation getInvocation( final Object object, final Instance instance, final Method method, 2028 final Object[] arguments ) throws InstantiationException 2029 { 2030 if ( object == null ) 2031 { 2032 throw new NullPointerException( "object" ); 2033 } 2034 if ( instance == null ) 2035 { 2036 throw new NullPointerException( "instance" ); 2037 } 2038 if ( method == null ) 2039 { 2040 throw new NullPointerException( "method" ); 2041 } 2042 2043 Invocation invocation = null; 2044 final ClassLoader classLoader = getClassLoader( object.getClass() ); 2045 final Modules model = this.getModules( classLoader ); 2046 final Specification invocationSpecification = model.getSpecification( Invocation.class ); 2047 2048 if ( invocationSpecification != null ) 2049 { 2050 final Implementations implementations = 2051 model.getImplementations( invocationSpecification.getIdentifier() ); 2052 2053 if ( implementations != null && !implementations.getImplementation().isEmpty() ) 2054 { 2055 for ( Implementation i : implementations.getImplementation() ) 2056 { 2057 if ( invocation == null ) 2058 { 2059 final Instance invocationInstance = model.getInstance( i.getIdentifier() ); 2060 2061 if ( invocationInstance != null ) 2062 { 2063 invocation = (Invocation) model.createObject( invocationInstance, classLoader ); 2064 } 2065 else if ( this.isLoggable( Level.WARNING ) ) 2066 { 2067 this.log( Level.WARNING, this.getMissingInstanceMessage( 2068 i.getIdentifier(), i.getName() ), new Exception() ); 2069 2070 } 2071 } 2072 else if ( this.isLoggable( Level.FINE ) ) 2073 { 2074 this.log( Level.FINE, this.getMessage( "ignoredInvocation", new Object[] 2075 { 2076 i.getIdentifier() 2077 } ), null ); 2078 2079 } 2080 } 2081 } 2082 } 2083 else if ( this.isLoggable( Level.WARNING ) ) 2084 { 2085 this.log( Level.WARNING, this.getMissingSpecificationMessage( Invocation.class.getName() ), 2086 new Exception() ); 2087 2088 } 2089 2090 if ( invocation == null ) 2091 { 2092 invocation = new DefaultInvocation(); 2093 } 2094 2095 invocation.getContext().put( DefaultInvocation.OBJECT_KEY, object ); 2096 invocation.getContext().put( DefaultInvocation.METHOD_KEY, method ); 2097 invocation.getContext().put( DefaultInvocation.ARGUMENTS_KEY, arguments ); 2098 invocation.getContext().put( DefaultInvocation.INSTANCE_KEY, instance ); 2099 invocation.getContext().put( DefaultInvocation.MODULES_KEY, model ); 2100 invocation.getContext().put( DefaultInvocation.CLASSLOADER_KEY, classLoader ); 2101 return invocation; 2102 } 2103 2104 /** 2105 * Initializes the instance. 2106 * <p>This method is called once on first usage of a new instance.</p> 2107 * 2108 * @throws InstantiationException if initialization fails. 2109 */ 2110 public synchronized void initialize() throws InstantiationException 2111 { 2112 if ( !this.initialized ) 2113 { 2114 final List<LogRecord> bootstrapLogRecords = new LinkedList<LogRecord>(); 2115 final List<Listener> providedListeners = new LinkedList<Listener>(); 2116 2117 try 2118 { 2119 final long t0 = System.currentTimeMillis(); 2120 this.initialized = true; 2121 2122 this.listeners = null; 2123 this.modules.clear(); 2124 this.invokers.clear(); 2125 this.locators.clear(); 2126 this.scopes.clear(); 2127 2128 Listener bootstrapListener = new Listener() 2129 { 2130 2131 public void onLog( final Level level, final String message, final Throwable throwable ) 2132 { 2133 final LogRecord record = new LogRecord( level, message ); 2134 record.setThrown( throwable ); 2135 bootstrapLogRecords.add( record ); 2136 } 2137 2138 }; 2139 this.getListeners().add( bootstrapListener ); 2140 2141 final ClassLoader classLoader = getClassLoader( this.getClass() ); 2142 final Modules model = this.getModules( classLoader ); 2143 final Specification objectManager = model.getSpecification( ObjectManager.class ); 2144 if ( objectManager == null ) 2145 { 2146 throw new InstantiationException( this.getMissingSpecificationMessage( 2147 ObjectManager.class.getName() ) ); 2148 2149 } 2150 2151 final Instance thisInstance = model.getInstance( this ); 2152 if ( thisInstance == null ) 2153 { 2154 throw new InstantiationException( this.getMissingInstanceMessage( 2155 this.getClass().getName(), this.getArtifactNameMessage() ) ); 2156 2157 } 2158 2159 if ( objectManager.getScope() != null ) 2160 { 2161 final Scope scope = this.getScope( classLoader, objectManager.getScope() ); 2162 if ( scope == null ) 2163 { 2164 throw new InstantiationException( this.getMissingScopeMessage( objectManager.getScope() ) ); 2165 } 2166 2167 scope.putObject( thisInstance.getIdentifier(), this ); 2168 } 2169 2170 // Bootstrap listener loading. 2171 final Specification listenerSpecification = model.getSpecification( Listener.class ); 2172 2173 if ( listenerSpecification != null ) 2174 { 2175 final Implementations implementations = 2176 model.getImplementations( listenerSpecification.getIdentifier() ); 2177 2178 if ( implementations != null && !implementations.getImplementation().isEmpty() ) 2179 { 2180 for ( Implementation i : implementations.getImplementation() ) 2181 { 2182 final Instance listenerInstance = model.getInstance( i.getIdentifier() ); 2183 if ( listenerInstance != null ) 2184 { 2185 final Listener l = (Listener) model.createObject( listenerInstance, classLoader ); 2186 providedListeners.add( l ); 2187 this.log( Level.CONFIG, this.getRegisteredListenerMessage( 2188 l.getClass().getName() ), null ); 2189 2190 } 2191 else if ( this.isLoggable( Level.WARNING ) ) 2192 { 2193 this.log( Level.WARNING, this.getMissingInstanceMessage( 2194 i.getIdentifier(), i.getName() ), null ); 2195 2196 } 2197 } 2198 } 2199 else if ( this.isLoggable( Level.WARNING ) ) 2200 { 2201 this.log( Level.WARNING, this.getMissingImplementationsMessage( 2202 listenerSpecification.getIdentifier() ), new Exception() ); 2203 2204 } 2205 } 2206 else if ( this.isLoggable( Level.WARNING ) ) 2207 { 2208 this.log( Level.WARNING, this.getMissingSpecificationMessage( 2209 Listener.class.getName() ), new Exception() ); 2210 2211 } 2212 2213 if ( this.isLoggable( Level.FINE ) ) 2214 { 2215 this.log( Level.FINE, this.getImplementationInfoMessage( 2216 Long.valueOf( System.currentTimeMillis() - t0 ) ), null ); 2217 2218 } 2219 2220 this.getListeners().addAll( providedListeners ); 2221 this.getListeners().remove( bootstrapListener ); 2222 bootstrapListener = null; 2223 2224 if ( !this.getListeners().isEmpty() ) 2225 { 2226 for ( LogRecord logRecord : bootstrapLogRecords ) 2227 { 2228 this.log( logRecord.getLevel(), logRecord.getMessage(), logRecord.getThrown() ); 2229 } 2230 } 2231 } 2232 catch ( final InstantiationException e ) 2233 { 2234 Throwable cause = e; 2235 if ( !bootstrapLogRecords.isEmpty() ) 2236 { 2237 for ( LogRecord r : bootstrapLogRecords ) 2238 { 2239 if ( r.getLevel().intValue() > Level.WARNING.intValue() ) 2240 { 2241 if ( r.getMessage() != null ) 2242 { 2243 cause = new IllegalStateException( r.getMessage() ).initCause( cause ); 2244 } 2245 if ( r.getThrown() != null ) 2246 { 2247 cause = new IllegalStateException( r.getThrown().toString() ).initCause( cause ); 2248 } 2249 } 2250 } 2251 } 2252 2253 this.listeners = null; 2254 this.modules.clear(); 2255 this.invokers.clear(); 2256 this.locators.clear(); 2257 this.scopes.clear(); 2258 this.initialized = false; 2259 2260 throw (InstantiationException) new InstantiationException( cause.getMessage() ).initCause( cause ); 2261 } 2262 } 2263 } 2264 2265 /** 2266 * Notifies registered listeners. 2267 * 2268 * @param level The level of the event. 2269 * @param message The message of the event or {@code null}. 2270 * @param throwable The throwable of the event or {@code null}. 2271 * 2272 * @throws NullPointerException if {@code level} is {@code null}. 2273 */ 2274 protected void log( final Level level, final String message, final Throwable throwable ) 2275 { 2276 if ( level == null ) 2277 { 2278 throw new NullPointerException( "level" ); 2279 } 2280 2281 if ( this.isLoggable( level ) ) 2282 { 2283 for ( Listener l : this.getListeners() ) 2284 { 2285 l.onLog( level, message, throwable ); 2286 } 2287 } 2288 } 2289 2290 /** 2291 * Creates a proxy for a given object. 2292 * 2293 * @param instance The instance of {@code object}. 2294 * @param object The object to create a proxy for. 2295 * 2296 * @return A proxy for {@code object}. 2297 * 2298 * @throws InstantiationException if creating a proxy fails. 2299 */ 2300 private Object createProxy( final Instance instance, final Object object ) throws InstantiationException 2301 { 2302 try 2303 { 2304 final ClassLoader classLoader = getClassLoader( object.getClass() ); 2305 final Set<Class> interfaces = new HashSet<Class>(); 2306 boolean canProxy = instance.getSpecifications() != null; 2307 2308 if ( canProxy ) 2309 { 2310 for ( Specification s : instance.getSpecifications().getSpecification() ) 2311 { 2312 if ( s.getClazz() != null ) 2313 { 2314 final Class clazz = Class.forName( s.getClazz(), true, classLoader ); 2315 2316 if ( !clazz.isInterface() ) 2317 { 2318 canProxy = false; 2319 break; 2320 } 2321 2322 interfaces.add( clazz ); 2323 } 2324 } 2325 } 2326 2327 if ( canProxy && !interfaces.isEmpty() ) 2328 { 2329 return Proxy.newProxyInstance( classLoader, interfaces.toArray( new Class[ interfaces.size() ] ), 2330 new java.lang.reflect.InvocationHandler() 2331 { 2332 2333 public Object invoke( final Object proxy, final Method method, final Object[] args ) 2334 throws Throwable 2335 { 2336 return getInvoker( classLoader ).invoke( getInvocation( object, instance, method, args ) ); 2337 } 2338 2339 } ); 2340 2341 } 2342 2343 return object; 2344 } 2345 catch ( final ClassNotFoundException e ) 2346 { 2347 throw (InstantiationException) new InstantiationException( e.getMessage() ).initCause( e ); 2348 } 2349 } 2350 2351 private String getMessage( final String key, final Object arguments ) 2352 { 2353 final ResourceBundle bundle = 2354 ResourceBundle.getBundle( DefaultObjectManager.class.getName().replace( '.', '/' ) ); 2355 2356 return new MessageFormat( bundle.getString( key ) ).format( arguments ); 2357 } 2358 2359 private String getArtifactNameMessage() 2360 { 2361 return this.getMessage( "artifactName", null ); 2362 } 2363 2364 private String getMissingSpecificationMessage( final String specification ) 2365 { 2366 return this.getMessage( "missingSpecification", new Object[] 2367 { 2368 specification 2369 } ); 2370 2371 } 2372 2373 private String getMissingImplementationsMessage( final String specification ) 2374 { 2375 return this.getMessage( "missingImplementations", new Object[] 2376 { 2377 specification 2378 } ); 2379 2380 } 2381 2382 private String getMissingImplementationMessage( final String implementationName, final String specification ) 2383 { 2384 return this.getMessage( "missingImplementation", new Object[] 2385 { 2386 implementationName, specification 2387 } ); 2388 2389 } 2390 2391 private String getMissingObjectInstanceMessage( final Object object ) 2392 { 2393 return this.getMessage( "missingObjectInstance", new Object[] 2394 { 2395 object.toString() 2396 } ); 2397 2398 } 2399 2400 private String getMissingDependencyMessage( final String dependency, final String implementation ) 2401 { 2402 return this.getMessage( "missingDependency", new Object[] 2403 { 2404 dependency, implementation 2405 } ); 2406 } 2407 2408 private String getMissingPropertyMessage( final String property, final String implementation ) 2409 { 2410 return this.getMessage( "missingProperty", new Object[] 2411 { 2412 property, implementation 2413 } ); 2414 2415 } 2416 2417 private String getMissingMessageMessage( final String message, final String implementation ) 2418 { 2419 return this.getMessage( "missingMessage", new Object[] 2420 { 2421 message, implementation 2422 } ); 2423 2424 } 2425 2426 private String getMissingInstanceMessage( final String implementation, final String implementationName ) 2427 { 2428 return this.getMessage( "missingInstance", new Object[] 2429 { 2430 implementation, implementationName 2431 } ); 2432 2433 } 2434 2435 private String getMissingObjectMessage( final String implementation, final String implementationName ) 2436 { 2437 return this.getMessage( "missingObject", new Object[] 2438 { 2439 implementation, implementationName 2440 } ); 2441 2442 } 2443 2444 private String getDependencyCycleMessage( final String implementation ) 2445 { 2446 return this.getMessage( "dependencyCycle", new Object[] 2447 { 2448 implementation 2449 } ); 2450 2451 } 2452 2453 private String getImplementationInfoMessage( final Long startMillis ) 2454 { 2455 return this.getMessage( "implementationInfo", new Object[] 2456 { 2457 startMillis 2458 } ); 2459 2460 } 2461 2462 private String getDefaultScopeInfoMessage( final String modelScope, final ClassLoader classLoader ) 2463 { 2464 return this.getMessage( "defaultScopeInfo", new Object[] 2465 { 2466 modelScope, classLoader.toString() 2467 } ); 2468 2469 } 2470 2471 private String getMissingScopeMessage( final String modelScope ) 2472 { 2473 return this.getMessage( "missingScope", new Object[] 2474 { 2475 modelScope 2476 } ); 2477 2478 } 2479 2480 private String getRegisteredListenerMessage( final String listener ) 2481 { 2482 return this.getMessage( "listenerInfo", new Object[] 2483 { 2484 listener 2485 } ); 2486 2487 } 2488 2489 private String getUnsupportedMultiplicityMessage( final Multiplicity multiplicity ) 2490 { 2491 return this.getMessage( "unsupportedMultiplicity", new Object[] 2492 { 2493 multiplicity 2494 } ); 2495 } 2496 2497 private String getDefaultLocatorInfoMessage( final String scheme, final ClassLoader classLoader ) 2498 { 2499 return this.getMessage( "defaultLocatorInfo", new Object[] 2500 { 2501 scheme, classLoader.toString() 2502 } ); 2503 2504 } 2505 2506 private String getMissingLocatorMessage( final URI location ) 2507 { 2508 return this.getMessage( "missingLocator", new Object[] 2509 { 2510 location.toString() 2511 } ); 2512 2513 } 2514 2515 private String getMissingSpecificationClassMessage( final Specification specification ) 2516 { 2517 return this.getMessage( "missingSpecificationClass", new Object[] 2518 { 2519 specification.getIdentifier() 2520 } ); 2521 2522 } 2523 2524 private String getModulesReport( final Modules mods, final ClassLoader classLoader ) 2525 { 2526 final StringBuilder modulesInfo = new StringBuilder(); 2527 final String lineSeparator = System.getProperty( "line.separator" ); 2528 2529 modulesInfo.append( classLoader ); 2530 2531 if ( mods.getDocumentation() != null ) 2532 { 2533 modulesInfo.append( " - " ).append( mods.getDocumentation().getText( 2534 Locale.getDefault().getLanguage() ).getValue() ); 2535 2536 } 2537 2538 modulesInfo.append( lineSeparator ); 2539 2540 for ( Module m : mods.getModule() ) 2541 { 2542 modulesInfo.append( "\tM:" ).append( m.getName() ); 2543 2544 if ( m.getVersion() != null ) 2545 { 2546 modulesInfo.append( "|Version:" ).append( m.getVersion() ); 2547 } 2548 if ( m.getVendor() != null ) 2549 { 2550 modulesInfo.append( "|Vendor:" ).append( m.getVendor() ); 2551 } 2552 2553 modulesInfo.append( lineSeparator ); 2554 2555 if ( m.getSpecifications() != null ) 2556 { 2557 for ( Specification s : m.getSpecifications().getSpecification() ) 2558 { 2559 modulesInfo.append( "\t\t" ); 2560 this.appendSpecificationInfo( s, modulesInfo ).append( lineSeparator ); 2561 2562 final Implementations available = mods.getImplementations( s.getIdentifier() ); 2563 2564 if ( available != null ) 2565 { 2566 for ( Implementation i : available.getImplementation() ) 2567 { 2568 modulesInfo.append( "\t\t\t" ); 2569 this.appendImplementationInfo( i, modulesInfo ).append( "|Module:" ). 2570 append( mods.getModuleOfImplementation( i.getIdentifier() ).getName() ). 2571 append( lineSeparator ); 2572 2573 } 2574 } 2575 } 2576 } 2577 2578 if ( m.getImplementations() != null ) 2579 { 2580 for ( Implementation i : m.getImplementations().getImplementation() ) 2581 { 2582 modulesInfo.append( "\t\t" ); 2583 this.appendImplementationInfo( i, modulesInfo ).append( lineSeparator ); 2584 2585 if ( i.getImplementations() != null ) 2586 { 2587 modulesInfo.append( "\t\t\t" ); 2588 for ( ImplementationReference r : i.getImplementations().getReference() ) 2589 { 2590 this.appendImplementationInfo( 2591 mods.getImplementation( r.getIdentifier() ), modulesInfo ).append( "|Module:" ). 2592 append( mods.getModuleOfImplementation( r.getIdentifier() ).getName() ). 2593 append( lineSeparator ); 2594 2595 } 2596 } 2597 if ( i.getSpecifications() != null ) 2598 { 2599 for ( SpecificationReference s : i.getSpecifications().getReference() ) 2600 { 2601 modulesInfo.append( "\t\t\tS:" ).append( s.getIdentifier() ); 2602 2603 if ( s.getVersion() != null ) 2604 { 2605 modulesInfo.append( "|Version:" ).append( s.getVersion() ); 2606 } 2607 2608 modulesInfo.append( "|Module:" ).append( mods.getModuleOfSpecification( 2609 s.getIdentifier() ).getName() ).append( lineSeparator ); 2610 2611 } 2612 } 2613 2614 if ( i.getDependencies() != null ) 2615 { 2616 for ( Dependency d : i.getDependencies().getDependency() ) 2617 { 2618 modulesInfo.append( "\t\t\tD:" ).append( d.getName() ).append( "|Identifier:" ). 2619 append( d.getIdentifier() ); 2620 2621 if ( d.getImplementationName() != null ) 2622 { 2623 modulesInfo.append( "|Name:" ).append( d.getImplementationName() ); 2624 } 2625 2626 modulesInfo.append( "|Module:" ).append( mods.getModuleOfSpecification( 2627 d.getIdentifier() ).getName() ).append( lineSeparator ); 2628 2629 final Implementations available = mods.getImplementations( d.getIdentifier() ); 2630 2631 if ( available != null ) 2632 { 2633 for ( Implementation di : available.getImplementation() ) 2634 { 2635 modulesInfo.append( "\t\t\t\t" ); 2636 this.appendImplementationInfo( di, modulesInfo ).append( "|Module:" ). 2637 append( mods.getModuleOfImplementation( di.getIdentifier() ).getName() ). 2638 append( lineSeparator ); 2639 2640 } 2641 } 2642 } 2643 } 2644 2645 if ( i.getMessages() != null ) 2646 { 2647 for ( Message msg : i.getMessages().getMessage() ) 2648 { 2649 modulesInfo.append( "\t\t\tM:" ).append( msg.getName() ).append( "|Text:" ). 2650 append( msg.getTemplate().getText( Locale.getDefault().getLanguage() ).getValue() ). 2651 append( lineSeparator ); 2652 2653 } 2654 } 2655 2656 if ( i.getProperties() != null ) 2657 { 2658 for ( Property p : i.getProperties().getProperty() ) 2659 { 2660 modulesInfo.append( "\t\t\tP:" ).append( p.getName() ); 2661 2662 if ( p.getType() != null ) 2663 { 2664 modulesInfo.append( "|Type:" ).append( p.getType() ); 2665 } 2666 2667 modulesInfo.append( "|Value:" ); 2668 2669 try 2670 { 2671 modulesInfo.append( p.getJavaValue( getClassLoader( this.getClass() ) ) ); 2672 } 2673 catch ( final ClassNotFoundException e ) 2674 { 2675 modulesInfo.append( Level.WARNING.getLocalizedName() ).append( " " ).append( e ); 2676 } 2677 catch ( final InstantiationException e ) 2678 { 2679 modulesInfo.append( Level.WARNING.getLocalizedName() ).append( " " ).append( e ); 2680 } 2681 2682 modulesInfo.append( lineSeparator ); 2683 } 2684 } 2685 } 2686 } 2687 } 2688 2689 return modulesInfo.toString(); 2690 } 2691 2692 private StringBuilder appendSpecificationInfo( final Specification s, final StringBuilder b ) 2693 { 2694 b.append( "S:" ).append( s.getIdentifier() ); 2695 if ( s.getVersion() != null ) 2696 { 2697 b.append( "|Version:" ).append( s.getVersion() ); 2698 } 2699 if ( s.getVendor() != null ) 2700 { 2701 b.append( "|Vendor:" ).append( s.getVendor() ); 2702 } 2703 2704 b.append( "|Multiplicity:" ).append( s.getMultiplicity() ).append( "|Scope:" ). 2705 append( s.getScope() == null ? "Multiton" : s.getScope() ); 2706 2707 if ( s.getClazz() != null ) 2708 { 2709 b.append( "|Class:" ).append( s.getClazz() ); 2710 } 2711 2712 return b; 2713 } 2714 2715 private StringBuilder appendImplementationInfo( final Implementation i, final StringBuilder b ) 2716 { 2717 b.append( "I:" ).append( i.getIdentifier() ).append( "|Name:" ).append( i.getName() ).append( "|Abstract:" ). 2718 append( i.isAbstract() ).append( "|Final:" ).append( i.isFinal() ).append( "|Stateless:" ). 2719 append( i.isStateless() ); 2720 2721 if ( i.getVersion() != null ) 2722 { 2723 b.append( "|Version:" ).append( i.getVersion() ); 2724 } 2725 if ( i.getVendor() != null ) 2726 { 2727 b.append( "|Vendor:" ).append( i.getVendor() ); 2728 } 2729 if ( i.getClazz() != null ) 2730 { 2731 b.append( "|Class:" ).append( i.getClazz() ); 2732 } 2733 if ( i.getLocation() != null ) 2734 { 2735 b.append( "|Location:" ).append( i.getLocation() ); 2736 } 2737 2738 return b; 2739 } 2740 2741 // SECTION-END 2742 // SECTION-START[Dependencies] 2743 // SECTION-END 2744 // SECTION-START[Properties] 2745 // SECTION-END 2746 // SECTION-START[Messages] 2747 // SECTION-END 2748 }