/* * Copyright 2008 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.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.JMethod; import com.google.gwt.core.ext.typeinfo.JType; import com.google.gwt.core.ext.typeinfo.NotFoundException; import com.google.gwt.core.ext.typeinfo.TypeOracle; import com.google.gwt.i18n.shared.CustomDateTimeFormat; import com.google.gwt.i18n.shared.CustomDateTimeFormat.Pattern; import com.google.gwt.i18n.shared.DateTimeFormat; import com.google.gwt.i18n.shared.GwtLocale; import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; import com.google.gwt.user.rebind.SourceWriter; import java.io.PrintWriter; /** * Generator used to generate an implementation of a * {@link CustomDateTimeFormat} interface, computing the best matching localized * format patterns at compile time. */ public class CustomDateTimeFormatGenerator extends Generator { /** * 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 */ @SuppressWarnings("deprecation") @Override public final String generate(TreeLogger logger, final GeneratorContext context, String typeName) throws UnableToCompleteException { TypeOracle typeOracle = context.getTypeOracle(); // Get the current locale and interface type. PropertyOracle propertyOracle = context.getPropertyOracle(); LocaleUtils localeUtils = LocaleUtils.getInstance(logger, propertyOracle, context); JClassType targetClass; try { targetClass = typeOracle.getType(typeName); } catch (NotFoundException e) { logger.log(TreeLogger.ERROR, "No such type " + typeName, e); throw new UnableToCompleteException(); } JClassType cdtfClass; try { cdtfClass = typeOracle.getType(CustomDateTimeFormat.class.getName()); } catch (NotFoundException e) { logger.log(TreeLogger.ERROR, "No such type " + CustomDateTimeFormat.class.getName(), e); throw new UnableToCompleteException(); } if (!cdtfClass.isAssignableFrom(targetClass)) { logger.log(TreeLogger.ERROR, typeName + " is not assignable to " + CustomDateTimeFormat.class.getName()); throw new UnableToCompleteException(); } JClassType oldDateTimeFormat; try { oldDateTimeFormat = typeOracle.getType( com.google.gwt.i18n.client.DateTimeFormat.class.getName()); } catch (NotFoundException e) { logger.log(TreeLogger.ERROR, "No client DateTimeFormat type?", e); throw new UnableToCompleteException(); } JClassType dateTimeFormat; try { dateTimeFormat = typeOracle.getType(DateTimeFormat.class.getName()); } catch (NotFoundException e) { logger.log(TreeLogger.ERROR, "No DateTimeFormat type?", e); throw new UnableToCompleteException(); } // TODO(jat): runtime locales support GwtLocale gwtLocale = localeUtils.getCompileLocale(); DateTimePatternGenerator dtpg = new DateTimePatternGenerator(gwtLocale); String packageName = targetClass.getPackage().getName(); String className = targetClass.getName().replace('.', '_') + "_" + gwtLocale.getAsString(); PrintWriter pw = context.tryCreate(logger, packageName, className); if (pw != null) { ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory( packageName, className); factory.addImplementedInterface(targetClass.getQualifiedSourceName()); factory.addImport("com.google.gwt.i18n.client.DateTimeFormat"); SourceWriter writer = factory.createSourceWriter(context, pw); writer.indent(); for (JMethod method : targetClass.getMethods()) { JType returnType = method.getReturnType(); if (returnType != dateTimeFormat && returnType != oldDateTimeFormat) { logger.log(TreeLogger.ERROR, typeName + "." + method.getName() + " must return DateTimeFormat"); throw new UnableToCompleteException(); } String pattern; Pattern annotation = method.getAnnotation(Pattern.class); if (annotation == null) { com.google.gwt.i18n.client.CustomDateTimeFormat.Pattern oldAnnotation = method.getAnnotation(com.google.gwt.i18n.client.CustomDateTimeFormat.Pattern.class); if (oldAnnotation == null) { logger.log(TreeLogger.ERROR, typeName + "." + method.getName() + " must have an @Pattern annotation"); throw new UnableToCompleteException(); } pattern = oldAnnotation.value(); } else { pattern = annotation.value(); } pattern = dtpg.getBestPattern(pattern); writer.println(); String retTypeName = method.getReturnType().getQualifiedSourceName(); writer.println("public " + retTypeName + " " + method.getName() + "() {"); writer.println(" return " + retTypeName + ".getFormat(\"" + pattern + "\");"); writer.println("}"); } writer.commit(logger); } return packageName + "." + className; } }