KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > i18n > rebind > AbstractLocalizableImplCreator


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.rebind;
17
18 import com.google.gwt.core.ext.GeneratorContext;
19 import com.google.gwt.core.ext.TreeLogger;
20 import com.google.gwt.core.ext.UnableToCompleteException;
21 import com.google.gwt.core.ext.typeinfo.JClassType;
22 import com.google.gwt.core.ext.typeinfo.JMethod;
23 import com.google.gwt.core.ext.typeinfo.NotFoundException;
24 import com.google.gwt.core.ext.typeinfo.TypeOracle;
25 import com.google.gwt.i18n.rebind.util.AbstractResource;
26 import com.google.gwt.i18n.rebind.util.ResourceFactory;
27 import com.google.gwt.user.rebind.AbstractGeneratorClassCreator;
28 import com.google.gwt.user.rebind.AbstractMethodCreator;
29 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
30 import com.google.gwt.user.rebind.SourceWriter;
31
32 import java.io.PrintWriter JavaDoc;
33 import java.util.Locale JavaDoc;
34 import java.util.MissingResourceException JavaDoc;
35 import java.util.Set JavaDoc;
36
37 /**
38  * Represents generic functionality needed for <code>Constants</code> and
39  * <code>Messages</code> classes.
40  */

41 abstract class AbstractLocalizableImplCreator extends
42     AbstractGeneratorClassCreator {
43
44   static String JavaDoc generateConstantOrMessageClass(TreeLogger logger,
45       GeneratorContext context, Locale JavaDoc locale, JClassType targetClass)
46       throws UnableToCompleteException {
47     TypeOracle oracle = context.getTypeOracle();
48     JClassType constantsClass;
49     JClassType messagesClass;
50     JClassType constantsWithLookupClass;
51     try {
52       constantsClass = oracle.getType(LocalizableGenerator.CONSTANTS_NAME);
53       constantsWithLookupClass = oracle.getType(LocalizableGenerator.CONSTANTS_WITH_LOOKUP_NAME);
54       messagesClass = oracle.getType(LocalizableGenerator.MESSAGES_NAME);
55     } catch (NotFoundException e) {
56       // Should never happen in practice.
57
throw error(logger, e);
58     }
59
60     String JavaDoc name = targetClass.getName();
61     String JavaDoc packageName = targetClass.getPackage().getName();
62
63     // Make sure the interface being rebound extends either Constants or
64
// Messages.
65
boolean assignableToConstants = constantsClass.isAssignableFrom(targetClass);
66     boolean assignableToMessages = messagesClass.isAssignableFrom(targetClass);
67     if (!assignableToConstants && !assignableToMessages) {
68       // Let the implementation generator handle this interface.
69
return null;
70     }
71
72     // Make sure that they don't try to extend both Messages and Constants.
73
if (assignableToConstants && assignableToMessages) {
74       throw error(logger, name + " cannot extend both Constants and Messages");
75     }
76
77     // Make sure that the type being rebound is in fact an interface.
78
if (targetClass.isInterface() == null) {
79       throw error(logger, name + " must be an interface");
80     }
81
82     AbstractResource resource;
83     try {
84       resource = ResourceFactory.getBundle(targetClass, locale);
85     } catch (MissingResourceException JavaDoc e) {
86       throw error(
87           logger,
88           "Localization failed; there must be at least one properties file accessible through the classpath in package '"
89               + packageName
90               + "' whose base name is '"
91               + ResourceFactory.getResourceName(targetClass) + "'");
92     } catch (IllegalArgumentException JavaDoc e) {
93       // A bad key can generate an illegal argument exception.
94
throw error(logger, e.getMessage());
95     }
96
97     // generated implementations for interface X will be named X_, X_en,
98
// X_en_CA, etc.
99
String JavaDoc realLocale = "_";
100     if (resource.getLocale() != null) {
101       realLocale += resource.getLocale();
102     }
103     // Use _ rather than "." in class name, cannot use $
104
String JavaDoc resourceName = targetClass.getName().replace('.', '_');
105     String JavaDoc className = resourceName + realLocale;
106     PrintWriter JavaDoc pw = context.tryCreate(logger, packageName, className);
107     if (pw != null) {
108       ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(
109           packageName, className);
110       factory.addImplementedInterface(targetClass.getQualifiedSourceName());
111       SourceWriter writer = factory.createSourceWriter(context, pw);
112       // Now that we have all the information set up, process the class
113
if (constantsWithLookupClass.isAssignableFrom(targetClass)) {
114         ConstantsWithLookupImplCreator c = new ConstantsWithLookupImplCreator(
115             logger, writer, targetClass, resource, context.getTypeOracle());
116         c.emitClass(logger);
117       } else if (constantsClass.isAssignableFrom(targetClass)) {
118         ConstantsImplCreator c = new ConstantsImplCreator(logger, writer,
119             targetClass, resource, context.getTypeOracle());
120         c.emitClass(logger);
121       } else {
122         MessagesImplCreator messages = new MessagesImplCreator(logger, writer,
123             targetClass, resource, context.getTypeOracle());
124         messages.emitClass(logger);
125       }
126       context.commit(logger, pw);
127     }
128     return packageName + "." + className;
129   }
130
131   /**
132    * The Dictionary/value bindings used to determine message contents.
133    */

134   private AbstractResource messageBindings;
135
136   /**
137    * Constructor for <code>AbstractLocalizableImplCreator</code>.
138    *
139    * @param writer writer
140    * @param targetClass current target
141    * @param messageBindings backing resource
142    */

143   public AbstractLocalizableImplCreator(SourceWriter writer,
144       JClassType targetClass, AbstractResource messageBindings) {
145     super(writer, targetClass);
146     this.messageBindings = messageBindings;
147   }
148
149   /**
150    * Gets the resource associated with this class.
151    *
152    * @return the resource
153    */

154   public AbstractResource getResourceBundle() {
155     return messageBindings;
156   }
157
158   protected String JavaDoc branchMessage() {
159     return "Processing " + this.getTarget();
160   }
161
162   /**
163    * Find the creator associated with the given method, and delegate the
164    * creation of the method body to it.
165    *
166    * @param logger
167    * @param method method to be generated
168    * @throws UnableToCompleteException
169    */

170   protected void delegateToCreator(TreeLogger logger, JMethod method)
171       throws UnableToCompleteException {
172     AbstractMethodCreator methodCreator = getMethodCreator(logger, method);
173     String JavaDoc key = getKey(logger, method);
174     String JavaDoc value;
175     try {
176       value = messageBindings.getString(key);
177     } catch (MissingResourceException JavaDoc e) {
178       String JavaDoc s = "Could not find requested resource key '" + key + "'";
179       TreeLogger child = logger.branch(TreeLogger.ERROR, s, null);
180       Set JavaDoc keys = messageBindings.keySet();
181       if (keys.size() < AbstractResource.REPORT_KEYS_THRESHOLD) {
182         String JavaDoc keyString = "Keys found: " + keys;
183         throw error(child, keyString);
184       } else {
185         throw new UnableToCompleteException();
186       }
187     }
188     String JavaDoc localeString;
189     if (messageBindings.getLocale() == null
190         || messageBindings.getLocale().toString().equals("")) {
191       localeString = "default";
192     } else {
193       localeString = messageBindings.getLocale().toString();
194     }
195     String JavaDoc info = "When locale is '" + localeString + "', property '" + key
196         + "' has the value '" + value + "'";
197     TreeLogger branch = logger.branch(TreeLogger.TRACE, info, null);
198     methodCreator.createMethodFor(branch, method, value);
199   }
200
201   /**
202    * Returns a resource key given a method name.
203    *
204    * @param logger
205    * @param method
206    * @return the key
207    */

208   protected String JavaDoc getKey(TreeLogger logger, JMethod method) {
209     String JavaDoc[][] id = method.getMetaData(LocalizableGenerator.GWT_KEY);
210     if (id.length > 0) {
211       if (id[0].length == 0) {
212         logger.log(TreeLogger.WARN, method
213             + " had a mislabeled gwt.key, using method name as key", null);
214       } else {
215         String JavaDoc tag = id[0][0];
216         return tag;
217       }
218     }
219     return method.getName();
220   }
221 }
222
Popular Tags