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