KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > i18n > rebind > util > ResourceFactory


1 /*
2  * Copyright 2006 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.rebind.util;
17
18 import com.google.gwt.core.ext.typeinfo.JClassType;
19
20 import java.io.InputStream JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Locale JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.MissingResourceException JavaDoc;
27 import java.util.Set JavaDoc;
28
29 /**
30  * Creates resources.
31  */

32 public abstract class ResourceFactory {
33   static class SimplePathTree extends AbstractPathTree {
34     String JavaDoc path;
35
36     SimplePathTree(String JavaDoc path) {
37       this.path = path;
38     }
39
40     public AbstractPathTree getChild(int i) {
41       throw new UnsupportedOperationException JavaDoc(
42           "Simple paths have no children, therefore cannot get child: " + i);
43     }
44
45     public String JavaDoc getPath() {
46       return path;
47     }
48
49     public int numChildren() {
50       return 0;
51     }
52   }
53
54   private abstract static class AbstractPathTree {
55     abstract AbstractPathTree getChild(int i);
56
57     abstract String JavaDoc getPath();
58
59     abstract int numChildren();
60   }
61
62   private static class ClassPathTree extends AbstractPathTree {
63     Class JavaDoc javaInterface;
64
65     ClassPathTree(Class JavaDoc javaInterface) {
66       this.javaInterface = javaInterface;
67     }
68
69     AbstractPathTree getChild(int i) {
70       // we expect to do this at most once, so no caching is used.
71
return new ClassPathTree(javaInterface.getInterfaces()[i]);
72     }
73
74     String JavaDoc getPath() {
75       return javaInterface.getName();
76     }
77
78     int numChildren() {
79       return javaInterface.getInterfaces().length;
80     }
81   }
82
83   private static class JClassTypePathTree extends AbstractPathTree {
84     JClassType javaInterface;
85
86     JClassTypePathTree(JClassType javaInterface) {
87       this.javaInterface = javaInterface;
88     }
89
90     AbstractPathTree getChild(int i) {
91       // we expect to do this at most once, so no caching is used.
92
return new JClassTypePathTree(javaInterface.getImplementedInterfaces()[i]);
93     }
94
95     /**
96      * Path is equivalent to javaInterface.getQualifiedName() except for inner
97      * classes.
98      *
99      * @see com.google.gwt.i18n.rebind.util.ResourceFactory.AbstractPathTree#getPath()
100      */

101     String JavaDoc getPath() {
102       String JavaDoc name = getResourceName(javaInterface);
103       String JavaDoc packageName = javaInterface.getPackage().getName();
104       return packageName + "." + name;
105     }
106
107     int numChildren() {
108       return javaInterface.getImplementedInterfaces().length;
109     }
110   }
111
112   public static final AbstractResource NOT_FOUND = new AbstractResource() {
113
114     void addToKeySet(Set JavaDoc s) {
115       throw new IllegalStateException JavaDoc("Not found resource");
116     }
117
118     Object JavaDoc handleGetObject(String JavaDoc key) {
119       throw new IllegalStateException JavaDoc("Not found resource");
120     }
121   };
122
123   private static Map JavaDoc cache = new HashMap JavaDoc();
124
125   private static List JavaDoc loaders = new ArrayList JavaDoc();
126   static {
127     loaders.add(new LocalizedPropertiesResource.Factory());
128   }
129
130   /**
131    * Clears the resource cache.
132    */

133   public static void clearCache() {
134     cache.clear();
135   }
136
137   /**
138    * Gets the resource associated with the given interface.
139    *
140    * @param javaInterface interface
141    * @param locale locale
142    * @return the resource
143    */

144   public static AbstractResource getBundle(Class JavaDoc javaInterface, Locale JavaDoc locale) {
145     if (javaInterface.isInterface() == false) {
146       throw new IllegalArgumentException JavaDoc(javaInterface
147           + " should be an interface.");
148     }
149     ClassPathTree path = new ClassPathTree(javaInterface);
150     return getBundleAux(path, locale, true);
151   }
152
153   /**
154    * Gets the resource associated with the given interface.
155    *
156    * @param javaInterface interface
157    * @param locale locale
158    * @return the resource
159    */

160   public static AbstractResource getBundle(JClassType javaInterface,
161       Locale JavaDoc locale) {
162     return getBundleAux(new JClassTypePathTree(javaInterface), locale, true);
163   }
164
165   /**
166    * Gets the resource associated with the given path.
167    *
168    * @param path the path
169    * @param locale locale
170    * @return the resource
171    */

172   public static AbstractResource getBundle(String JavaDoc path, Locale JavaDoc locale) {
173     return getBundleAux(new SimplePathTree(path), locale, true);
174   }
175
176   public static String JavaDoc getResourceName(JClassType targetClass) {
177     String JavaDoc name = targetClass.getName();
178     if (targetClass.isMemberType()) {
179       name = name.replace('.', '$');
180     }
181     return name;
182   }
183
184   private static List JavaDoc findAlternativeParents(
185       ResourceFactory.AbstractPathTree tree, Locale JavaDoc locale) {
186     List JavaDoc altParents = null;
187     if (tree != null) {
188       altParents = new ArrayList JavaDoc();
189       for (int i = 0; i < tree.numChildren(); i++) {
190         ResourceFactory.AbstractPathTree child = tree.getChild(i);
191         AbstractResource altParent = getBundleAux(child, locale, false);
192         if (altParent != null) {
193           altParents.add(altParent);
194         }
195       }
196     }
197     return altParents;
198   }
199
200   private static AbstractResource findPrimaryParent(
201       ResourceFactory.AbstractPathTree tree, Locale JavaDoc locale) {
202     // Create bundle
203
AbstractResource parent = null;
204
205     // If we are not in the default case, calculate parent
206
if (locale != null) {
207       if (!("".equals(locale.getVariant()))) {
208         // parents, by default, share the list of alternativePaths;
209
parent = getBundleAux(tree, new Locale JavaDoc(locale.getLanguage(),
210             locale.getCountry()), false);
211       } else if (!"".equals(locale.getCountry())) {
212         parent = getBundleAux(tree, new Locale JavaDoc(locale.getLanguage()), false);
213       }
214
215       // If either no country was defined or no bundle was found, use null
216
// locale instead.
217
if (parent == null) {
218         parent = getBundleAux(tree, null, false);
219       }
220     }
221     return parent;
222   }
223
224   private static AbstractResource getBundleAux(
225       ResourceFactory.AbstractPathTree tree, Locale JavaDoc locale, boolean required) {
226     String JavaDoc targetPath = tree.getPath();
227     ClassLoader JavaDoc loader = AbstractResource.class.getClassLoader();
228     // Calculate baseName
229
String JavaDoc localizedPath = targetPath;
230     if (locale != null) {
231       localizedPath = targetPath + "_" + locale;
232     }
233     AbstractResource result = (AbstractResource) cache.get(localizedPath);
234     if (result != null) {
235       if (result == NOT_FOUND) {
236         return null;
237       } else {
238         return result;
239       }
240     }
241     String JavaDoc partualPath = localizedPath.replace('.', '/');
242     AbstractResource parent = findPrimaryParent(tree, locale);
243     List JavaDoc altParents = findAlternativeParents(tree, locale);
244
245     AbstractResource found = null;
246     for (int i = 0; i < loaders.size(); i++) {
247       ResourceFactory element = (ResourceFactory) loaders.get(i);
248       String JavaDoc path = partualPath + "." + element.getExt();
249       InputStream JavaDoc m = loader.getResourceAsStream(path);
250       if (m != null) {
251         found = element.load(m);
252         found.setPath(partualPath);
253         found.setPrimaryParent(parent);
254         found.setLocale(locale);
255         for (int j = 0; j < altParents.size(); j++) {
256           AbstractResource altParent = (AbstractResource) altParents.get(j);
257           found.addAlternativeParent(altParent);
258         }
259         found.checkKeys();
260         break;
261       }
262     }
263     if (found == null) {
264       if (parent != null) {
265         found = parent;
266       } else {
267         found = NOT_FOUND;
268       }
269       found = parent;
270     }
271
272     cache.put(localizedPath, found);
273     if (found == null && required) {
274       throw new MissingResourceException JavaDoc(
275           "Could not find any resource associated with " + tree.getPath(),
276           null, null);
277     }
278     return found;
279   }
280
281   abstract String JavaDoc getExt();
282
283   abstract AbstractResource load(InputStream JavaDoc m);
284 }
285
Popular Tags