001// SECTION-START[License Header] 002// <editor-fold defaultstate="collapsed" desc=" Generated License "> 003/* 004 * Java Object Management and Configuration 005 * Copyright (C) Christian Schulte, 2011-313 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 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 021 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 022 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 023 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, 024 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 025 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 026 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 027 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 029 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 030 * 031 * $JOMC: RuntimeModules.java 4588 2012-06-03 06:01:30Z schulte2005 $ 032 * 033 */ 034// </editor-fold> 035// SECTION-END 036package org.jomc.ri.model; 037 038import java.util.List; 039import java.util.Map; 040import javax.xml.bind.annotation.XmlTransient; 041import org.jomc.model.Dependencies; 042import org.jomc.model.Dependency; 043import org.jomc.model.Implementation; 044import org.jomc.model.Implementations; 045import org.jomc.model.Instance; 046import org.jomc.model.Message; 047import org.jomc.model.Messages; 048import org.jomc.model.Module; 049import org.jomc.model.Modules; 050import org.jomc.model.Properties; 051import org.jomc.model.Property; 052import org.jomc.model.Specification; 053import org.jomc.model.Specifications; 054import static org.jomc.ri.model.RuntimeModelObjects.createMap; 055 056// SECTION-START[Documentation] 057// <editor-fold defaultstate="collapsed" desc=" Generated Documentation "> 058/** 059 * Runtime {@code Modules}. 060 * 061 * <dl> 062 * <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeModules</dd> 063 * <dt><b>Name:</b></dt><dd>JOMC RI RuntimeModules</dd> 064 * <dt><b>Specifications:</b></dt> 065 * <dd>org.jomc.ri.model.RuntimeModelObject @ 1.2</dd> 066 * <dt><b>Abstract:</b></dt><dd>No</dd> 067 * <dt><b>Final:</b></dt><dd>No</dd> 068 * <dt><b>Stateless:</b></dt><dd>No</dd> 069 * </dl> 070 * 071 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.2 072 * @version 1.2 073 */ 074// </editor-fold> 075// SECTION-END 076// SECTION-START[Annotations] 077// <editor-fold defaultstate="collapsed" desc=" Generated Annotations "> 078@javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" ) 079// </editor-fold> 080// SECTION-END 081public class RuntimeModules extends Modules implements RuntimeModelObject 082{ 083 // SECTION-START[RuntimeModules] 084 085 /** Cache map. */ 086 @XmlTransient 087 private transient final Map<String, Module> modulesByNameCache = createMap(); 088 089 /** Cache map. */ 090 @XmlTransient 091 private transient final Map<String, Specifications> specificationsCache = createMap(); 092 093 /** Cache map. */ 094 @XmlTransient 095 private transient final Map<String, Implementations> implementationsCache = createMap(); 096 097 /** Cache map. */ 098 @XmlTransient 099 private transient final Map<String, Module> moduleBySpecificationIdentifierCache = createMap(); 100 101 /** Cache map. */ 102 @XmlTransient 103 private transient final Map<String, Module> moduleByImplementationIdentifierCache = createMap(); 104 105 /** Cache map. */ 106 @XmlTransient 107 private transient final Map<String, Specification> specificationByIdentifierCache = createMap(); 108 109 /** Cache map. */ 110 @XmlTransient 111 private transient final Map<String, Specification> specificationByClassNameCache = createMap(); 112 113 /** Cache map. */ 114 @XmlTransient 115 private transient final Map<String, Specifications> specificationsByImplemenationIdentifierCache = createMap(); 116 117 /** Cache map. */ 118 @XmlTransient 119 private transient final Map<String, Implementation> implementationByIdentifierCache = createMap(); 120 121 /** Cache map. */ 122 @XmlTransient 123 private transient final Map<String, Implementation> implementationByClassNameCache = createMap(); 124 125 /** Cache map. */ 126 @XmlTransient 127 private transient final Map<String, Implementation> implementationByObjectClassNameCache = createMap(); 128 129 /** Cache map. */ 130 @XmlTransient 131 private transient final Map<String, Implementation> implementationBySpecificationAndNameCache = createMap(); 132 133 /** Cache map. */ 134 @XmlTransient 135 private transient final Map<String, Dependencies> dependenciesByImplementationIdentifierCache = createMap(); 136 137 /** Cache map. */ 138 @XmlTransient 139 private transient final Map<String, Properties> propertiesByImplementationIdentifierCache = createMap(); 140 141 /** Cache map. */ 142 @XmlTransient 143 private transient final Map<String, Properties> specifiedPropertiesByImplementationIdentifierCache = createMap(); 144 145 /** Cache map. */ 146 @XmlTransient 147 private transient final Map<String, Messages> messagesByImplementationIdentifierCache = createMap(); 148 149 /** Cache map. */ 150 @XmlTransient 151 private transient final Map<String, Implementations> implementationsBySpecificationIdentifierCache = createMap(); 152 153 /** Cache map. */ 154 @XmlTransient 155 private transient final Map<String, List<Object>> anyObjectsByImplemenationIdentifierCache = createMap(); 156 157 /** 158 * Creates a new {@code RuntimeModules} instance by deeply copying a given {@code Modules} instance. 159 * 160 * @param modules The instance to copy. 161 * 162 * @throws NullPointerException if {@code modules} is {@code null}. 163 */ 164 public RuntimeModules( final Modules modules ) 165 { 166 super( modules ); 167 168 if ( this.getAuthors() != null ) 169 { 170 this.setAuthors( RuntimeModelObjects.getInstance().copyOf( this.getAuthors() ) ); 171 } 172 if ( this.getDocumentation() != null ) 173 { 174 this.setDocumentation( RuntimeModelObjects.getInstance().copyOf( this.getDocumentation() ) ); 175 } 176 177 this.copyModules(); 178 } 179 180 /** 181 * Creates a new {@code DefaultModules} instance by deeply copying a given {@code Modules} instance taking a map 182 * backing the instance. 183 * 184 * @param modules The instance to copy. 185 * @param objects The map backing the instance. 186 * 187 * @throws NullPointerException if {@code modules} or {@code objects} is {@code null}. 188 */ 189 public RuntimeModules( final Modules modules, final Map<Object, Instance> objects ) 190 { 191 super( modules, objects ); 192 193 if ( this.getAuthors() != null ) 194 { 195 this.setAuthors( RuntimeModelObjects.getInstance().copyOf( this.getAuthors() ) ); 196 } 197 if ( this.getDocumentation() != null ) 198 { 199 this.setDocumentation( RuntimeModelObjects.getInstance().copyOf( this.getDocumentation() ) ); 200 } 201 202 this.copyModules(); 203 } 204 205 /** 206 * Gets a module for a given name from the list of modules. 207 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 208 * cached result object is available, this method queries the super-class for a result object to return and caches 209 * the outcome of that query for use on successive calls.</p> 210 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 211 * state of the instance, should the state of the instance change.</p> 212 * 213 * @param name The name of the module to return. 214 * 215 * @return The first matching module or {@code null}, if no such module is found. 216 * 217 * @throws NullPointerException if {@code name} is {@code null}. 218 * 219 * @see #getModule() 220 * @see Module#getName() 221 * @see #clear() 222 */ 223 @Override 224 public Module getModule( final String name ) 225 { 226 if ( name == null ) 227 { 228 throw new NullPointerException( "name" ); 229 } 230 231 synchronized ( this.modulesByNameCache ) 232 { 233 Module m = this.modulesByNameCache.get( name ); 234 235 if ( m == null && !this.modulesByNameCache.containsKey( name ) ) 236 { 237 m = super.getModule( name ); 238 this.modulesByNameCache.put( name, m ); 239 } 240 241 return m; 242 } 243 } 244 245 /** 246 * Gets all specifications of the list of modules. 247 * <p>This method queries an internal cache for a result object to return. If no cached result object is available, 248 * this method queries the super-class for a result object to return and caches the outcome of that query for use on 249 * successive calls.</p> 250 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 251 * state of the instance, should the state of the instance change.</p> 252 * 253 * @return All specifications or {@code null}, if no specifications are found. 254 * 255 * @see #getModule() 256 * @see #clear() 257 */ 258 @Override 259 public Specifications getSpecifications() 260 { 261 synchronized ( this.specificationsCache ) 262 { 263 Specifications s = this.specificationsCache.get( RuntimeModules.class.getName() ); 264 265 if ( s == null && !this.specificationsCache.containsKey( RuntimeModules.class.getName() ) ) 266 { 267 s = super.getSpecifications(); 268 269 if ( s != null ) 270 { 271 s = RuntimeModelObjects.getInstance().copyOf( s ); 272 } 273 274 this.specificationsCache.put( RuntimeModules.class.getName(), s ); 275 } 276 277 return s; 278 } 279 } 280 281 /** 282 * Gets all specifications of the list of modules. 283 * <p>This method queries an internal cache for a result object to return. If no cached result object is available, 284 * this method queries the super-class for a result object to return and caches the outcome of that query for use on 285 * successive calls.</p> 286 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 287 * state of the instance, should the state of the instance change.</p> 288 * 289 * @return All specifications or {@code null}, if no specifications are found. 290 * 291 * @see #getModule() 292 * @see #clear() 293 */ 294 @Override 295 public Implementations getImplementations() 296 { 297 synchronized ( this.implementationsCache ) 298 { 299 Implementations i = this.implementationsCache.get( RuntimeModules.class.getName() ); 300 301 if ( i == null && !this.implementationsCache.containsKey( RuntimeModules.class.getName() ) ) 302 { 303 i = super.getImplementations(); 304 305 if ( i != null ) 306 { 307 i = RuntimeModelObjects.getInstance().copyOf( i ); 308 } 309 310 this.implementationsCache.put( RuntimeModules.class.getName(), i ); 311 } 312 313 return i; 314 } 315 } 316 317 /** 318 * Gets the module declaring a given specification from the list of modules. 319 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 320 * cached result object is available, this method queries the super-class for a result object to return and caches 321 * the outcome of that query for use on successive calls.</p> 322 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 323 * state of the instance, should the state of the instance change.</p> 324 * 325 * @param specification The identifier of the specification whose declaring module to return. 326 * 327 * @return The first matching module or {@code null}, if no such module is found. 328 * 329 * @throws NullPointerException if {@code specification} is {@code null}. 330 * 331 * @see #getModule() 332 * @see Module#getSpecifications() 333 * @see Specifications#getSpecification( java.lang.String ) 334 * @see #clear() 335 */ 336 @Override 337 public Module getModuleOfSpecification( final String specification ) 338 { 339 if ( specification == null ) 340 { 341 throw new NullPointerException( "specification" ); 342 } 343 344 synchronized ( this.moduleBySpecificationIdentifierCache ) 345 { 346 Module m = this.moduleBySpecificationIdentifierCache.get( specification ); 347 348 if ( m == null && !this.moduleBySpecificationIdentifierCache.containsKey( specification ) ) 349 { 350 m = super.getModuleOfSpecification( specification ); 351 this.moduleBySpecificationIdentifierCache.put( specification, m ); 352 } 353 354 return m; 355 } 356 } 357 358 /** 359 * Gets the module declaring a given implementation from the list of modules. 360 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 361 * cached result object is available, this method queries the super-class for a result object to return and caches 362 * the outcome of that query for use on successive calls.</p> 363 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 364 * state of the instance, should the state of the instance change.</p> 365 * 366 * @param implementation The identifier of the implementation whose declaring module to return. 367 * 368 * @return The first matching module or {@code null}, if no such module is found. 369 * 370 * @throws NullPointerException if {@code implementation} is {@code null}. 371 * 372 * @see #getModule() 373 * @see Module#getImplementations() 374 * @see Implementations#getImplementation( java.lang.String ) 375 * @see #clear() 376 */ 377 @Override 378 public Module getModuleOfImplementation( final String implementation ) 379 { 380 if ( implementation == null ) 381 { 382 throw new NullPointerException( "implementation" ); 383 } 384 385 synchronized ( this.moduleByImplementationIdentifierCache ) 386 { 387 Module m = this.moduleByImplementationIdentifierCache.get( implementation ); 388 389 if ( m == null && !this.moduleByImplementationIdentifierCache.containsKey( implementation ) ) 390 { 391 m = super.getModuleOfImplementation( implementation ); 392 this.moduleByImplementationIdentifierCache.put( implementation, m ); 393 } 394 395 return m; 396 } 397 } 398 399 /** 400 * Gets a specification for a given identifier from the list of modules. 401 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 402 * cached result object is available, this method queries the super-class for a result object to return and caches 403 * the outcome of that query for use on successive calls.</p> 404 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 405 * state of the instance, should the state of the instance change.</p> 406 * 407 * @param specification The identifier of the specification to return. 408 * 409 * @return The first matching specification or {@code null}, if no such specification is found. 410 * 411 * @throws NullPointerException if {@code specification} is {@code null}. 412 * 413 * @see #getModule() 414 * @see Module#getSpecifications() 415 * @see Specifications#getSpecification( java.lang.String ) 416 * @see #clear() 417 */ 418 @Override 419 public Specification getSpecification( final String specification ) 420 { 421 if ( specification == null ) 422 { 423 throw new NullPointerException( "specification" ); 424 } 425 426 synchronized ( this.specificationByIdentifierCache ) 427 { 428 Specification s = this.specificationByIdentifierCache.get( specification ); 429 430 if ( s == null && !this.specificationByIdentifierCache.containsKey( specification ) ) 431 { 432 s = super.getSpecification( specification ); 433 this.specificationByIdentifierCache.put( specification, s ); 434 } 435 436 return s; 437 } 438 } 439 440 /** 441 * Gets a specification for a given class from the list of modules. 442 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 443 * cached result object is available, this method queries the super-class for a result object to return and caches 444 * the outcome of that query for use on successive calls.</p> 445 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 446 * state of the instance, should the state of the instance change.</p> 447 * 448 * @param specification The class of the specification to return. 449 * 450 * @return The first matching specification or {@code null}, if no such specification is found. 451 * 452 * @throws NullPointerException if {@code specification} is {@code null}. 453 * 454 * @see #getModule() 455 * @see Module#getSpecifications() 456 * @see Specifications#getSpecification( java.lang.Class ) 457 * @see #clear() 458 */ 459 @Override 460 public Specification getSpecification( final Class<?> specification ) 461 { 462 if ( specification == null ) 463 { 464 throw new NullPointerException( "specification" ); 465 } 466 467 synchronized ( this.specificationByClassNameCache ) 468 { 469 Specification s = this.specificationByClassNameCache.get( specification.getName() ); 470 471 if ( s == null && !this.specificationByClassNameCache.containsKey( specification.getName() ) ) 472 { 473 s = super.getSpecification( specification ); 474 this.specificationByClassNameCache.put( specification.getName(), s ); 475 } 476 477 return s; 478 } 479 } 480 481 /** 482 * Gets all specifications an implementation implements from the list of modules. 483 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 484 * cached result object is available, this method queries the super-class for a result object to return and caches 485 * the outcome of that query for use on successive calls.</p> 486 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 487 * state of the instance, should the state of the instance change.</p> 488 * 489 * @param implementation The identifier of the implementation to get all implemented specifications of. 490 * 491 * @return All specifications implemented by the first matching implementation or {@code null}, if no such 492 * implementation is found or if the first matching implementation does not implement any specification. 493 * 494 * @throws NullPointerException if {@code implementation} is {@code null}. 495 * 496 * @see #getModule() 497 * @see #getImplementation( java.lang.String ) 498 * @see Implementation#getImplementations() 499 * @see Implementations#getReference() 500 * @see #clear() 501 */ 502 @Override 503 public Specifications getSpecifications( final String implementation ) 504 { 505 if ( implementation == null ) 506 { 507 throw new NullPointerException( "implementation" ); 508 } 509 510 synchronized ( this.specificationsByImplemenationIdentifierCache ) 511 { 512 Specifications s = this.specificationsByImplemenationIdentifierCache.get( implementation ); 513 514 if ( s == null && !this.specificationsByImplemenationIdentifierCache.containsKey( implementation ) ) 515 { 516 s = super.getSpecifications( implementation ); 517 518 if ( s != null ) 519 { 520 s = RuntimeModelObjects.getInstance().copyOf( s ); 521 } 522 523 this.specificationsByImplemenationIdentifierCache.put( implementation, s ); 524 } 525 526 return s; 527 } 528 } 529 530 /** 531 * Gets an implementation for a given identifier from the list of modules. 532 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 533 * cached result object is available, this method queries the super-class for a result object to return and caches 534 * the outcome of that query for use on successive calls.</p> 535 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 536 * state of the instance, should the state of the instance change.</p> 537 * 538 * @param implementation The identifier of the implementation to return. 539 * 540 * @return The first matching implementation or {@code null}, if no such implementation is found. 541 * 542 * @throws NullPointerException if {@code implementation} is {@code null}. 543 * 544 * @see #getModule() 545 * @see Module#getImplementations() 546 * @see Implementations#getImplementation( java.lang.String ) 547 * @see #clear() 548 */ 549 @Override 550 public Implementation getImplementation( final String implementation ) 551 { 552 if ( implementation == null ) 553 { 554 throw new NullPointerException( "implementation" ); 555 } 556 557 synchronized ( this.implementationByIdentifierCache ) 558 { 559 Implementation i = this.implementationByIdentifierCache.get( implementation ); 560 561 if ( i == null && !this.implementationByIdentifierCache.containsKey( implementation ) ) 562 { 563 i = super.getImplementation( implementation ); 564 this.implementationByIdentifierCache.put( implementation, i ); 565 } 566 567 return i; 568 } 569 } 570 571 /** 572 * Gets an implementation for a given class from the list of modules. 573 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 574 * cached result object is available, this method queries the super-class for a result object to return and caches 575 * the outcome of that query for use on successive calls.</p> 576 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 577 * state of the instance, should the state of the instance change.</p> 578 * 579 * @param implementation The class of the implementation to return. 580 * 581 * @return The first matching implementation or {@code null}, if no such implementation is found. 582 * 583 * @throws NullPointerException if {@code implementation} is {@code null}. 584 * 585 * @see #getModule() 586 * @see Module#getImplementations() 587 * @see Implementations#getImplementation( java.lang.Class ) 588 * @see #clear() 589 */ 590 @Override 591 public Implementation getImplementation( final Class<?> implementation ) 592 { 593 if ( implementation == null ) 594 { 595 throw new NullPointerException( "implementation" ); 596 } 597 598 synchronized ( this.implementationByClassNameCache ) 599 { 600 Implementation i = this.implementationByClassNameCache.get( implementation.getName() ); 601 602 if ( i == null && !this.implementationByClassNameCache.containsKey( implementation.getName() ) ) 603 { 604 i = super.getImplementation( implementation ); 605 this.implementationByClassNameCache.put( implementation.getName(), i ); 606 } 607 608 return i; 609 } 610 } 611 612 /** 613 * Gets an implementation for a given object from the list of modules. 614 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 615 * cached result object is available, this method queries the super-class for a result object to return and caches 616 * the outcome of that query for use on successive calls.</p> 617 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 618 * state of the instance, should the state of the instance change.</p> 619 * 620 * @param object The object of the implementation to return. 621 * 622 * @return The first matching implementation or {@code null}, if no such implementation is found. 623 * 624 * @throws NullPointerException if {@code object} is {@code null}. 625 * 626 * @see #getModule() 627 * @see #getImplementation( java.lang.Class ) 628 * @see #clear() 629 */ 630 @Override 631 public Implementation getImplementation( final Object object ) 632 { 633 if ( object == null ) 634 { 635 throw new NullPointerException( "object" ); 636 } 637 638 synchronized ( this.implementationByObjectClassNameCache ) 639 { 640 Implementation i = this.implementationByObjectClassNameCache.get( object.getClass().getName() ); 641 642 if ( i == null && !this.implementationByObjectClassNameCache.containsKey( object.getClass().getName() ) ) 643 { 644 i = super.getImplementation( object ); 645 this.implementationByObjectClassNameCache.put( object.getClass().getName(), i ); 646 } 647 648 return i; 649 } 650 } 651 652 /** 653 * Gets an implementation for a given name implementing a given specification from the list of modules. 654 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 655 * cached result object is available, this method queries the super-class for a result object to return and caches 656 * the outcome of that query for use on successive calls.</p> 657 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 658 * state of the instance, should the state of the instance change.</p> 659 * 660 * @param specification The identifier of the specification to return an implementation of. 661 * @param name The name of the implementation to return. 662 * 663 * @return The first matching implementation or {@code null}, if no such implementation is found. 664 * 665 * @throws NullPointerException if {@code specification} or {@code name} is {@code null}. 666 * 667 * @see #getModule() 668 * @see #getImplementations( java.lang.String ) 669 * @see Implementations#getImplementationByName( java.lang.String ) 670 * @see #clear() 671 */ 672 @Override 673 public Implementation getImplementation( final String specification, final String name ) 674 { 675 if ( specification == null ) 676 { 677 throw new NullPointerException( "specification" ); 678 } 679 if ( name == null ) 680 { 681 throw new NullPointerException( "name" ); 682 } 683 684 synchronized ( this.implementationBySpecificationAndNameCache ) 685 { 686 final String key = specification + "|" + name; 687 Implementation i = this.implementationBySpecificationAndNameCache.get( key ); 688 689 if ( i == null && !this.implementationBySpecificationAndNameCache.containsKey( key ) ) 690 { 691 i = super.getImplementation( specification, name ); 692 this.implementationBySpecificationAndNameCache.put( key, i ); 693 } 694 695 return i; 696 } 697 } 698 699 /** 700 * Gets all dependencies of an implementation from the list of modules. 701 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 702 * cached result object is available, this method queries the super-class for a result object to return and caches 703 * the outcome of that query for use on successive calls.</p> 704 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 705 * state of the instance, should the state of the instance change.</p> 706 * 707 * @param implementation The identifier of the implementation to get all dependencies of. 708 * 709 * @return All dependencies of the first matching implementation or {@code null}, if no such implementation is 710 * found or if the first matching implementation does not have any dependencies. 711 * 712 * @throws NullPointerException if {@code implementation} is {@code null}. 713 * 714 * @see #getModule() 715 * @see #getImplementation( java.lang.String ) 716 * @see Implementation#getImplementations() 717 * @see Implementations#getReference() 718 * @see #clear() 719 */ 720 @Override 721 public Dependencies getDependencies( final String implementation ) 722 { 723 if ( implementation == null ) 724 { 725 throw new NullPointerException( "implementation" ); 726 } 727 728 synchronized ( this.dependenciesByImplementationIdentifierCache ) 729 { 730 Dependencies d = this.dependenciesByImplementationIdentifierCache.get( implementation ); 731 732 if ( d == null && !this.dependenciesByImplementationIdentifierCache.containsKey( implementation ) ) 733 { 734 d = super.getDependencies( implementation ); 735 736 if ( d != null ) 737 { 738 d = RuntimeModelObjects.getInstance().copyOf( d ); 739 } 740 741 this.dependenciesByImplementationIdentifierCache.put( implementation, d ); 742 } 743 744 return d; 745 } 746 } 747 748 /** 749 * Gets all properties of an implementation from the list of modules. 750 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 751 * cached result object is available, this method queries the super-class for a result object to return and caches 752 * the outcome of that query for use on successive calls.</p> 753 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 754 * state of the instance, should the state of the instance change.</p> 755 * 756 * @param implementation The identifier of the implementation to get all properties of. 757 * 758 * @return All properties of the first matching implementation or {@code null}, if no such implementation is found 759 * or if the first matching implementation does not have any properties. 760 * 761 * @throws NullPointerException if {@code implementation} is {@code null}. 762 * 763 * @see #getModule() 764 * @see #getImplementation( java.lang.String ) 765 * @see Implementation#getImplementations() 766 * @see Implementations#getReference() 767 * @see #clear() 768 */ 769 @Override 770 public Properties getProperties( final String implementation ) 771 { 772 if ( implementation == null ) 773 { 774 throw new NullPointerException( "implementation" ); 775 } 776 777 synchronized ( this.propertiesByImplementationIdentifierCache ) 778 { 779 Properties p = this.propertiesByImplementationIdentifierCache.get( implementation ); 780 781 if ( p == null && !this.propertiesByImplementationIdentifierCache.containsKey( implementation ) ) 782 { 783 p = super.getProperties( implementation ); 784 785 if ( p != null ) 786 { 787 p = RuntimeModelObjects.getInstance().copyOf( p ); 788 } 789 790 this.propertiesByImplementationIdentifierCache.put( implementation, p ); 791 } 792 793 return p; 794 } 795 } 796 797 /** 798 * Gets all properties specified for an implementation from the list of modules. 799 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 800 * cached result object is available, this method queries the super-class for a result object to return and caches 801 * the outcome of that query for use on successive calls.</p> 802 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 803 * state of the instance, should the state of the instance change.</p> 804 * 805 * @param implementation The identifier of the implementation to return specified properties of. 806 * 807 * @return All properties specified for the first matching implementation or {@code null}, if no such implementation 808 * is found or if the first matching implementation does not have any specified properties. 809 * 810 * @throws NullPointerException if {@code implementation} is {@code null}. 811 * 812 * @see #getModule() 813 * @see #getSpecifications( java.lang.String ) 814 * @see Specification#getProperties() 815 * @see #clear() 816 */ 817 @Override 818 public Properties getSpecifiedProperties( final String implementation ) 819 { 820 if ( implementation == null ) 821 { 822 throw new NullPointerException( "implementation" ); 823 } 824 825 synchronized ( this.specifiedPropertiesByImplementationIdentifierCache ) 826 { 827 Properties p = this.specifiedPropertiesByImplementationIdentifierCache.get( implementation ); 828 829 if ( p == null && !this.specifiedPropertiesByImplementationIdentifierCache.containsKey( implementation ) ) 830 { 831 p = super.getSpecifiedProperties( implementation ); 832 833 if ( p != null ) 834 { 835 p = RuntimeModelObjects.getInstance().copyOf( p ); 836 } 837 838 this.specifiedPropertiesByImplementationIdentifierCache.put( implementation, p ); 839 } 840 841 return p; 842 } 843 } 844 845 /** 846 * Gets all messages of an implementation from the list of modules. 847 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 848 * cached result object is available, this method queries the super-class for a result object to return and caches 849 * the outcome of that query for use on successive calls.</p> 850 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 851 * state of the instance, should the state of the instance change.</p> 852 * 853 * @param implementation The identifier of the implementation to get all messages of. 854 * 855 * @return All messages of the first matching implementation or {@code null}, if no such implementation is found 856 * or if the first matching implementation does not have any messages. 857 * 858 * @throws NullPointerException if {@code implementation} is {@code null}. 859 * 860 * @see #getModule() 861 * @see #getImplementation( java.lang.String ) 862 * @see Implementation#getImplementations() 863 * @see Implementations#getReference() 864 * @see #clear() 865 */ 866 @Override 867 public Messages getMessages( final String implementation ) 868 { 869 if ( implementation == null ) 870 { 871 throw new NullPointerException( "implementation" ); 872 } 873 874 synchronized ( this.messagesByImplementationIdentifierCache ) 875 { 876 Messages m = this.messagesByImplementationIdentifierCache.get( implementation ); 877 878 if ( m == null && !this.messagesByImplementationIdentifierCache.containsKey( implementation ) ) 879 { 880 m = super.getMessages( implementation ); 881 882 if ( m != null ) 883 { 884 m = RuntimeModelObjects.getInstance().copyOf( m ); 885 } 886 887 this.messagesByImplementationIdentifierCache.put( implementation, m ); 888 } 889 890 return m; 891 } 892 } 893 894 /** 895 * Gets all implementations implementing a given specification from the list of modules. 896 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 897 * cached result object is available, this method queries the super-class for a result object to return and caches 898 * the outcome of that query for use on successive calls.</p> 899 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 900 * state of the instance, should the state of the instance change.</p> 901 * 902 * @param specification The identifier of the specification to return all implementations of. 903 * 904 * @return All implementations implementing the first matching specification or {@code null}, if no such 905 * specification is found or if the first matching specification does not have any implementations. 906 * 907 * @throws NullPointerException if {@code specification} is {@code null}. 908 * 909 * @see #getModule() 910 * @see #getSpecifications( java.lang.String ) 911 * @see #clear() 912 */ 913 @Override 914 public Implementations getImplementations( final String specification ) 915 { 916 if ( specification == null ) 917 { 918 throw new NullPointerException( "specification" ); 919 } 920 921 synchronized ( this.implementationsBySpecificationIdentifierCache ) 922 { 923 Implementations i = this.implementationsBySpecificationIdentifierCache.get( specification ); 924 925 if ( i == null && !this.implementationsBySpecificationIdentifierCache.containsKey( specification ) ) 926 { 927 i = super.getImplementations( specification ); 928 929 if ( i != null ) 930 { 931 i = RuntimeModelObjects.getInstance().copyOf( i ); 932 } 933 934 this.implementationsBySpecificationIdentifierCache.put( specification, i ); 935 } 936 937 return i; 938 } 939 } 940 941 /** 942 * Gets any objects of an implementation from the list of modules. 943 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 944 * cached result object is available, this method queries the super-class for a result object to return and caches 945 * the outcome of that query for use on successive calls.</p> 946 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 947 * state of the instance, should the state of the instance change.</p> 948 * 949 * @param implementation The identifier of the implementation to get any objects of. 950 * 951 * @return Any objects of the first matching implementation or {@code null}, if no such implementation is found. 952 * 953 * @throws NullPointerException if {@code implementation} is {@code null}. 954 * 955 * @see #getModule() 956 * @see #getImplementation( java.lang.String ) 957 * @see Implementation#getImplementations() 958 * @see Implementations#getReference() 959 * @see #clear() 960 */ 961 @Override 962 public List<Object> getAnyObjects( final String implementation ) 963 { 964 if ( implementation == null ) 965 { 966 throw new NullPointerException( "implementation" ); 967 } 968 969 synchronized ( this.anyObjectsByImplemenationIdentifierCache ) 970 { 971 List<Object> any = this.anyObjectsByImplemenationIdentifierCache.get( implementation ); 972 973 if ( any == null && !this.anyObjectsByImplemenationIdentifierCache.containsKey( implementation ) ) 974 { 975 any = super.getAnyObjects( implementation ); 976 this.anyObjectsByImplemenationIdentifierCache.put( implementation, any ); 977 } 978 979 return any; 980 } 981 } 982 983 /** 984 * Gets an instance for an implementation from the list of modules. 985 * 986 * @param implementation The identifier of the implementation to get an instance for. 987 * 988 * @return A new instance for the first matching implementation or {@code null}, if no such implementation is found. 989 * 990 * @throws NullPointerException if {@code implementation} is {@code null}. 991 * 992 * @see #getModule() 993 * @see #getImplementation( java.lang.String ) 994 * @see #getDependencies(java.lang.String) 995 * @see #getProperties(java.lang.String) 996 * @see #getMessages(java.lang.String) 997 * @see #getSpecifications(java.lang.String) 998 * @see #getAnyObjects(java.lang.String) 999 */ 1000 @Override 1001 public Instance getInstance( final String implementation ) 1002 { 1003 if ( implementation == null ) 1004 { 1005 throw new NullPointerException( "implementation" ); 1006 } 1007 1008 final Implementation i = this.getImplementation( implementation ); 1009 1010 if ( i != null && i.getClazz() != null ) 1011 { 1012 final Instance instance = new RuntimeInstance(); 1013 instance.setIdentifier( i.getIdentifier() ); 1014 instance.setName( i.getName() ); 1015 instance.setClazz( i.getClazz() ); 1016 instance.setStateless( i.isStateless() ); 1017 instance.setDependencies( this.getDependencies( implementation ) ); 1018 instance.setProperties( this.getProperties( implementation ) ); 1019 instance.setMessages( this.getMessages( implementation ) ); 1020 instance.setSpecifications( this.getSpecifications( implementation ) ); 1021 instance.getAny().addAll( this.getAnyObjects( implementation ) ); 1022 return instance; 1023 } 1024 1025 return null; 1026 } 1027 1028 /** 1029 * Gets an instance for an implementation from the list of modules overridden with a given dependency. 1030 * 1031 * @param implementation The identifier of the implementation to get an instance for. 1032 * @param dependency The dependency to use for overriding model objects of the instance. 1033 * 1034 * @return An instance for the first matching implementation with any model objects overridden using 1035 * {@code dependency} or {@code null}, if no such implementation is found. 1036 * 1037 * @throws NullPointerException if {@code implementation} or {@code dependency} is {@code null}. 1038 * 1039 * @see #getModule() 1040 * @see #getInstance( java.lang.String ) 1041 */ 1042 @Override 1043 public Instance getInstance( final String implementation, final Dependency dependency ) 1044 { 1045 if ( implementation == null ) 1046 { 1047 throw new NullPointerException( "implementation" ); 1048 } 1049 if ( dependency == null ) 1050 { 1051 throw new NullPointerException( "dependency" ); 1052 } 1053 1054 Instance instance = this.getInstance( implementation ); 1055 1056 if ( instance != null ) 1057 { 1058 final Specification dependencySpecification = this.getSpecification( dependency.getIdentifier() ); 1059 1060 if ( dependencySpecification != null && dependencySpecification.getScope() == null ) 1061 { 1062 if ( dependency.getDependencies() != null && !dependency.getDependencies().getDependency().isEmpty() ) 1063 { 1064 final Dependencies dependencies = 1065 RuntimeModelObjects.getInstance().copyOf( dependency.getDependencies() ); 1066 1067 if ( instance.getDependencies() != null ) 1068 { 1069 for ( int i = 0, s0 = instance.getDependencies().getDependency().size(); i < s0; i++ ) 1070 { 1071 final Dependency d = instance.getDependencies().getDependency().get( i ); 1072 final Dependency td = dependencies.getDependency( d.getName() ); 1073 1074 if ( td == null ) 1075 { 1076 dependencies.getDependency().add( d ); 1077 1078 if ( dependencies instanceof RuntimeModelObject ) 1079 { 1080 ( (RuntimeModelObject) dependencies ).clear(); 1081 } 1082 } 1083 else 1084 { 1085 this.collectDependencies( d, td ); 1086 } 1087 } 1088 } 1089 1090 instance.setDependencies( dependencies ); 1091 } 1092 1093 if ( dependency.getMessages() != null && !dependency.getMessages().getMessage().isEmpty() ) 1094 { 1095 final Messages messages = 1096 RuntimeModelObjects.getInstance().copyOf( dependency.getMessages() ); 1097 1098 if ( instance.getMessages() != null ) 1099 { 1100 for ( int i = 0, s0 = instance.getMessages().getMessage().size(); i < s0; i++ ) 1101 { 1102 final Message m = instance.getMessages().getMessage().get( i ); 1103 1104 if ( messages.getMessage( m.getName() ) == null ) 1105 { 1106 messages.getMessage().add( m ); 1107 1108 if ( messages instanceof RuntimeModelObject ) 1109 { 1110 ( (RuntimeModelObject) messages ).clear(); 1111 } 1112 } 1113 } 1114 } 1115 1116 instance.setMessages( messages ); 1117 } 1118 1119 if ( dependency.getProperties() != null && !dependency.getProperties().getProperty().isEmpty() ) 1120 { 1121 final Properties properties = 1122 RuntimeModelObjects.getInstance().copyOf( dependency.getProperties() ); 1123 1124 if ( instance.getProperties() != null ) 1125 { 1126 for ( int i = 0, s0 = instance.getProperties().getProperty().size(); i < s0; i++ ) 1127 { 1128 final Property p = instance.getProperties().getProperty().get( i ); 1129 1130 if ( properties.getProperty( p.getName() ) == null ) 1131 { 1132 properties.getProperty().add( p ); 1133 1134 if ( properties instanceof RuntimeModelObject ) 1135 { 1136 ( (RuntimeModelObject) properties ).clear(); 1137 } 1138 } 1139 } 1140 } 1141 1142 instance.setProperties( properties ); 1143 } 1144 } 1145 } 1146 1147 return instance; 1148 } 1149 1150 private void collectDependencies( final Dependency source, final Dependency target ) 1151 { 1152 if ( source.getMessages() != null ) 1153 { 1154 if ( target.getMessages() == null ) 1155 { 1156 target.setMessages( new RuntimeMessages() ); 1157 } 1158 1159 for ( int i = 0, s0 = source.getMessages().getMessage().size(); i < s0; i++ ) 1160 { 1161 final Message m = source.getMessages().getMessage().get( i ); 1162 1163 if ( target.getMessages().getMessage( m.getName() ) == null ) 1164 { 1165 target.getMessages().getMessage().add( m ); 1166 1167 if ( target.getMessages() instanceof RuntimeModelObject ) 1168 { 1169 ( (RuntimeModelObject) target.getMessages() ).clear(); 1170 } 1171 } 1172 } 1173 } 1174 1175 if ( source.getProperties() != null ) 1176 { 1177 if ( target.getProperties() == null ) 1178 { 1179 target.setProperties( new RuntimeProperties() ); 1180 } 1181 1182 for ( int i = 0, s0 = source.getProperties().getProperty().size(); i < s0; i++ ) 1183 { 1184 final Property p = source.getProperties().getProperty().get( i ); 1185 1186 if ( target.getProperties().getProperty( p.getName() ) == null ) 1187 { 1188 target.getProperties().getProperty().add( p ); 1189 1190 if ( target.getProperties() instanceof RuntimeModelObject ) 1191 { 1192 ( (RuntimeModelObject) target.getProperties() ).clear(); 1193 } 1194 } 1195 } 1196 } 1197 1198 if ( source.getDependencies() != null ) 1199 { 1200 if ( target.getDependencies() == null ) 1201 { 1202 target.setDependencies( new RuntimeDependencies() ); 1203 } 1204 1205 for ( int i = 0, s0 = source.getDependencies().getDependency().size(); i < s0; i++ ) 1206 { 1207 final Dependency sd = source.getDependencies().getDependency().get( i ); 1208 final Dependency td = target.getDependencies().getDependency( sd.getName() ); 1209 1210 if ( td == null ) 1211 { 1212 target.getDependencies().getDependency().add( sd ); 1213 1214 if ( target.getDependencies() instanceof RuntimeModelObject ) 1215 { 1216 ( (RuntimeModelObject) target.getDependencies() ).clear(); 1217 } 1218 } 1219 else 1220 { 1221 this.collectDependencies( sd, td ); 1222 } 1223 } 1224 } 1225 } 1226 1227 private void copyModules() 1228 { 1229 for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ ) 1230 { 1231 final Module m = this.getModule().get( i ); 1232 this.getModule().set( i, RuntimeModelObjects.getInstance().copyOf( m ) ); 1233 } 1234 } 1235 1236 // SECTION-END 1237 // SECTION-START[RuntimeModelObject] 1238 public void gc() 1239 { 1240 gcMap( this.specificationsCache ); 1241 gcMap( this.implementationsCache ); 1242 gcMap( this.specificationsByImplemenationIdentifierCache ); 1243 gcMap( this.dependenciesByImplementationIdentifierCache ); 1244 gcMap( this.propertiesByImplementationIdentifierCache ); 1245 gcMap( this.specifiedPropertiesByImplementationIdentifierCache ); 1246 gcMap( this.messagesByImplementationIdentifierCache ); 1247 gcMap( this.implementationsBySpecificationIdentifierCache ); 1248 this.gcOrClear( true, false ); 1249 } 1250 1251 public void clear() 1252 { 1253 synchronized ( this.anyObjectsByImplemenationIdentifierCache ) 1254 { 1255 this.anyObjectsByImplemenationIdentifierCache.clear(); 1256 } 1257 synchronized ( this.dependenciesByImplementationIdentifierCache ) 1258 { 1259 this.dependenciesByImplementationIdentifierCache.clear(); 1260 } 1261 synchronized ( this.implementationByClassNameCache ) 1262 { 1263 this.implementationByClassNameCache.clear(); 1264 } 1265 synchronized ( this.implementationByIdentifierCache ) 1266 { 1267 this.implementationByIdentifierCache.clear(); 1268 } 1269 synchronized ( this.implementationByObjectClassNameCache ) 1270 { 1271 this.implementationByObjectClassNameCache.clear(); 1272 } 1273 synchronized ( this.implementationBySpecificationAndNameCache ) 1274 { 1275 this.implementationBySpecificationAndNameCache.clear(); 1276 } 1277 synchronized ( this.implementationsBySpecificationIdentifierCache ) 1278 { 1279 this.implementationsBySpecificationIdentifierCache.clear(); 1280 } 1281 synchronized ( this.implementationsCache ) 1282 { 1283 this.implementationsCache.clear(); 1284 } 1285 synchronized ( this.messagesByImplementationIdentifierCache ) 1286 { 1287 this.messagesByImplementationIdentifierCache.clear(); 1288 } 1289 synchronized ( this.moduleByImplementationIdentifierCache ) 1290 { 1291 this.moduleByImplementationIdentifierCache.clear(); 1292 } 1293 synchronized ( this.moduleBySpecificationIdentifierCache ) 1294 { 1295 this.moduleBySpecificationIdentifierCache.clear(); 1296 } 1297 synchronized ( this.modulesByNameCache ) 1298 { 1299 this.modulesByNameCache.clear(); 1300 } 1301 synchronized ( this.propertiesByImplementationIdentifierCache ) 1302 { 1303 this.propertiesByImplementationIdentifierCache.clear(); 1304 } 1305 synchronized ( this.specificationByClassNameCache ) 1306 { 1307 this.specificationByClassNameCache.clear(); 1308 } 1309 synchronized ( this.specificationByIdentifierCache ) 1310 { 1311 this.specificationByIdentifierCache.clear(); 1312 } 1313 synchronized ( this.specificationsByImplemenationIdentifierCache ) 1314 { 1315 this.specificationsByImplemenationIdentifierCache.clear(); 1316 } 1317 synchronized ( this.specificationsCache ) 1318 { 1319 this.specificationsCache.clear(); 1320 } 1321 synchronized ( this.specifiedPropertiesByImplementationIdentifierCache ) 1322 { 1323 this.specifiedPropertiesByImplementationIdentifierCache.clear(); 1324 } 1325 1326 this.gcOrClear( false, true ); 1327 } 1328 1329 private void gcOrClear( final boolean gc, final boolean clear ) 1330 { 1331 if ( this.getAuthors() instanceof RuntimeModelObject ) 1332 { 1333 if ( gc ) 1334 { 1335 ( (RuntimeModelObject) this.getAuthors() ).gc(); 1336 } 1337 if ( clear ) 1338 { 1339 ( (RuntimeModelObject) this.getAuthors() ).clear(); 1340 } 1341 } 1342 if ( this.getDocumentation() instanceof RuntimeModelObject ) 1343 { 1344 if ( gc ) 1345 { 1346 ( (RuntimeModelObject) this.getDocumentation() ).gc(); 1347 } 1348 if ( clear ) 1349 { 1350 ( (RuntimeModelObject) this.getDocumentation() ).clear(); 1351 } 1352 } 1353 1354 this.gcOrClearModules( gc, clear ); 1355 } 1356 1357 private void gcOrClearModules( final boolean gc, final boolean clear ) 1358 { 1359 1360 for ( int i = 0, s0 = this.getModule().size(); i < s0; i++ ) 1361 { 1362 final Module m = this.getModule().get( i ); 1363 if ( m instanceof RuntimeModelObject ) 1364 { 1365 if ( gc ) 1366 { 1367 ( (RuntimeModelObject) m ).gc(); 1368 } 1369 if ( clear ) 1370 { 1371 ( (RuntimeModelObject) m ).clear(); 1372 } 1373 } 1374 } 1375 } 1376 1377 private static void gcMap( final Map<?, ?> map ) 1378 { 1379 synchronized ( map ) 1380 { 1381 for ( Map.Entry<?, ?> e : map.entrySet() ) 1382 { 1383 if ( e.getValue() instanceof RuntimeModelObject ) 1384 { 1385 ( (RuntimeModelObject) e.getValue() ).gc(); 1386 } 1387 } 1388 } 1389 } 1390 1391 // SECTION-END 1392 // SECTION-START[Constructors] 1393 // <editor-fold defaultstate="collapsed" desc=" Generated Constructors "> 1394 /** Creates a new {@code RuntimeModules} instance. */ 1395 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" ) 1396 public RuntimeModules() 1397 { 1398 // SECTION-START[Default Constructor] 1399 super(); 1400 // SECTION-END 1401 } 1402 // </editor-fold> 1403 // SECTION-END 1404 // SECTION-START[Dependencies] 1405 // SECTION-END 1406 // SECTION-START[Properties] 1407 // SECTION-END 1408 // SECTION-START[Messages] 1409 // SECTION-END 1410}