RuntimeSpecification.java

  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: RuntimeSpecification.java 5061 2015-05-31 13:20:40Z schulte $
  32.  *
  33.  */
  34. // </editor-fold>
  35. // SECTION-END
  36. package org.jomc.ri.model;

  37. import java.lang.ref.Reference;
  38. import java.lang.ref.WeakReference;
  39. import java.util.Map;
  40. import javax.xml.bind.annotation.XmlTransient;
  41. import org.jomc.model.JavaTypeName;
  42. import org.jomc.model.ModelObjectException;
  43. import org.jomc.model.Specification;
  44. import static org.jomc.ri.model.RuntimeModelObjects.BOOTSTRAP_CLASSLOADER_KEY;
  45. import static org.jomc.ri.model.RuntimeModelObjects.classesByClassLoaderAndNameCache;
  46. import static org.jomc.ri.model.RuntimeModelObjects.createMap;

  47. // SECTION-START[Documentation]
  48. // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
  49. /**
  50.  * Runtime {@code Specification}.
  51.  *
  52.  * <dl>
  53.  *   <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeSpecification</dd>
  54.  *   <dt><b>Name:</b></dt><dd>JOMC ⁑ RI ⁑ RuntimeSpecification</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:cs@schulte.it">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.9", comments = "See http://www.jomc.org/jomc/1.9/jomc-tools-1.9" )
  70. // </editor-fold>
  71. // SECTION-END
  72. public class RuntimeSpecification extends Specification implements RuntimeModelObject
  73. {
  74.     // SECTION-START[RuntimeSpecification]

  75.     /**
  76.      * Java type name.
  77.      */
  78.     @XmlTransient
  79.     private volatile JavaTypeName javaTypeName;

  80.     /**
  81.      * Creates a new {@code RuntimeSpecification} instance by deeply copying a given {@code Specification} instance.
  82.      *
  83.      * @param specification The instance to copy.
  84.      *
  85.      * @throws NullPointerException if {@code specification} is {@code null}.
  86.      */
  87.     public RuntimeSpecification( final Specification specification )
  88.     {
  89.         super( specification );

  90.         if ( this.getAuthors() != null )
  91.         {
  92.             this.setAuthors( RuntimeModelObjects.getInstance().copyOf( this.getAuthors() ) );
  93.         }
  94.         if ( this.getDocumentation() != null )
  95.         {
  96.             this.setDocumentation( RuntimeModelObjects.getInstance().copyOf( this.getDocumentation() ) );
  97.         }
  98.         if ( this.getProperties() != null )
  99.         {
  100.             this.setProperties( RuntimeModelObjects.getInstance().copyOf( this.getProperties() ) );
  101.         }
  102.     }

  103.     /**
  104.      * Gets the Java class of the specification for a given class loader.
  105.      * <p>
  106.      * This method queries an internal cache for a result object to return for the given argument values. If no
  107.      * cached result object is available, this method queries the super-class for a result object to return and caches
  108.      * the outcome of that query for use on successive calls.
  109.      * </p>
  110.      * <p>
  111.      * <b>Note:</b><br/>Method {@code RuntimeModelObjects.clear()} must be used to synchronize the state of the
  112.      * internal cache with the state of the class loader, should the state of the class loader change.
  113.      * </p>
  114.      *
  115.      * @param classLoader The class loader to get the Java class from or {@code null}, to get the Java class from the
  116.      * platform's bootstrap class loader.
  117.      *
  118.      * @return The Java class of the specification or {@code null}, if the specification does not declare a class.
  119.      *
  120.      * @throws ClassNotFoundException if the Java class is not found.
  121.      * @throws ModelObjectException if parsing the name of the referenced type fails.
  122.      *
  123.      * @see #getClazz()
  124.      * @see RuntimeModelObjects#clear()
  125.      */
  126.     @Override
  127.     public Class<?> getJavaClass( final ClassLoader classLoader )
  128.         throws ModelObjectException, ClassNotFoundException
  129.     {
  130.         Class<?> javaClass = null;

  131.         if ( this.getJavaTypeName() != null )
  132.         {
  133.             synchronized ( classesByClassLoaderAndNameCache )
  134.             {
  135.                 ClassLoader classLoaderKey = classLoader;
  136.                 if ( classLoaderKey == null )
  137.                 {
  138.                     classLoaderKey = BOOTSTRAP_CLASSLOADER_KEY;
  139.                 }

  140.                 Map<String, Reference<Class<?>>> map = classesByClassLoaderAndNameCache.get( classLoaderKey );

  141.                 if ( map == null )
  142.                 {
  143.                     map = createMap();
  144.                     classesByClassLoaderAndNameCache.put( classLoaderKey, map );
  145.                 }

  146.                 final Reference<Class<?>> reference = map.get( this.getJavaTypeName().getClassName() );

  147.                 if ( reference != null )
  148.                 {
  149.                     javaClass = reference.get();
  150.                 }

  151.                 if ( javaClass == null )
  152.                 {
  153.                     javaClass = super.getJavaClass( classLoader );
  154.                     map.put( this.getJavaTypeName().getClassName(), new WeakReference<Class<?>>( javaClass ) );
  155.                 }
  156.             }
  157.         }

  158.         return javaClass;
  159.     }

  160.     /**
  161.      * Gets the Java type name of the type referenced by the specification.
  162.      * <p>
  163.      * This method queries an internal cache for a result object to return. If no cached result object is available,
  164.      * this method queries the super-class for a result object to return and caches the outcome of that query for use on
  165.      * successive calls.
  166.      * </p>
  167.      * <p>
  168.      * <b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
  169.      * state of the instance, should the state of the instance change.
  170.      * </p>
  171.      *
  172.      * @return The Java type name of the type referenced by the specification or {@code null}, if the specification does
  173.      * not reference a type.
  174.      *
  175.      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails.
  176.      *
  177.      * @since 1.4
  178.      *
  179.      * @see #getJavaTypeName()
  180.      * @see #clear()
  181.      */
  182.     @Override
  183.     public JavaTypeName getJavaTypeName() throws ModelObjectException
  184.     {
  185.         if ( this.javaTypeName == null )
  186.         {
  187.             this.javaTypeName = super.getJavaTypeName();
  188.         }

  189.         return this.javaTypeName;
  190.     }

  191.     // SECTION-END
  192.     // SECTION-START[RuntimeModelObject]
  193.     public void gc()
  194.     {
  195.         this.gcOrClear( true, false );
  196.     }

  197.     public void clear()
  198.     {
  199.         this.javaTypeName = null;
  200.         this.gcOrClear( false, true );
  201.     }

  202.     private void gcOrClear( final boolean gc, final boolean clear )
  203.     {
  204.         if ( this.getAuthors() instanceof RuntimeModelObject )
  205.         {
  206.             if ( gc )
  207.             {
  208.                 ( (RuntimeModelObject) this.getAuthors() ).gc();
  209.             }
  210.             if ( clear )
  211.             {
  212.                 ( (RuntimeModelObject) this.getAuthors() ).clear();
  213.             }
  214.         }
  215.         if ( this.getDocumentation() instanceof RuntimeModelObject )
  216.         {
  217.             if ( gc )
  218.             {
  219.                 ( (RuntimeModelObject) this.getDocumentation() ).gc();
  220.             }
  221.             if ( clear )
  222.             {
  223.                 ( (RuntimeModelObject) this.getDocumentation() ).clear();
  224.             }
  225.         }
  226.         if ( this.getProperties() instanceof RuntimeModelObject )
  227.         {
  228.             if ( gc )
  229.             {
  230.                 ( (RuntimeModelObject) this.getProperties() ).gc();
  231.             }
  232.             if ( clear )
  233.             {
  234.                 ( (RuntimeModelObject) this.getProperties() ).clear();
  235.             }
  236.         }
  237.     }

  238.     // SECTION-END
  239.     // SECTION-START[Constructors]
  240.     // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
  241.     /** Creates a new {@code RuntimeSpecification} instance. */
  242.     @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.9", comments = "See http://www.jomc.org/jomc/1.9/jomc-tools-1.9" )
  243.     public RuntimeSpecification()
  244.     {
  245.         // SECTION-START[Default Constructor]
  246.         super();
  247.         // SECTION-END
  248.     }
  249.     // </editor-fold>
  250.     // SECTION-END
  251.     // SECTION-START[Dependencies]
  252.     // SECTION-END
  253.     // SECTION-START[Properties]
  254.     // SECTION-END
  255.     // SECTION-START[Messages]
  256.     // SECTION-END

  257. }