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: RuntimeSpecifications.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.Specification;
41  import org.jomc.model.SpecificationReference;
42  import org.jomc.model.Specifications;
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 Specifications}.
49   *
50   * <dl>
51   *   <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeSpecifications</dd>
52   *   <dt><b>Name:</b></dt><dd>JOMC RI RuntimeSpecifications</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 RuntimeSpecifications extends Specifications implements RuntimeModelObject
71  {
72      // SECTION-START[RuntimeSpecifications]
73  
74      /** Cache map. */
75      @XmlTransient
76      private transient final Map<String, Specification> specificationsByIdentifierCache = createMap();
77  
78      /** Cache map. */
79      @XmlTransient
80      private transient final Map<String, Specification> specificationsByClassCache = createMap();
81  
82      /** Cache map. */
83      @XmlTransient
84      private transient final Map<String, SpecificationReference> referencesByIdentifierCache = createMap();
85  
86      /**
87       * Creates a new {@code RuntimeSpecifications} instance by deeply copying a given {@code Specifications} instance.
88       *
89       * @param specifications The instance to copy.
90       *
91       * @throws NullPointerException if {@code specifications} is {@code null}.
92       */
93      public RuntimeSpecifications( final Specifications specifications )
94      {
95          super( specifications );
96  
97          if ( this.getAuthors() != null )
98          {
99              this.setAuthors( RuntimeModelObjects.getInstance().copyOf( this.getAuthors() ) );
100         }
101         if ( this.getDocumentation() != null )
102         {
103             this.setDocumentation( RuntimeModelObjects.getInstance().copyOf( this.getDocumentation() ) );
104         }
105 
106         this.copySpecifications();
107         this.copyReferences();
108     }
109 
110     /**
111      * Gets a specification for a given identifier from the list of specifications.
112      * <p>This method queries an internal cache for a result object to return for the given argument values. If no
113      * cached result object is available, this method queries the super-class for a result object to return and caches
114      * the outcome of that query for use on successive calls.</p>
115      * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
116      * state of the instance, should the state of the instance change.</p>
117      *
118      * @param specification The identifier of the specification to return.
119      *
120      * @return The first matching specification or {@code null}, if no such specification is found.
121      *
122      * @throws NullPointerException if {@code specification} is {@code null}.
123      *
124      * @see #getSpecification()
125      * @see Specification#getIdentifier()
126      * @see #clear()
127      */
128     @Override
129     public Specification getSpecification( final String specification )
130     {
131         if ( specification == null )
132         {
133             throw new NullPointerException( "specification" );
134         }
135 
136         synchronized ( this.specificationsByIdentifierCache )
137         {
138             Specification s = this.specificationsByIdentifierCache.get( specification );
139 
140             if ( s == null && !this.specificationsByIdentifierCache.containsKey( specification ) )
141             {
142                 s = super.getSpecification( specification );
143                 this.specificationsByIdentifierCache.put( specification, s );
144             }
145 
146             return s;
147         }
148     }
149 
150     /**
151      * Gets a specification for a given class from the list of specifications.
152      * <p>This method queries an internal cache for a result object to return for the given argument values. If no
153      * cached result object is available, this method queries the super-class for a result object to return and caches
154      * the outcome of that query for use on successive calls.</p>
155      * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
156      * state of the instance, should the state of the instance change.</p>
157      *
158      * @param specification The class of the specification to return.
159      *
160      * @return The first matching specification or {@code null}, if no such specification is found.
161      *
162      * @throws NullPointerException if {@code specification} is {@code null}.
163      *
164      * @see #getSpecification()
165      * @see Specification#isClassDeclaration()
166      * @see Specification#getClazz()
167      * @see #clear()
168      */
169     @Override
170     public Specification getSpecification( final Class<?> specification )
171     {
172         if ( specification == null )
173         {
174             throw new NullPointerException( "specification" );
175         }
176 
177         synchronized ( this.specificationsByClassCache )
178         {
179             Specification s = this.specificationsByClassCache.get( specification.getName() );
180 
181             if ( s == null && !this.specificationsByClassCache.containsKey( specification.getName() ) )
182             {
183                 s = super.getSpecification( specification );
184                 this.specificationsByClassCache.put( specification.getName(), s );
185             }
186 
187             return s;
188         }
189     }
190 
191     /**
192      * Gets a specification reference for a given identifier from the list of references.
193      * <p>This method queries an internal cache for a result object to return for the given argument values. If no
194      * cached result object is available, this method queries the super-class for a result object to return and caches
195      * the outcome of that query for use on successive calls.</p>
196      * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
197      * state of the instance, should the state of the instance change.</p>
198      *
199      * @param specification The identifier of the reference to return.
200      *
201      * @return The first matching specification reference or {@code null}, if no such specification reference is found.
202      *
203      * @throws NullPointerException if {@code specification} is {@code null}.
204      *
205      * @see #getReference()
206      * @see SpecificationReference#getIdentifier()
207      * @see #clear()
208      */
209     @Override
210     public SpecificationReference getReference( final String specification )
211     {
212         if ( specification == null )
213         {
214             throw new NullPointerException( "specification" );
215         }
216 
217         synchronized ( this.referencesByIdentifierCache )
218         {
219             SpecificationReference r = this.referencesByIdentifierCache.get( specification );
220 
221             if ( r == null && !this.referencesByIdentifierCache.containsKey( specification ) )
222             {
223                 r = super.getReference( specification );
224                 this.referencesByIdentifierCache.put( specification, r );
225             }
226 
227             return r;
228         }
229     }
230 
231     private void copySpecifications()
232     {
233         for ( int i = 0, s0 = this.getSpecification().size(); i < s0; i++ )
234         {
235             final Specification s = this.getSpecification().get( i );
236             this.getSpecification().set( i, RuntimeModelObjects.getInstance().copyOf( s ) );
237         }
238     }
239 
240     private void copyReferences()
241     {
242         for ( int i = 0, s0 = this.getReference().size(); i < s0; i++ )
243         {
244             final SpecificationReference r = this.getReference().get( i );
245             this.getReference().set( i, RuntimeModelObjects.getInstance().copyOf( r ) );
246         }
247     }
248 
249     // SECTION-END
250     // SECTION-START[RuntimeModelObject]
251     public void gc()
252     {
253         this.gcOrClear( true, false );
254     }
255 
256     public void clear()
257     {
258         synchronized ( this.specificationsByClassCache )
259         {
260             this.specificationsByClassCache.clear();
261         }
262         synchronized ( this.specificationsByIdentifierCache )
263         {
264             this.specificationsByIdentifierCache.clear();
265         }
266         synchronized ( this.referencesByIdentifierCache )
267         {
268             this.referencesByIdentifierCache.clear();
269         }
270 
271         this.gcOrClear( false, true );
272     }
273 
274     private void gcOrClear( final boolean gc, final boolean clear )
275     {
276         if ( this.getAuthors() instanceof RuntimeModelObject )
277         {
278             if ( gc )
279             {
280                 ( (RuntimeModelObject) this.getAuthors() ).gc();
281             }
282             if ( clear )
283             {
284                 ( (RuntimeModelObject) this.getAuthors() ).clear();
285             }
286         }
287         if ( this.getDocumentation() instanceof RuntimeModelObject )
288         {
289             if ( gc )
290             {
291                 ( (RuntimeModelObject) this.getDocumentation() ).gc();
292             }
293             if ( clear )
294             {
295                 ( (RuntimeModelObject) this.getDocumentation() ).clear();
296             }
297         }
298 
299         this.gcOrClearReferences( gc, clear );
300         this.gcOrClearSpecifications( gc, clear );
301     }
302 
303     private void gcOrClearSpecifications( final boolean gc, final boolean clear )
304     {
305         for ( int i = 0, s0 = this.getSpecification().size(); i < s0; i++ )
306         {
307             final Specification s = this.getSpecification().get( i );
308             if ( s instanceof RuntimeModelObject )
309             {
310                 if ( gc )
311                 {
312                     ( (RuntimeModelObject) s ).gc();
313                 }
314                 if ( clear )
315                 {
316                     ( (RuntimeModelObject) s ).clear();
317                 }
318             }
319         }
320     }
321 
322     private void gcOrClearReferences( final boolean gc, final boolean clear )
323     {
324         for ( int i = 0, s0 = this.getReference().size(); i < s0; i++ )
325         {
326             final SpecificationReference r = this.getReference().get( i );
327             if ( r instanceof RuntimeModelObject )
328             {
329                 if ( gc )
330                 {
331                     ( (RuntimeModelObject) r ).gc();
332                 }
333                 if ( clear )
334                 {
335                     ( (RuntimeModelObject) r ).clear();
336                 }
337             }
338         }
339     }
340     // SECTION-END
341     // SECTION-START[Constructors]
342     // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
343     /** Creates a new {@code RuntimeSpecifications} instance. */
344     @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" )
345     public RuntimeSpecifications()
346     {
347         // SECTION-START[Default Constructor]
348         super();
349         // SECTION-END
350     }
351     // </editor-fold>
352     // SECTION-END
353     // SECTION-START[Dependencies]
354     // SECTION-END
355     // SECTION-START[Properties]
356     // SECTION-END
357     // SECTION-START[Messages]
358     // SECTION-END
359 }