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, 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: RuntimeImplementations.java 4381 2012-03-04 19:29:29Z schulte2005 $
32   *
33   */
34  // </editor-fold>
35  // SECTION-END
36  package org.jomc.ri.model;
37  
38  import java.util.Map;
39  import javax.xml.bind.annotation.XmlTransient;
40  import org.jomc.model.Implementation;
41  import org.jomc.model.ImplementationReference;
42  import org.jomc.model.Implementations;
43  import static org.jomc.ri.model.RuntimeModelObjects.createMap;
44  
45  // SECTION-START[Documentation]
46  // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
47  /**
48   * Runtime {@code Implementations}.
49   *
50   * <dl>
51   *   <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeImplementations</dd>
52   *   <dt><b>Name:</b></dt><dd>JOMC RI RuntimeImplementations</dd>
53   *   <dt><b>Specifications:</b></dt>
54   *     <dd>org.jomc.ri.model.RuntimeModelObject @ 1.2</dd>
55   *   <dt><b>Abstract:</b></dt><dd>No</dd>
56   *   <dt><b>Final:</b></dt><dd>No</dd>
57   *   <dt><b>Stateless:</b></dt><dd>No</dd>
58   * </dl>
59   *
60   * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.2
61   * @version 1.2
62   */
63  // </editor-fold>
64  // SECTION-END
65  // SECTION-START[Annotations]
66  // <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
67  @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.2.2", comments = "See http://jomc.sourceforge.net/jomc/1.2/jomc-tools-1.2.2" )
68  // </editor-fold>
69  // SECTION-END
70  public class RuntimeImplementations extends Implementations implements RuntimeModelObject
71  {
72      // SECTION-START[RuntimeImplementations]
73  
74      /** Cache map. */
75      @XmlTransient
76      private transient final Map<String, Implementation> implementationsByIdentifierCache = createMap();
77  
78      /** Cache map. */
79      @XmlTransient
80      private transient final Map<String, Implementation> implementationsByClassCache = createMap();
81  
82      /** Cache map. */
83      @XmlTransient
84      private transient final Map<String, Implementation> implementationsByNameCache = createMap();
85  
86      /** Cache map. */
87      @XmlTransient
88      private transient final Map<String, ImplementationReference> referencesByIdentifierCache = createMap();
89  
90      /**
91       * Creates a new {@code RuntimeImplementations} instance by deeply copying a given {@code Implementations} instance.
92       *
93       * @param implementations The instance to copy.
94       *
95       * @throws NullPointerException if {@code implementations} is {@code null}.
96       */
97      public RuntimeImplementations( final Implementations implementations )
98      {
99          super( implementations );
100 
101         if ( this.getAuthors() != null )
102         {
103             this.setAuthors( RuntimeModelObjects.getInstance().copyOf( this.getAuthors() ) );
104         }
105         if ( this.getDocumentation() != null )
106         {
107             this.setDocumentation( RuntimeModelObjects.getInstance().copyOf( this.getDocumentation() ) );
108         }
109 
110         this.copyImplementations();
111         this.copyImplementationReferences();
112     }
113 
114     /**
115      * Gets an implementation for a given identifier from the list of implementations.
116      * <p>This method queries an internal cache for a result object to return for the given argument values. If no
117      * cached result object is available, this method queries the super-class for a result object to return and caches
118      * the outcome of that query for use on successive calls.</p>
119      * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
120      * state of the instance, should the state of the instance change.</p>
121      *
122      * @param implementation The identifier of the implementation to return.
123      *
124      * @return The first matching implementation or {@code null}, if no such implementation is found.
125      *
126      * @throws NullPointerException if {@code implementation} is {@code null}.
127      *
128      * @see #getImplementation()
129      * @see Implementation#getIdentifier()
130      * @see #clear()
131      */
132     @Override
133     public Implementation getImplementation( final String implementation )
134     {
135         if ( implementation == null )
136         {
137             throw new NullPointerException( "implementation" );
138         }
139 
140         synchronized ( this.implementationsByIdentifierCache )
141         {
142             Implementation i = this.implementationsByIdentifierCache.get( implementation );
143 
144             if ( i == null && !this.implementationsByIdentifierCache.containsKey( implementation ) )
145             {
146                 i = super.getImplementation( implementation );
147                 this.implementationsByIdentifierCache.put( implementation, i );
148             }
149 
150             return i;
151         }
152     }
153 
154     /**
155      * Gets an implementation for a given class from the list of implementations.
156      * <p>This method queries an internal cache for a result object to return for the given argument values. If no
157      * cached result object is available, this method queries the super-class for a result object to return and caches
158      * the outcome of that query for use on successive calls.</p>
159      * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
160      * state of the instance, should the state of the instance change.</p>
161      *
162      * @param implementation The class of the implementation to return.
163      *
164      * @return The first matching implementation or {@code null}, if no such implementation is found.
165      *
166      * @throws NullPointerException if {@code implementation} is {@code null}.
167      *
168      * @see #getImplementation()
169      * @see Implementation#isClassDeclaration()
170      * @see Implementation#getClazz()
171      * @see #clear()
172      */
173     @Override
174     public Implementation getImplementation( final Class<?> implementation )
175     {
176         if ( implementation == null )
177         {
178             throw new NullPointerException( "implementation" );
179         }
180 
181         synchronized ( this.implementationsByClassCache )
182         {
183             Implementation i = this.implementationsByClassCache.get( implementation.getName() );
184 
185             if ( i == null && !this.implementationsByClassCache.containsKey( implementation.getName() ) )
186             {
187                 i = super.getImplementation( implementation );
188                 this.implementationsByClassCache.put( implementation.getName(), i );
189             }
190 
191             return i;
192         }
193     }
194 
195     /**
196      * Gets an implementation for a given name from the list of implementations.
197      * <p>This method queries an internal cache for a result object to return for the given argument values. If no
198      * cached result object is available, this method queries the super-class for a result object to return and caches
199      * the outcome of that query for use on successive calls.</p>
200      * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
201      * state of the instance, should the state of the instance change.</p>
202      *
203      * @param name The name of the implementation to return.
204      *
205      * @return The first matching implementation or {@code null}, if no such implementation is found.
206      *
207      * @throws NullPointerException if {@code name} is {@code null}.
208      *
209      * @see #getImplementation()
210      * @see Implementation#getName()
211      * @see #clear()
212      */
213     @Override
214     public Implementation getImplementationByName( final String name )
215     {
216         if ( name == null )
217         {
218             throw new NullPointerException( "name" );
219         }
220 
221         synchronized ( this.implementationsByNameCache )
222         {
223             Implementation i = this.implementationsByNameCache.get( name );
224 
225             if ( i == null && !this.implementationsByNameCache.containsKey( name ) )
226             {
227                 i = super.getImplementationByName( name );
228                 this.implementationsByNameCache.put( name, i );
229             }
230 
231             return i;
232         }
233     }
234 
235     /**
236      * Gets an implementation reference for a given identifier from the list of references.
237      * <p>This method queries an internal cache for a result object to return for the given argument values. If no
238      * cached result object is available, this method queries the super-class for a result object to return and caches
239      * the outcome of that query for use on successive calls.</p>
240      * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
241      * state of the instance, should the state of the instance change.</p>
242      *
243      * @param implementation The identifier of the reference to return.
244      *
245      * @return The first matching implementation reference or {@code null}, if no such reference is found.
246      *
247      * @throws NullPointerException if {@code implementation} is {@code null}.
248      *
249      * @see #getReference()
250      * @see ImplementationReference#getIdentifier()
251      * @see #clear()
252      */
253     @Override
254     public ImplementationReference getReference( final String implementation )
255     {
256         if ( implementation == null )
257         {
258             throw new NullPointerException( "implementation" );
259         }
260 
261         synchronized ( this.referencesByIdentifierCache )
262         {
263             ImplementationReference r = this.referencesByIdentifierCache.get( implementation );
264 
265             if ( r == null && !this.referencesByIdentifierCache.containsKey( implementation ) )
266             {
267                 r = super.getReference( implementation );
268                 this.referencesByIdentifierCache.put( implementation, r );
269             }
270 
271             return r;
272         }
273     }
274 
275     private void copyImplementations()
276     {
277         for ( int i = 0, s0 = this.getImplementation().size(); i < s0; i++ )
278         {
279             final Implementation impl = this.getImplementation().get( i );
280             this.getImplementation().set( i, RuntimeModelObjects.getInstance().copyOf( impl ) );
281         }
282     }
283 
284     private void copyImplementationReferences()
285     {
286         for ( int i = 0, s0 = this.getReference().size(); i < s0; i++ )
287         {
288             final ImplementationReference r = this.getReference().get( i );
289             this.getReference().set( i, RuntimeModelObjects.getInstance().copyOf( r ) );
290         }
291     }
292 
293     // SECTION-END
294     // SECTION-START[RuntimeModelObject]
295     public void gc()
296     {
297         this.gcOrClear( true, false );
298     }
299 
300     public void clear()
301     {
302         synchronized ( this.implementationsByClassCache )
303         {
304             this.implementationsByClassCache.clear();
305         }
306         synchronized ( this.implementationsByIdentifierCache )
307         {
308             this.implementationsByIdentifierCache.clear();
309         }
310         synchronized ( this.implementationsByNameCache )
311         {
312             this.implementationsByNameCache.clear();
313         }
314         synchronized ( this.referencesByIdentifierCache )
315         {
316             this.referencesByIdentifierCache.clear();
317         }
318 
319         this.gcOrClear( false, true );
320     }
321 
322     private void gcOrClear( final boolean gc, final boolean clear )
323     {
324         if ( this.getAuthors() instanceof RuntimeModelObject )
325         {
326             if ( gc )
327             {
328                 ( (RuntimeModelObject) this.getAuthors() ).gc();
329             }
330             if ( clear )
331             {
332                 ( (RuntimeModelObject) this.getAuthors() ).clear();
333             }
334         }
335         if ( this.getDocumentation() instanceof RuntimeModelObject )
336         {
337             if ( gc )
338             {
339                 ( (RuntimeModelObject) this.getDocumentation() ).gc();
340             }
341             if ( clear )
342             {
343                 ( (RuntimeModelObject) this.getDocumentation() ).clear();
344             }
345         }
346 
347         this.gcOrClearImplementationReferences( gc, clear );
348         this.gcOrClearImplementations( gc, clear );
349     }
350 
351     private void gcOrClearImplementations( final boolean gc, final boolean clear )
352     {
353         for ( int i = 0, s0 = this.getImplementation().size(); i < s0; i++ )
354         {
355             final Implementation impl = this.getImplementation().get( i );
356             if ( impl instanceof RuntimeModelObject )
357             {
358                 if ( gc )
359                 {
360                     ( (RuntimeModelObject) impl ).gc();
361                 }
362                 if ( clear )
363                 {
364                     ( (RuntimeModelObject) impl ).clear();
365                 }
366             }
367         }
368     }
369 
370     private void gcOrClearImplementationReferences( final boolean gc, final boolean clear )
371     {
372         for ( int i = 0, s0 = this.getReference().size(); i < s0; i++ )
373         {
374             final ImplementationReference r = this.getReference().get( i );
375             if ( r instanceof RuntimeModelObject )
376             {
377                 if ( gc )
378                 {
379                     ( (RuntimeModelObject) r ).gc();
380                 }
381                 if ( clear )
382                 {
383                     ( (RuntimeModelObject) r ).clear();
384                 }
385             }
386         }
387     }
388 
389     // SECTION-END
390     // SECTION-START[Constructors]
391     // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
392     /** Creates a new {@code RuntimeImplementations} instance. */
393     @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.2.2", comments = "See http://jomc.sourceforge.net/jomc/1.2/jomc-tools-1.2.2" )
394     public RuntimeImplementations()
395     {
396         // SECTION-START[Default Constructor]
397         super();
398         // SECTION-END
399     }
400     // </editor-fold>
401     // SECTION-END
402     // SECTION-START[Dependencies]
403     // SECTION-END
404     // SECTION-START[Properties]
405     // SECTION-END
406     // SECTION-START[Messages]
407     // SECTION-END
408 }