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