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: RuntimeImplementation.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.net.URI;
41  import java.util.Map;
42  import org.jomc.model.Implementation;
43  import static org.jomc.ri.model.RuntimeModelObjects.BOOTSTRAP_CLASSLOADER_KEY;
44  import static org.jomc.ri.model.RuntimeModelObjects.classesByClassLoaderAndNameCache;
45  import static org.jomc.ri.model.RuntimeModelObjects.createMap;
46  
47  // SECTION-START[Documentation]
48  // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
49  /**
50   * Runtime {@code Implementation}.
51   *
52   * <dl>
53   *   <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeImplementation</dd>
54   *   <dt><b>Name:</b></dt><dd>JOMC RI RuntimeImplementation</dd>
55   *   <dt><b>Specifications:</b></dt>
56   *     <dd>org.jomc.ri.model.RuntimeModelObject @ 1.2</dd>
57   *   <dt><b>Abstract:</b></dt><dd>No</dd>
58   *   <dt><b>Final:</b></dt><dd>No</dd>
59   *   <dt><b>Stateless:</b></dt><dd>No</dd>
60   * </dl>
61   *
62   * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.2
63   * @version 1.2
64   */
65  // </editor-fold>
66  // SECTION-END
67  // SECTION-START[Annotations]
68  // <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
69  @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" )
70  // </editor-fold>
71  // SECTION-END
72  public class RuntimeImplementation extends Implementation implements RuntimeModelObject
73  {
74      // SECTION-START[RuntimeImplementation]
75  
76      /** Cached location URI. */
77      private volatile URI locationUri;
78  
79      /**
80       * Creates a new {@code RuntimeImplementation} instance by deeply copying a given {@code Implementation} instance.
81       *
82       * @param implementation The instance to copy.
83       *
84       * @throws NullPointerException if {@code implementation} is {@code null}.
85       */
86      public RuntimeImplementation( final Implementation implementation )
87      {
88          super( implementation );
89  
90          if ( this.getAuthors() != null )
91          {
92              this.setAuthors( RuntimeModelObjects.getInstance().copyOf( this.getAuthors() ) );
93          }
94          if ( this.getDependencies() != null )
95          {
96              this.setDependencies( RuntimeModelObjects.getInstance().copyOf( this.getDependencies() ) );
97          }
98          if ( this.getDocumentation() != null )
99          {
100             this.setDocumentation( RuntimeModelObjects.getInstance().copyOf( this.getDocumentation() ) );
101         }
102         if ( this.getImplementations() != null )
103         {
104             this.setImplementations( RuntimeModelObjects.getInstance().copyOf( this.getImplementations() ) );
105         }
106         if ( this.getMessages() != null )
107         {
108             this.setMessages( RuntimeModelObjects.getInstance().copyOf( this.getMessages() ) );
109         }
110         if ( this.getProperties() != null )
111         {
112             this.setProperties( RuntimeModelObjects.getInstance().copyOf( this.getProperties() ) );
113         }
114         if ( this.getSpecifications() != null )
115         {
116             this.setSpecifications( RuntimeModelObjects.getInstance().copyOf( this.getSpecifications() ) );
117         }
118     }
119 
120     /**
121      * Gets the location URI used for locating instances of this implementation.
122      * <p>This method queries an internal cache for a result object to return. If no cached result object is available,
123      * this method queries the super-class for a result object to return and caches the outcome of that query for use on
124      * successive calls.</p>
125      * <p><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.</p>
127      *
128      * @return The location URI used for locating instances of this implementation or {@code null}, if instances of this
129      * implementation do not need to be located.
130      *
131      * @see #getLocation()
132      * @see #clear()
133      */
134     @Override
135     public URI getLocationUri()
136     {
137         if ( this.locationUri == null )
138         {
139             this.locationUri = super.getLocationUri();
140         }
141 
142         return this.locationUri;
143     }
144 
145     /**
146      * Gets the Java class of the implementation for a given class loader.
147      * <p>This method queries an internal cache for a result object to return for the given argument values. If no
148      * cached result object is available, this method queries the super-class for a result object to return and caches
149      * the outcome of that query for use on successive calls.</p>
150      * <p><b>Note:</b><br/>Method {@code RuntimeModelObjects.clear()} must be used to synchronize the state of the
151      * internal cache with the state of the class loader, should the state of the class loader change.</p>
152      *
153      * @param classLoader The class loader to get the Java class from or {@code null}, to get the Java class from the
154      * platform's bootstrap class loader.
155      *
156      * @return The Java class of the implementation or {@code null}, if the implementation does not declare a class.
157      *
158      * @throws ClassNotFoundException if the Java class is not found.
159      *
160      * @see #getClazz()
161      * @see RuntimeModelObjects#clear()
162      */
163     @Override
164     public Class<?> getJavaClass( final ClassLoader classLoader ) throws ClassNotFoundException
165     {
166         Class<?> javaClass = null;
167 
168         if ( this.getClazz() != null )
169         {
170             ClassLoader classLoaderKey = classLoader;
171             if ( classLoaderKey == null )
172             {
173                 classLoaderKey = BOOTSTRAP_CLASSLOADER_KEY;
174             }
175 
176             synchronized ( classesByClassLoaderAndNameCache )
177             {
178                 Map<String, Reference<Class<?>>> map = classesByClassLoaderAndNameCache.get( classLoaderKey );
179 
180                 if ( map == null )
181                 {
182                     map = createMap();
183                     classesByClassLoaderAndNameCache.put( classLoaderKey, map );
184                 }
185 
186                 final Reference<Class<?>> reference = map.get( this.getClazz() );
187 
188                 if ( reference != null )
189                 {
190                     javaClass = reference.get();
191                 }
192 
193                 if ( javaClass == null )
194                 {
195                     javaClass = super.getJavaClass( classLoader );
196                     map.put( this.getClazz(), new WeakReference<Class<?>>( javaClass ) );
197                 }
198             }
199         }
200 
201         return javaClass;
202     }
203 
204     // SECTION-END
205     // SECTION-START[RuntimeModelObject]
206     public void gc()
207     {
208         this.gcOrClear( true, false );
209     }
210 
211     public void clear()
212     {
213         this.locationUri = null;
214         this.gcOrClear( false, true );
215     }
216 
217     private void gcOrClear( final boolean gc, final boolean clear )
218     {
219         if ( this.getAuthors() instanceof RuntimeModelObject )
220         {
221             if ( gc )
222             {
223                 ( (RuntimeModelObject) this.getAuthors() ).gc();
224             }
225             if ( clear )
226             {
227                 ( (RuntimeModelObject) this.getAuthors() ).clear();
228             }
229         }
230         if ( this.getDependencies() instanceof RuntimeModelObject )
231         {
232             if ( gc )
233             {
234                 ( (RuntimeModelObject) this.getDependencies() ).gc();
235             }
236             if ( clear )
237             {
238                 ( (RuntimeModelObject) this.getDependencies() ).clear();
239             }
240         }
241         if ( this.getDocumentation() instanceof RuntimeModelObject )
242         {
243             if ( gc )
244             {
245                 ( (RuntimeModelObject) this.getDocumentation() ).gc();
246             }
247             if ( clear )
248             {
249                 ( (RuntimeModelObject) this.getDocumentation() ).clear();
250             }
251         }
252         if ( this.getImplementations() instanceof RuntimeModelObject )
253         {
254             if ( gc )
255             {
256                 ( (RuntimeModelObject) this.getImplementations() ).gc();
257             }
258             if ( clear )
259             {
260                 ( (RuntimeModelObject) this.getImplementations() ).clear();
261             }
262         }
263         if ( this.getMessages() instanceof RuntimeModelObject )
264         {
265             if ( gc )
266             {
267                 ( (RuntimeModelObject) this.getMessages() ).gc();
268             }
269             if ( clear )
270             {
271                 ( (RuntimeModelObject) this.getMessages() ).clear();
272             }
273         }
274         if ( this.getProperties() instanceof RuntimeModelObject )
275         {
276             if ( gc )
277             {
278                 ( (RuntimeModelObject) this.getProperties() ).gc();
279             }
280             if ( clear )
281             {
282                 ( (RuntimeModelObject) this.getProperties() ).clear();
283             }
284         }
285         if ( this.getSpecifications() instanceof RuntimeModelObject )
286         {
287             if ( gc )
288             {
289                 ( (RuntimeModelObject) this.getSpecifications() ).gc();
290             }
291             if ( clear )
292             {
293                 ( (RuntimeModelObject) this.getSpecifications() ).clear();
294             }
295         }
296     }
297 
298     // SECTION-END
299     // SECTION-START[Constructors]
300     // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
301     /** Creates a new {@code RuntimeImplementation} instance. */
302     @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" )
303     public RuntimeImplementation()
304     {
305         // SECTION-START[Default Constructor]
306         super();
307         // SECTION-END
308     }
309     // </editor-fold>
310     // SECTION-END
311     // SECTION-START[Dependencies]
312     // SECTION-END
313     // SECTION-START[Properties]
314     // SECTION-END
315     // SECTION-START[Messages]
316     // SECTION-END
317 }