01 
02 /*
03  *  JScripter Standard 1.0 - To Script In Java
04  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
05  *  
06  *  This program is free software: you can redistribute it and/or modify
07  *  it under the terms of the GNU Affero General Public License as published by
08  *  the Free Software Foundation, either version 3 of the License, or
09  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU Affero General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU Affero General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 package js;
21 
22 /**
23  * <p>An <b>opaque</b> class helping to create Java <tt>static final</tt> references 
24  * for Java applets.</p>
25  * <p>This <b>opaque</b> class is especially helpful when used together with the <b>opaque</b> 
26  * class {@link Field} to make Java <tt>static final</tt> references to the fields of 
27  * JavaScript global objects which requires refresh-on-reload and late-evaluation in 
28  * JS applets or other JS Embed Simulations.</p>
29  *
30  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
31  * @see Field
32  * 
33  * @javascript <b>Opaque</b> types can be resolved but no class objects for them can be 
34  * generated into the target codes. Re-compilers must exit with error on the operations of 
35  * accessing that kind of class objects.
36  */
37 
38 public final class Static<T> extends Var<T>
39 {
40     private final Var<T> var;
41     private T t;
42 
43     /**
44      * <p>Creates a refresh-on-reload static reference of an opaque variable.</p>
45      * @param var The opaque variable to create the refresh-on-reload static reference for.
46      * @since 1.0
47      * @javascript Re-compilers must ignore this constructor, that is, replacing it with its 
48      * only argument.
49      */
50     public Static(Var<T> var) {
51         synchronized(Static.class) {
52             statics = new Object[]{this, statics};
53         }
54         this.var = var;
55     }
56 
57     /**
58      * <p>Evaluates the current refresh-on-reload static reference, loading it if it is 
59      * not loaded.</p>
60      * @since 1.0
61      * @javascript Re-compilers must ignore the virtual invocation of this method, that is, 
62      * replacing it with its current instance.
63      */
64     @Override
65     public final T var() {
66         return t != null ? t : (t = var.var());
67     }
68 
69     private static Object[] statics;
70 
71     /**
72      * <p>Clear all of the static references.</p>
73      * <p>This method is <b>internal</b> and only called inside of <b>opaque</b> or 
74      * <b>internal</b> classes or class members.</p>
75      * @since 1.0
76      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
77      */
78     static final synchronized void destroy() {
79         Object[] statics = Static.statics;
80         while (statics != null) {
81             ((Static<?>)statics[0]).t = null;
82             statics = (Object[])statics[1];
83         }
84     }
85 }