001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.i18n.rebind;
017:
018: import com.google.gwt.core.ext.BadPropertyValueException;
019: import com.google.gwt.core.ext.Generator;
020: import com.google.gwt.core.ext.GeneratorContext;
021: import com.google.gwt.core.ext.PropertyOracle;
022: import com.google.gwt.core.ext.TreeLogger;
023: import com.google.gwt.core.ext.UnableToCompleteException;
024: import com.google.gwt.core.ext.typeinfo.JClassType;
025: import com.google.gwt.core.ext.typeinfo.NotFoundException;
026: import com.google.gwt.core.ext.typeinfo.TypeOracle;
027: import com.google.gwt.i18n.client.Constants;
028: import com.google.gwt.i18n.client.ConstantsWithLookup;
029: import com.google.gwt.i18n.client.Messages;
030: import com.google.gwt.i18n.rebind.util.ResourceFactory;
031:
032: /**
033: * Generator used to bind classes extending the <code>Localizable</code> and
034: * <code>Constants</code> interfaces.
035: */
036: public class LocalizableGenerator extends Generator {
037: /**
038: * GWT method to override default use of method name as resource key.
039: */
040: public static final String GWT_KEY = "gwt.key";
041:
042: static final String CONSTANTS_NAME = Constants.class.getName();
043:
044: static final String CONSTANTS_WITH_LOOKUP_NAME = ConstantsWithLookup.class
045: .getName();
046:
047: static final String MESSAGES_NAME = Messages.class.getName();
048: private static long lastReloadCount = -1;
049: /**
050: * The token representing the locale property controlling Localization.
051: */
052: private static final String PROP_LOCALE = "locale";
053:
054: private LocalizableLinkageCreator linkageCreator = new LocalizableLinkageCreator();
055:
056: /**
057: * Generate an implementation for the given type.
058: *
059: * @param logger error logger
060: * @param context generator context
061: * @param typeName target type name
062: * @return generated class name
063: * @throws UnableToCompleteException
064: */
065: @Override
066: public final String generate(TreeLogger logger,
067: GeneratorContext context, String typeName)
068: throws UnableToCompleteException {
069: // Clear cache if reset was done.
070: TypeOracle typeOracle = context.getTypeOracle();
071: if (lastReloadCount != typeOracle.getReloadCount()) {
072: ResourceFactory.clearCache();
073: lastReloadCount = typeOracle.getReloadCount();
074: }
075:
076: // Get the current locale and interface type.
077: PropertyOracle propertyOracle = context.getPropertyOracle();
078: String locale;
079: try {
080: // Look at the code for the "locale" property provider in
081: // I18N.gwt.xml to see the possible values for the locale
082: // property. Basically,
083: //
084: // 1) If the locale is specified by the user using a request parameter
085: // or a meta tag, AND
086: // 2) The locale matches or is a parent of one of the locales
087: // exposed in the application's gwt.xml file, THEN
088: //
089: // the value returned by getPropertyValue() will be:
090: //
091: // a) the locale specified by the user, OR
092: // b) the parent locale, if an exact match between the user-specified
093: // locale and the exposed locales cannot be found
094: //
095: // If the locale is not specified by the user as a request parameter
096: // or via a meta tag, or if the locale is formatted incorrectly,
097: // getPropertyValue() will return "default".
098: locale = propertyOracle.getPropertyValue(logger,
099: PROP_LOCALE);
100: } catch (BadPropertyValueException e) {
101: logger.log(TreeLogger.ERROR,
102: "Could not parse specified locale", e);
103: throw new UnableToCompleteException();
104: }
105:
106: JClassType targetClass;
107: try {
108: targetClass = typeOracle.getType(typeName);
109: } catch (NotFoundException e) {
110: logger.log(TreeLogger.ERROR, "No such type", e);
111: throw new UnableToCompleteException();
112: }
113:
114: // Link current locale and interface type to correct implementation class.
115: String generatedClass = AbstractLocalizableImplCreator
116: .generateConstantOrMessageClass(logger, context,
117: locale, targetClass);
118: if (generatedClass != null) {
119: return generatedClass;
120: }
121: return linkageCreator.linkWithImplClass(logger, targetClass,
122: locale);
123: }
124: }
|