blob: 73bb227b105d2f18066a8488f659ebe94098cb15 [file] [log] [blame]
/*
* Copyright 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.i18n.rebind;
import com.google.gwt.core.ext.BadPropertyValueException;
import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.i18n.client.ConstantsWithLookup;
import com.google.gwt.i18n.client.Messages;
import com.google.gwt.i18n.rebind.util.ResourceFactory;
import java.util.Locale;
/**
* Generator used to bind classes extending the <code>Localizable</code> and
* <code>Constants</code> interfaces.
*/
public class LocalizableGenerator extends Generator {
/**
* GWT method to override default use of method name as resource key.
*/
public static final String GWT_KEY = "gwt.key";
static final String CONSTANTS_NAME = Constants.class.getName();
static final String CONSTANTS_WITH_LOOKUP_NAME = ConstantsWithLookup.class.getName();
/**
* Represents default locale.
*/
static final String DEFAULT_TOKEN = "default";
static final String MESSAGES_NAME = Messages.class.getName();
private static long lastReloadCount = -1;
/**
* The token representing the locale property controlling Localization.
*/
private static final String PROP_LOCALE = "locale";
private LocalizableLinkageCreator linkageCreator = new LocalizableLinkageCreator();
/**
* Generate an implementation for the given type.
*
* @param logger error logger
* @param context generator context
* @param typeName target type name
* @return generated class name
* @throws UnableToCompleteException
*/
public final String generate(TreeLogger logger, GeneratorContext context,
String typeName) throws UnableToCompleteException {
// Clear cache if reset was done.
TypeOracle typeOracle = context.getTypeOracle();
if (lastReloadCount != typeOracle.getReloadCount()) {
ResourceFactory.clearCache();
lastReloadCount = typeOracle.getReloadCount();
}
// Get the current locale and interface type.
PropertyOracle propertyOracle = context.getPropertyOracle();
Locale locale;
try {
String localeID = propertyOracle.getPropertyValue(logger, PROP_LOCALE);
if ("default".equals(localeID)) {
locale = null;
} else {
String[] localeChunks = localeID.split("_");
if (localeChunks.length > 0) {
if (!localeChunks[0].equals(localeChunks[0].toLowerCase())) {
logger.log(TreeLogger.ERROR, localeID
+ "'s language code should be lower case", null);
throw new UnableToCompleteException();
}
}
if (localeChunks.length == 1) {
locale = new Locale(localeChunks[0]);
} else if (localeChunks.length == 2) {
// Ignore the localized locale string if present, just use language
// and country.
locale = new Locale(localeChunks[0], localeChunks[1]);
} else if (localeChunks.length == 3) {
locale = new Locale(localeChunks[0], localeChunks[1], localeChunks[2]);
} else {
logger.log(TreeLogger.ERROR, localeID
+ " is not a correctly formatted locale", null);
throw new UnableToCompleteException();
}
}
} catch (BadPropertyValueException e) {
logger.log(TreeLogger.ERROR, "Could not parse specified locale", e);
throw new UnableToCompleteException();
}
JClassType targetClass;
try {
targetClass = typeOracle.getType(typeName);
} catch (NotFoundException e) {
logger.log(TreeLogger.ERROR, "No such type", e);
throw new UnableToCompleteException();
}
// Link current locale and interface type to correct implementation class.
String generatedClass = AbstractLocalizableImplCreator.generateConstantOrMessageClass(
logger, context, locale, targetClass);
if (generatedClass != null) {
return generatedClass;
}
return linkageCreator.linkWithImplClass(logger, targetClass, locale);
}
}