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: RuntimeSpecification.java 4588 2012-06-03 06:01:30Z schulte2005 $
32   *
33   */
34  // </editor-fold>
35  // SECTION-END
36  package org.jomc.ri.model;
37  
38  import java.lang.ref.Reference;
39  import java.lang.ref.WeakReference;
40  import java.util.Map;
41  import org.jomc.model.Specification;
42  import static org.jomc.ri.model.RuntimeModelObjects.BOOTSTRAP_CLASSLOADER_KEY;
43  import static org.jomc.ri.model.RuntimeModelObjects.classesByClassLoaderAndNameCache;
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 Specification}.
50   *
51   * <dl>
52   *   <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeSpecification</dd>
53   *   <dt><b>Name:</b></dt><dd>JOMC RI RuntimeSpecification</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:schulte2005@users.sourceforge.net">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.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" )
69  // </editor-fold>
70  // SECTION-END
71  public class RuntimeSpecification extends Specification implements RuntimeModelObject
72  {
73      // SECTION-START[RuntimeSpecification]
74  
75      /**
76       * Creates a new {@code RuntimeSpecification} instance by deeply copying a given {@code Specification} instance.
77       *
78       * @param specification The instance to copy.
79       *
80       * @throws NullPointerException if {@code specification} is {@code null}.
81       */
82      public RuntimeSpecification( final Specification specification )
83      {
84          super( specification );
85  
86          if ( this.getAuthors() != null )
87          {
88              this.setAuthors( RuntimeModelObjects.getInstance().copyOf( this.getAuthors() ) );
89          }
90          if ( this.getDocumentation() != null )
91          {
92              this.setDocumentation( RuntimeModelObjects.getInstance().copyOf( this.getDocumentation() ) );
93          }
94          if ( this.getProperties() != null )
95          {
96              this.setProperties( RuntimeModelObjects.getInstance().copyOf( this.getProperties() ) );
97          }
98      }
99  
100     /**
101      * Gets the Java class of the specification for a given class loader.
102      * <p>This method queries an internal cache for a result object to return for the given argument values. If no
103      * cached result object is available, this method queries the super-class for a result object to return and caches
104      * the outcome of that query for use on successive calls.</p>
105      * <p><b>Note:</b><br/>Method {@code RuntimeModelObjects.clear()} must be used to synchronize the state of the
106      * internal cache with the state of the class loader, should the state of the class loader change.</p>
107      *
108      * @param classLoader The class loader to get the Java class from or {@code null}, to get the Java class from the
109      * platform's bootstrap class loader.
110      *
111      * @return The Java class of the specification or {@code null}, if the specification does not declare a class.
112      *
113      * @throws ClassNotFoundException if the Java class is not found.
114      *
115      * @see #getClazz()
116      * @see RuntimeModelObjects#clear()
117      */
118     @Override
119     public Class<?> getJavaClass( final ClassLoader classLoader ) throws ClassNotFoundException
120     {
121         Class<?> javaClass = null;
122 
123         if ( this.getClazz() != null )
124         {
125             synchronized ( classesByClassLoaderAndNameCache )
126             {
127                 ClassLoader classLoaderKey = classLoader;
128                 if ( classLoaderKey == null )
129                 {
130                     classLoaderKey = BOOTSTRAP_CLASSLOADER_KEY;
131                 }
132 
133                 Map<String, Reference<Class<?>>> map = classesByClassLoaderAndNameCache.get( classLoaderKey );
134 
135                 if ( map == null )
136                 {
137                     map = createMap();
138                     classesByClassLoaderAndNameCache.put( classLoaderKey, map );
139                 }
140 
141                 final Reference<Class<?>> reference = map.get( this.getClazz() );
142 
143                 if ( reference != null )
144                 {
145                     javaClass = reference.get();
146                 }
147 
148                 if ( javaClass == null )
149                 {
150                     javaClass = super.getJavaClass( classLoader );
151                     map.put( this.getClazz(), new WeakReference<Class<?>>( javaClass ) );
152                 }
153             }
154         }
155 
156         return javaClass;
157     }
158 
159     // SECTION-END
160     // SECTION-START[RuntimeModelObject]
161     public void gc()
162     {
163         this.gcOrClear( true, false );
164     }
165 
166     public void clear()
167     {
168         this.gcOrClear( false, true );
169     }
170 
171     private void gcOrClear( final boolean gc, final boolean clear )
172     {
173         if ( this.getAuthors() instanceof RuntimeModelObject )
174         {
175             if ( gc )
176             {
177                 ( (RuntimeModelObject) this.getAuthors() ).gc();
178             }
179             if ( clear )
180             {
181                 ( (RuntimeModelObject) this.getAuthors() ).clear();
182             }
183         }
184         if ( this.getDocumentation() instanceof RuntimeModelObject )
185         {
186             if ( gc )
187             {
188                 ( (RuntimeModelObject) this.getDocumentation() ).gc();
189             }
190             if ( clear )
191             {
192                 ( (RuntimeModelObject) this.getDocumentation() ).clear();
193             }
194         }
195         if ( this.getProperties() instanceof RuntimeModelObject )
196         {
197             if ( gc )
198             {
199                 ( (RuntimeModelObject) this.getProperties() ).gc();
200             }
201             if ( clear )
202             {
203                 ( (RuntimeModelObject) this.getProperties() ).clear();
204             }
205         }
206     }
207 
208     // SECTION-END
209     // SECTION-START[Constructors]
210     // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
211     /** Creates a new {@code RuntimeSpecification} instance. */
212     @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" )
213     public RuntimeSpecification()
214     {
215         // SECTION-START[Default Constructor]
216         super();
217         // SECTION-END
218     }
219     // </editor-fold>
220     // SECTION-END
221     // SECTION-START[Dependencies]
222     // SECTION-END
223     // SECTION-START[Properties]
224     // SECTION-END
225     // SECTION-START[Messages]
226     // SECTION-END
227 }