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: RuntimeTexts.java 4712 2013-01-02 13:56:12Z schulte $
32   *
33   */
34  // </editor-fold>
35  // SECTION-END
36  package org.jomc.ri.model;
37  
38  import java.util.Locale;
39  import java.util.Map;
40  import javax.xml.bind.annotation.XmlTransient;
41  import org.jomc.model.Text;
42  import org.jomc.model.Texts;
43  import static org.jomc.ri.model.RuntimeModelObjects.createMap;
44  
45  // SECTION-START[Documentation]
46  // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
47  /**
48   * Runtime {@code Texts}.
49   *
50   * <dl>
51   *   <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeTexts</dd>
52   *   <dt><b>Name:</b></dt><dd>JOMC ⁑ RI ⁑ RuntimeTexts</dd>
53   *   <dt><b>Specifications:</b></dt>
54   *     <dd>org.jomc.ri.model.RuntimeModelObject @ 1.2</dd>
55   *   <dt><b>Abstract:</b></dt><dd>No</dd>
56   *   <dt><b>Final:</b></dt><dd>No</dd>
57   *   <dt><b>Stateless:</b></dt><dd>No</dd>
58   * </dl>
59   *
60   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 1.2
61   * @version 1.2
62   */
63  // </editor-fold>
64  // SECTION-END
65  // SECTION-START[Annotations]
66  // <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
67  @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.4", comments = "See http://www.jomc.org/jomc/1.4/jomc-tools-1.4" )
68  // </editor-fold>
69  // SECTION-END
70  public class RuntimeTexts extends Texts implements RuntimeModelObject
71  {
72      // SECTION-START[RuntimeTexts]
73  
74      /** Cache map. */
75      @XmlTransient
76      private transient final Map<String, Text> textsByLanguageCache = createMap();
77  
78      /** Cache map. */
79      @XmlTransient
80      private transient final Map<Locale, Text> textsByLocaleCache = createMap();
81  
82      /**
83       * Creates a new {@code RuntimeTexts} instance by deeply copying a given {@code Texts} instance.
84       *
85       * @param texts The instance to copy.
86       *
87       * @throws NullPointerException if {@code texts} is {@code null}.
88       */
89      public RuntimeTexts( final Texts texts )
90      {
91          super( texts );
92          this.copyTexts();
93      }
94  
95      /**
96       * Gets a text for a given language from the list of texts.
97       * <p>This method queries an internal cache for a result object to return for the given argument values. If no
98       * cached result object is available, this method queries the super-class for a result object to return and caches
99       * the outcome of that query for use on successive calls.</p>
100      * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
101      * state of the instance, should the state of the instance change.</p>
102      *
103      * @param language The language of the text to return.
104      *
105      * @return The first matching text or the default text, if no such text is found.
106      *
107      * @throws NullPointerException if {@code language} is {@code null}.
108      *
109      * @see #getText()
110      * @see #getDefaultLanguage()
111      * @see Text#getLanguage()
112      * @see #clear()
113      */
114     @Override
115     public Text getText( final String language )
116     {
117         if ( language == null )
118         {
119             throw new NullPointerException( "language" );
120         }
121 
122         synchronized ( this.textsByLanguageCache )
123         {
124             Text t = this.textsByLanguageCache.get( language );
125 
126             if ( t == null && !this.textsByLanguageCache.containsKey( language ) )
127             {
128                 t = super.getText( language );
129                 this.textsByLanguageCache.put( language, t );
130             }
131 
132             return t;
133         }
134     }
135 
136     /**
137      * Gets a text for a given language from the list of texts.
138      * <p>This method queries an internal cache for a result object to return for the given argument values. If no
139      * cached result object is available, this method queries the super-class for a result object to return and caches
140      * the outcome of that query for use on successive calls.</p>
141      * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the
142      * state of the instance, should the state of the instance change.</p>
143      *
144      * @param locale The locale of the text to return.
145      *
146      * @return The first matching text or the default text, if no such text is found.
147      *
148      * @throws NullPointerException if {@code locale} is {@code null}.
149      *
150      * @see #getText()
151      * @see #getDefaultLanguage()
152      * @see Text#getLanguage()
153      * @see #clear()
154      *
155      * @since 1.4
156      */
157     @Override
158     public Text getText( final Locale locale )
159     {
160         if ( locale == null )
161         {
162             throw new NullPointerException( "locale" );
163         }
164 
165         synchronized ( this.textsByLocaleCache )
166         {
167             Text t = this.textsByLocaleCache.get( locale );
168 
169             if ( t == null && !this.textsByLocaleCache.containsKey( locale ) )
170             {
171                 t = super.getText( locale );
172                 this.textsByLocaleCache.put( locale, t );
173             }
174 
175             return t;
176         }
177     }
178 
179     private void copyTexts()
180     {
181         for ( int i = 0, s0 = this.getText().size(); i < s0; i++ )
182         {
183             final Text t = this.getText().get( i );
184             this.getText().set( i, RuntimeModelObjects.getInstance().copyOf( t ) );
185         }
186     }
187 
188     // SECTION-END
189     // SECTION-START[RuntimeModelObject]
190     public void gc()
191     {
192         this.gcOrClear( true, false );
193     }
194 
195     public void clear()
196     {
197         synchronized ( this.textsByLanguageCache )
198         {
199             this.textsByLanguageCache.clear();
200         }
201         synchronized ( this.textsByLocaleCache )
202         {
203             this.textsByLocaleCache.clear();
204         }
205 
206         this.gcOrClear( false, true );
207     }
208 
209     private void gcOrClear( final boolean gc, final boolean clear )
210     {
211         this.gcOrClearTexts( gc, clear );
212     }
213 
214     private void gcOrClearTexts( final boolean gc, final boolean clear )
215     {
216         for ( int i = 0, s0 = this.getText().size(); i < s0; i++ )
217         {
218             final Text t = this.getText().get( i );
219             if ( t instanceof RuntimeModelObject )
220             {
221                 if ( gc )
222                 {
223                     ( (RuntimeModelObject) t ).gc();
224                 }
225                 if ( clear )
226                 {
227                     ( (RuntimeModelObject) t ).clear();
228                 }
229             }
230         }
231     }
232     // SECTION-END
233     // SECTION-START[Constructors]
234     // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
235     /** Creates a new {@code RuntimeTexts} instance. */
236     @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.4", comments = "See http://www.jomc.org/jomc/1.4/jomc-tools-1.4" )
237     public RuntimeTexts()
238     {
239         // SECTION-START[Default Constructor]
240         super();
241         // SECTION-END
242     }
243     // </editor-fold>
244     // SECTION-END
245     // SECTION-START[Dependencies]
246     // SECTION-END
247     // SECTION-START[Properties]
248     // SECTION-END
249     // SECTION-START[Messages]
250     // SECTION-END
251 }