Package com.google.gwt.i18n.rebind

Source Code of com.google.gwt.i18n.rebind.AbstractLocalizableImplCreator

/*
* Copyright 2007 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.GeneratorContext;
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.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.i18n.rebind.util.AbstractResource;
import com.google.gwt.i18n.rebind.util.ResourceFactory;
import com.google.gwt.user.rebind.AbstractGeneratorClassCreator;
import com.google.gwt.user.rebind.AbstractMethodCreator;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;

import java.io.PrintWriter;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Set;

/**
* Represents generic functionality needed for <code>Constants</code> and
* <code>Messages</code> classes.
*/
abstract class AbstractLocalizableImplCreator extends
    AbstractGeneratorClassCreator {

  static String generateConstantOrMessageClass(TreeLogger logger,
      GeneratorContext context, Locale locale, JClassType targetClass)
      throws UnableToCompleteException {
    TypeOracle oracle = context.getTypeOracle();
    JClassType constantsClass;
    JClassType messagesClass;
    JClassType constantsWithLookupClass;
    try {
      constantsClass = oracle.getType(LocalizableGenerator.CONSTANTS_NAME);
      constantsWithLookupClass = oracle.getType(LocalizableGenerator.CONSTANTS_WITH_LOOKUP_NAME);
      messagesClass = oracle.getType(LocalizableGenerator.MESSAGES_NAME);
    } catch (NotFoundException e) {
      // Should never happen in practice.
      throw error(logger, e);
    }

    String name = targetClass.getName();
    String packageName = targetClass.getPackage().getName();

    // Make sure the interface being rebound extends either Constants or
    // Messages.
    boolean assignableToConstants = constantsClass.isAssignableFrom(targetClass);
    boolean assignableToMessages = messagesClass.isAssignableFrom(targetClass);
    if (!assignableToConstants && !assignableToMessages) {
      // Let the implementation generator handle this interface.
      return null;
    }

    // Make sure that they don't try to extend both Messages and Constants.
    if (assignableToConstants && assignableToMessages) {
      throw error(logger, name + " cannot extend both Constants and Messages");
    }

    // Make sure that the type being rebound is in fact an interface.
    if (targetClass.isInterface() == null) {
      throw error(logger, name + " must be an interface");
    }

    AbstractResource resource;
    try {
      resource = ResourceFactory.getBundle(targetClass, locale);
    } catch (MissingResourceException e) {
      throw error(
          logger,
          "Localization failed; there must be at least one properties file accessible through the classpath in package '"
              + packageName
              + "' whose base name is '"
              + ResourceFactory.getResourceName(targetClass) + "'");
    } catch (IllegalArgumentException e) {
      // A bad key can generate an illegal argument exception.
      throw error(logger, e.getMessage());
    }

    // generated implementations for interface X will be named X_, X_en,
    // X_en_CA, etc.
    String realLocale = "_";
    if (resource.getLocale() != null) {
      realLocale += resource.getLocale();
    }
    // Use _ rather than "." in class name, cannot use $
    String resourceName = targetClass.getName().replace('.', '_');
    String className = resourceName + realLocale;
    PrintWriter pw = context.tryCreate(logger, packageName, className);
    if (pw != null) {
      ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(
          packageName, className);
      factory.addImplementedInterface(targetClass.getQualifiedSourceName());
      SourceWriter writer = factory.createSourceWriter(context, pw);
      // Now that we have all the information set up, process the class
      if (constantsWithLookupClass.isAssignableFrom(targetClass)) {
        ConstantsWithLookupImplCreator c = new ConstantsWithLookupImplCreator(
            logger, writer, targetClass, resource, context.getTypeOracle());
        c.emitClass(logger);
      } else if (constantsClass.isAssignableFrom(targetClass)) {
        ConstantsImplCreator c = new ConstantsImplCreator(logger, writer,
            targetClass, resource, context.getTypeOracle());
        c.emitClass(logger);
      } else {
        MessagesImplCreator messages = new MessagesImplCreator(logger, writer,
            targetClass, resource, context.getTypeOracle());
        messages.emitClass(logger);
      }
      context.commit(logger, pw);
    }
    return packageName + "." + className;
  }

  /**
   * The Dictionary/value bindings used to determine message contents.
   */
  private AbstractResource messageBindings;

  /**
   * Constructor for <code>AbstractLocalizableImplCreator</code>.
   *
   * @param writer writer
   * @param targetClass current target
   * @param messageBindings backing resource
   */
  public AbstractLocalizableImplCreator(SourceWriter writer,
      JClassType targetClass, AbstractResource messageBindings) {
    super(writer, targetClass);
    this.messageBindings = messageBindings;
  }

  /**
   * Gets the resource associated with this class.
   *
   * @return the resource
   */
  public AbstractResource getResourceBundle() {
    return messageBindings;
  }

  protected String branchMessage() {
    return "Processing " + this.getTarget();
  }

  /**
   * Find the creator associated with the given method, and delegate the
   * creation of the method body to it.
   *
   * @param logger
   * @param method method to be generated
   * @throws UnableToCompleteException
   */
  protected void delegateToCreator(TreeLogger logger, JMethod method)
      throws UnableToCompleteException {
    AbstractMethodCreator methodCreator = getMethodCreator(logger, method);
    String key = getKey(logger, method);
    String value;
    try {
      value = messageBindings.getString(key);
    } catch (MissingResourceException e) {
      String s = "Could not find requested resource key '" + key + "'";
      TreeLogger child = logger.branch(TreeLogger.ERROR, s, null);
      Set keys = messageBindings.keySet();
      if (keys.size() < AbstractResource.REPORT_KEYS_THRESHOLD) {
        String keyString = "Keys found: " + keys;
        throw error(child, keyString);
      } else {
        throw new UnableToCompleteException();
      }
    }
    String localeString;
    if (messageBindings.getLocale() == null
        || messageBindings.getLocale().toString().equals("")) {
      localeString = "default";
    } else {
      localeString = messageBindings.getLocale().toString();
    }
    String info = "When locale is '" + localeString + "', property '" + key
        + "' has the value '" + value + "'";
    TreeLogger branch = logger.branch(TreeLogger.TRACE, info, null);
    methodCreator.createMethodFor(branch, method, value);
  }

  /**
   * Returns a resource key given a method name.
   *
   * @param logger
   * @param method
   * @return the key
   */
  protected String getKey(TreeLogger logger, JMethod method) {
    String[][] id = method.getMetaData(LocalizableGenerator.GWT_KEY);
    if (id.length > 0) {
      if (id[0].length == 0) {
        logger.log(TreeLogger.WARN, method
            + " had a mislabeled gwt.key, using method name as key", null);
      } else {
        String tag = id[0][0];
        return tag;
      }
    }
    return method.getName();
  }
}
TOP

Related Classes of com.google.gwt.i18n.rebind.AbstractLocalizableImplCreator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.