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