| /* |
| * 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 = getDateTimePatternGenerator(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; |
| } |
| |
| protected DateTimePatternGenerator getDateTimePatternGenerator(GwtLocale gwtLocale) { |
| return new DateTimePatternGenerator(gwtLocale); |
| } |
| } |