KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > i18n > client > Dictionary


1 /*
2  * Copyright 2007 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */

16 package com.google.gwt.i18n.client;
17
18 import com.google.gwt.core.client.JavaScriptObject;
19
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collection JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.MissingResourceException JavaDoc;
26 import java.util.Set JavaDoc;
27
28 /**
29  * Provides dynamic string lookup of key/value string pairs defined in a
30  * module's host HTML page. Each unique instance of <code>Dictionary</code> is
31  * bound to a named JavaScript object that resides in the global namespace of
32  * the host page's window object. The bound JavaScript object is used directly
33  * as an associative array.
34  *
35  * <p>
36  * For example, suppose you define the following JavaScript object in your host
37  * page:
38  *
39  * {@gwt.include com/google/gwt/examples/i18n/ThemeDictionaryExample.js}
40  *
41  * You can then use a <code>Dictionary</code> to access the key/value pairs
42  * above:
43  *
44  * {@example com.google.gwt.examples.i18n.ThemeDictionaryExample#useThemeDictionary()}
45  * </p>
46  *
47  * <p>
48  * Unlike the family of interfaces that extend
49  * {@link com.google.gwt.i18n.client.Localizable} which support static
50  * internationalization, the <code>Dictionary</code> class is fully dynamic.
51  * As a result, a variety of error conditions (particularly those involving key
52  * mismatches) cannot be caught until runtime. Similarly, the GWT compiler is
53  * unable discard unused dictionary values since the structure cannot be
54  * statically analyzed.
55  * </p>
56  *
57  * <h3>A Caveat Regarding Locale</h3>
58  * The module's host page completely determines the mappings defined for each
59  * dictionary without regard to the <code>locale</code> client property. Thus,
60  * <code>Dictionary</code> is the most flexible of the internationalization
61  * types and may provide the simplest form of integration with existing
62  * localization systems which were not specifically designed to use GWT's
63  * <code>locale</code> client property.
64  *
65  * <p>
66  * See {@link com.google.gwt.i18n.client.Localizable} for background on the
67  * <code>locale</code> client property.
68  * </p>
69  *
70  * <h3>Required Module</h3>
71  * Modules that use this interface should inherit
72  * <code>com.google.gwt.i18n.I18N</code>.
73  *
74  * {@gwt.include com/google/gwt/examples/i18n/InheritsExample.gwt.xml}
75  */

76 public final class Dictionary {
77
78   private static Map JavaDoc cache = new HashMap JavaDoc();
79   private static final int MAX_KEYS_TO_SHOW = 20;
80
81   /**
82    * Returns the <code>Dictionary</code> object associated with the given
83    * name.
84    *
85    * @param name
86    * @return specified dictionary
87    * @throws MissingResourceException
88    */

89   public static Dictionary getDictionary(String JavaDoc name) {
90     Dictionary target = (Dictionary) cache.get(name);
91     if (target == null) {
92       target = new Dictionary(name);
93       cache.put(name, target);
94     }
95     return target;
96   }
97
98   static void resourceErrorBadType(String JavaDoc name) {
99     throw new MissingResourceException JavaDoc("'" + name
100         + "' is not a JavaScript object and cannot be used as a Dictionary",
101         null, name);
102   }
103
104   private JavaScriptObject dict;
105
106   private String JavaDoc label;
107
108   /**
109    * Constructor for <code>Dictionary</code>.
110    *
111    * @param name name of linked JavaScript Object
112    */

113   private Dictionary(String JavaDoc name) {
114     if (name == null || "".equals(name)) {
115       throw new IllegalArgumentException JavaDoc(
116           "Cannot create a Dictionary with a null or empty name");
117     }
118     this.label = "Dictionary " + name;
119     attach(name);
120     if (dict == null) {
121       throw new MissingResourceException JavaDoc(
122           "Cannot find JavaScript object with the name '" + name + "'", name,
123           null);
124     }
125   }
126
127   /**
128    * Get the value associated with the given Dictionary key.
129    *
130    * We have to call Object.hasOwnProperty to verify that the value is
131    * defined on this object, rather than a superclass, since normal Object
132    * properties are also visible on this object.
133    *
134    * @param key to lookup
135    * @return the value
136    * @throws MissingResourceException if the value is not found
137    */

138   public native String JavaDoc get(String JavaDoc key) /*-{
139    var value = this.@com.google.gwt.i18n.client.Dictionary::dict[key];
140    if (value == null || !Object.prototype.hasOwnProperty.call(
141        this.@com.google.gwt.i18n.client.Dictionary::dict, key))
142    {
143      this.@com.google.gwt.i18n.client.Dictionary::resourceError(Ljava/lang/String;)(key);
144    }
145    return String(value);
146    }-*/
;
147
148   /**
149    * The set of keys associated with this dictionary.
150    *
151    * @return the Dictionary set
152    */

153   public Set JavaDoc keySet() {
154     HashSet JavaDoc s = new HashSet JavaDoc();
155     addKeys(s);
156     return s;
157   }
158
159   public String JavaDoc toString() {
160     return label;
161   }
162
163   /**
164    * Collection of values associated with this dictionary.
165    *
166    * @return the values
167    */

168   public Collection JavaDoc values() {
169     ArrayList JavaDoc s = new ArrayList JavaDoc();
170     addValues(s);
171     return s;
172   }
173
174   void resourceError(String JavaDoc key) {
175     Collection JavaDoc s = this.keySet();
176     String JavaDoc error = "Cannot find '" + key + "' in " + this;
177     if (s.size() < MAX_KEYS_TO_SHOW) {
178       error += "\n keys found: " + s;
179     }
180     throw new MissingResourceException JavaDoc(error, this.toString(), key);
181   }
182
183   private native void addKeys(HashSet JavaDoc s) /*-{
184     for (x in this.@com.google.gwt.i18n.client.Dictionary::dict) {
185       s.@java.util.HashSet::add(Ljava/lang/Object;)(x);
186     }
187   }-*/
;
188
189   private native void addValues(ArrayList JavaDoc s) /*-{
190     for (x in this.@com.google.gwt.i18n.client.Dictionary::dict) {
191       var value = this.@com.google.gwt.i18n.client.Dictionary::get(Ljava/lang/String;)(x);
192       s.@java.util.ArrayList::add(Ljava/lang/Object;)(value);
193     }
194   }-*/
;
195
196   private native void attach(String JavaDoc name)/*-{
197     try {
198       if (typeof($wnd[name]) != "object") {
199         @com.google.gwt.i18n.client.Dictionary::resourceErrorBadType(Ljava/lang/String;)(name);
200       }
201       this.@com.google.gwt.i18n.client.Dictionary::dict = $wnd[name];
202     } catch(e) {
203       @com.google.gwt.i18n.client.Dictionary::resourceErrorBadType(Ljava/lang/String;)(name);
204     }
205   }-*/
;
206 }
207
Popular Tags