All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.i18n.rebind.LocalizableLinkageCreator Maven / Gradle / Ivy

The newest version!
/*
 * 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.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.i18n.shared.GwtLocale;
import com.google.gwt.user.rebind.AbstractSourceCreator;

import java.util.HashMap;
import java.util.Map;

/**
 * Links classes with their localized counterparts.
 */
class LocalizableLinkageCreator extends AbstractSourceCreator {
  
  static Map findDerivedClasses(TreeLogger logger,
      JClassType baseClass) throws UnableToCompleteException {
    // Construct valid set of candidates for this type.
    Map matchingClasses = new HashMap();
    // Add base class if possible.
    if (baseClass.isInterface() == null && baseClass.isAbstract() == false) {
      matchingClasses.put(GwtLocale.DEFAULT_LOCALE, baseClass);
    }
    String baseName = baseClass.getSimpleSourceName();

    // Find matching sub types.
    JClassType[] x = baseClass.getSubtypes();
    for (int i = 0; i < x.length; i++) {
      JClassType subType = x[i];
      if ((subType.isInterface() == null) && (subType.isAbstract() == false)) {
        String name = subType.getSimpleSourceName();
        // Strip locale from type,
        int localeIndex = name.indexOf(ResourceFactory.LOCALE_SEPARATOR);
        String subTypeBaseName = name;
        if (localeIndex != -1) {
          subTypeBaseName = name.substring(0, localeIndex);
        }
        boolean matches = subTypeBaseName.equals(baseName);
        if (matches) {
          boolean isDefault = localeIndex == -1
              || localeIndex == name.length() - 1
              || GwtLocale.DEFAULT_LOCALE.equals(name.substring(localeIndex + 1));
          if (isDefault) {
            // Don't override base as default if present.
            JClassType defaultClass = 
              matchingClasses.get(GwtLocale.DEFAULT_LOCALE);
            if (defaultClass != null) {
              throw error(logger, defaultClass + " and " + baseName
                  + " are both potential default classes for " + baseClass);
            } else {
              matchingClasses.put(GwtLocale.DEFAULT_LOCALE, subType);
            }
          } else {
            // Don't allow a locale to be ambiguous. Very similar to default
            // case, different error message.
            String localeSubString = name.substring(localeIndex + 1);
            JClassType dopClass = matchingClasses.get(localeSubString);
            if (dopClass != null) {
              throw error(logger, dopClass.getQualifiedSourceName() + " and "
                  + subType.getQualifiedSourceName()
                  + " are both potential matches to " + baseClass
                  + " in locale " + localeSubString);
            }
            matchingClasses.put(localeSubString, subType);
          }
        }
      }
    }
    return matchingClasses;
  }

  /**
   * Map to cache linkages of implementation classes and interfaces.
   */
  // Change back to ReferenceMap once apache collections is in.
  private final Map implCache = new HashMap();

  /**
   * * Finds associated implementation in the current locale. Here are the rules
   * 

*

*

* If class name is X, and locale is z_y, look for X_z_y, then X_z, then X *

* * @param baseClass * @return class name to link with * @throws UnableToCompleteException */ String linkWithImplClass(TreeLogger logger, JClassType baseClass, GwtLocale locale) throws UnableToCompleteException { String baseName = baseClass.getQualifiedSourceName(); /** * Try to find implementation class, as the current class is not a Constant * or Message. */ String className = implCache.get(baseName + locale.toString()); if (className != null) { return className; } if (baseClass.getName().indexOf(ResourceFactory.LOCALE_SEPARATOR) != -1) { throw error(logger, "Cannot have a " + ResourceFactory.LOCALE_SEPARATOR + " in the base localizable class " + baseClass); } Map matchingClasses = findDerivedClasses(logger, baseClass); // Now that we have all matches, find best class JClassType result = null; for (GwtLocale search : locale.getCompleteSearchList()) { result = matchingClasses.get(search.toString()); if (result != null) { className = result.getQualifiedSourceName(); implCache.put(baseName + locale.toString(), className); return className; } } // No classes matched. throw error(logger, "Cannot find a class to bind to argument type " + baseClass.getQualifiedSourceName()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy