RuntimeTexts.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: RuntimeTexts.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.util.Locale;
  38. import java.util.Map;
  39. import javax.xml.bind.annotation.XmlTransient;
  40. import org.jomc.model.Text;
  41. import org.jomc.model.Texts;
  42. import static org.jomc.ri.model.RuntimeModelObjects.createMap;

  43. // SECTION-START[Documentation]
  44. // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
  45. /**
  46.  * Runtime {@code Texts}.
  47.  *
  48.  * <dl>
  49.  *   <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeTexts</dd>
  50.  *   <dt><b>Name:</b></dt><dd>JOMC ⁑ RI ⁑ RuntimeTexts</dd>
  51.  *   <dt><b>Specifications:</b></dt>
  52.  *     <dd>org.jomc.ri.model.RuntimeModelObject @ 1.2</dd>
  53.  *   <dt><b>Abstract:</b></dt><dd>No</dd>
  54.  *   <dt><b>Final:</b></dt><dd>No</dd>
  55.  *   <dt><b>Stateless:</b></dt><dd>No</dd>
  56.  * </dl>
  57.  *
  58.  * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 1.2
  59.  * @version 1.2
  60.  */
  61. // </editor-fold>
  62. // SECTION-END
  63. // SECTION-START[Annotations]
  64. // <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
  65. @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.9", comments = "See http://www.jomc.org/jomc/1.9/jomc-tools-1.9" )
  66. // </editor-fold>
  67. // SECTION-END
  68. public class RuntimeTexts extends Texts implements RuntimeModelObject
  69. {
  70.     // SECTION-START[RuntimeTexts]

  71.     /**
  72.      * Cache map.
  73.      */
  74.     @XmlTransient
  75.     private transient final Map<String, Text> textsByLanguageCache = createMap();

  76.     /**
  77.      * Cache map.
  78.      */
  79.     @XmlTransient
  80.     private transient final Map<Locale, Text> textsByLocaleCache = createMap();

  81.     /**
  82.      * Creates a new {@code RuntimeTexts} instance by deeply copying a given {@code Texts} instance.
  83.      *
  84.      * @param texts The instance to copy.
  85.      *
  86.      * @throws NullPointerException if {@code texts} is {@code null}.
  87.      */
  88.     public RuntimeTexts( final Texts texts )
  89.     {
  90.         super( texts );
  91.         this.copyTexts();
  92.     }

  93.     /**
  94.      * Gets a text for a given language from the list of texts.
  95.      * <p>
  96.      * This method queries an internal cache for a result object to return for the given argument values. If no
  97.      * cached result object is available, this method queries the super-class for a result object to return and caches
  98.      * the outcome of that query for use on successive calls.
  99.      * </p>
  100.      * <p>
  101.      * <b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
  102.      * state of the instance, should the state of the instance change.
  103.      * </p>
  104.      *
  105.      * @param language The language of the text to return.
  106.      *
  107.      * @return The first matching text or the default text, if no such text is found.
  108.      *
  109.      * @throws NullPointerException if {@code language} is {@code null}.
  110.      *
  111.      * @see #getText()
  112.      * @see #getDefaultLanguage()
  113.      * @see Text#getLanguage()
  114.      * @see #clear()
  115.      */
  116.     @Override
  117.     public Text getText( final String language )
  118.     {
  119.         if ( language == null )
  120.         {
  121.             throw new NullPointerException( "language" );
  122.         }

  123.         synchronized ( this.textsByLanguageCache )
  124.         {
  125.             Text t = this.textsByLanguageCache.get( language );

  126.             if ( t == null && !this.textsByLanguageCache.containsKey( language ) )
  127.             {
  128.                 t = super.getText( language );
  129.                 this.textsByLanguageCache.put( language, t );
  130.             }

  131.             return t;
  132.         }
  133.     }

  134.     /**
  135.      * Gets a text for a given language from the list of texts.
  136.      * <p>
  137.      * This method queries an internal cache for a result object to return for the given argument values. If no
  138.      * cached result object is available, this method queries the super-class for a result object to return and caches
  139.      * the outcome of that query for use on successive calls.
  140.      * </p>
  141.      * <p>
  142.      * <b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
  143.      * state of the instance, should the state of the instance change.
  144.      * </p>
  145.      *
  146.      * @param locale The locale of the text to return.
  147.      *
  148.      * @return The first matching text or the default text, if no such text is found.
  149.      *
  150.      * @throws NullPointerException if {@code locale} is {@code null}.
  151.      *
  152.      * @see #getText()
  153.      * @see #getDefaultLanguage()
  154.      * @see Text#getLanguage()
  155.      * @see #clear()
  156.      *
  157.      * @since 1.4
  158.      */
  159.     @Override
  160.     public Text getText( final Locale locale )
  161.     {
  162.         if ( locale == null )
  163.         {
  164.             throw new NullPointerException( "locale" );
  165.         }

  166.         synchronized ( this.textsByLocaleCache )
  167.         {
  168.             Text t = this.textsByLocaleCache.get( locale );

  169.             if ( t == null && !this.textsByLocaleCache.containsKey( locale ) )
  170.             {
  171.                 t = super.getText( locale );
  172.                 this.textsByLocaleCache.put( locale, t );
  173.             }

  174.             return t;
  175.         }
  176.     }

  177.     private void copyTexts()
  178.     {
  179.         for ( int i = 0, s0 = this.getText().size(); i < s0; i++ )
  180.         {
  181.             final Text t = this.getText().get( i );
  182.             this.getText().set( i, RuntimeModelObjects.getInstance().copyOf( t ) );
  183.         }
  184.     }

  185.     // SECTION-END
  186.     // SECTION-START[RuntimeModelObject]
  187.     public void gc()
  188.     {
  189.         this.gcOrClear( true, false );
  190.     }

  191.     public void clear()
  192.     {
  193.         synchronized ( this.textsByLanguageCache )
  194.         {
  195.             this.textsByLanguageCache.clear();
  196.         }
  197.         synchronized ( this.textsByLocaleCache )
  198.         {
  199.             this.textsByLocaleCache.clear();
  200.         }

  201.         this.gcOrClear( false, true );
  202.     }

  203.     private void gcOrClear( final boolean gc, final boolean clear )
  204.     {
  205.         this.gcOrClearTexts( gc, clear );
  206.     }

  207.     private void gcOrClearTexts( final boolean gc, final boolean clear )
  208.     {
  209.         for ( int i = 0, s0 = this.getText().size(); i < s0; i++ )
  210.         {
  211.             final Text t = this.getText().get( i );
  212.             if ( t instanceof RuntimeModelObject )
  213.             {
  214.                 if ( gc )
  215.                 {
  216.                     ( (RuntimeModelObject) t ).gc();
  217.                 }
  218.                 if ( clear )
  219.                 {
  220.                     ( (RuntimeModelObject) t ).clear();
  221.                 }
  222.             }
  223.         }
  224.     }

  225.     // SECTION-END
  226.     // SECTION-START[Constructors]
  227.     // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
  228.     /** Creates a new {@code RuntimeTexts} instance. */
  229.     @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.9", comments = "See http://www.jomc.org/jomc/1.9/jomc-tools-1.9" )
  230.     public RuntimeTexts()
  231.     {
  232.         // SECTION-START[Default Constructor]
  233.         super();
  234.         // SECTION-END
  235.     }
  236.     // </editor-fold>
  237.     // SECTION-END
  238.     // SECTION-START[Dependencies]
  239.     // SECTION-END
  240.     // SECTION-START[Properties]
  241.     // SECTION-END
  242.     // SECTION-START[Messages]
  243.     // SECTION-END

  244. }