KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > i18n > rebind > LocalizableLinkageCreator


1 /*
2  * Copyright 2006 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */

16 package com.google.gwt.i18n.rebind;
17
18 import com.google.gwt.core.ext.TreeLogger;
19 import com.google.gwt.core.ext.UnableToCompleteException;
20 import com.google.gwt.core.ext.typeinfo.JClassType;
21 import com.google.gwt.user.rebind.AbstractSourceCreator;
22
23 import java.util.HashMap JavaDoc;
24 import java.util.Locale JavaDoc;
25 import java.util.Map JavaDoc;
26
27 /**
28  * Links classes with their localized counterparts.
29  */

30 class LocalizableLinkageCreator extends AbstractSourceCreator {
31   private static Map JavaDoc findDerivedClasses(TreeLogger logger, JClassType baseClass)
32       throws UnableToCompleteException {
33     // Construct valid set of candidates for this type.
34
Map JavaDoc matchingClasses = new HashMap JavaDoc();
35     // Add base class if possible.
36
if (baseClass.isInterface() == null && baseClass.isAbstract() == false) {
37       matchingClasses.put(LocalizableGenerator.DEFAULT_TOKEN, baseClass);
38     }
39     String JavaDoc baseName = baseClass.getSimpleSourceName();
40
41     // Find matching sub types.
42
JClassType[] x = baseClass.getSubtypes();
43     for (int i = 0; i < x.length; i++) {
44       JClassType subType = x[i];
45       if ((subType.isInterface() == null) && (subType.isAbstract() == false)) {
46         String JavaDoc name = subType.getSimpleSourceName();
47         // Strip locale from type,
48
int localeIndex = name.indexOf("_");
49         String JavaDoc subTypeBaseName = name;
50         if (localeIndex != -1) {
51           subTypeBaseName = name.substring(0, localeIndex);
52         }
53         boolean matches = subTypeBaseName.equals(baseName);
54         if (matches) {
55           boolean isDefault = localeIndex == -1
56               || localeIndex == name.length() - 1;
57           if (isDefault) {
58             // Don't override base as default if present.
59
JClassType defaultClass = (JClassType) matchingClasses.get(LocalizableGenerator.DEFAULT_TOKEN);
60             if (defaultClass != null) {
61               throw error(logger, defaultClass + " and " + baseName
62                   + " are both potencial default classes for " + baseClass);
63             } else {
64               matchingClasses.put(LocalizableGenerator.DEFAULT_TOKEN, subType);
65             }
66           } else {
67             // Don't allow a locale to be ambiguous. Very similar to default
68
// case, different error message.
69
String JavaDoc localeSubString = name.substring(localeIndex + 1);
70             JClassType dopClass = (JClassType) matchingClasses.get(localeSubString);
71             if (dopClass != null) {
72               throw error(logger, dopClass.getQualifiedSourceName() + " and "
73                   + subType.getQualifiedSourceName()
74                   + " are both potential matches to " + baseClass
75                   + " in locale" + localeSubString);
76             }
77             matchingClasses.put(localeSubString, subType);
78           }
79         }
80       }
81     }
82     return matchingClasses;
83   }
84
85   /**
86    * Map to cache linkages of implementation classes and interfaces.
87    */

88   // Change back to ReferenceMap once apache collections is in.
89
private final Map JavaDoc implCache = new HashMap JavaDoc();
90
91   /**
92    * * Finds associated implementation in the current locale. Here are the rules
93    * <p>
94    * </p>
95    * <p>
96    * If class name is X, and locale is z_y, look for X_z_y, then X_z, then X
97    * </p>
98    *
99    * @param baseClass
100    * @return class name to link with
101    * @throws UnableToCompleteException
102    */

103   String JavaDoc linkWithImplClass(TreeLogger logger, JClassType baseClass,
104       Locale JavaDoc locale) throws UnableToCompleteException {
105
106     String JavaDoc baseName = baseClass.getQualifiedSourceName();
107     /**
108      * Try to find implementation class, as the current class is not a Constant
109      * or Message.
110      */

111     String JavaDoc className = (String JavaDoc) implCache.get(baseName + locale);
112     if (className != null) {
113       return className;
114     }
115
116     if (baseClass.getName().indexOf("_") == 0) {
117       throw error(logger, "Cannot have a '_' in the base localizable class "
118           + baseClass);
119     }
120     Map JavaDoc matchingClasses = findDerivedClasses(logger, baseClass);
121     // Now that we have all matches, find best class
122
String JavaDoc localeSuffix;
123     JClassType result = null;
124     if (locale == null) {
125       localeSuffix = LocalizableGenerator.DEFAULT_TOKEN;
126     } else {
127       localeSuffix = locale.toString();
128     }
129     while (true) {
130       // Check for current result.
131
result = (JClassType) matchingClasses.get(localeSuffix);
132       if (result != null) {
133         break;
134       }
135       // Now set up next option.
136
int strip = localeSuffix.lastIndexOf("_");
137       if (localeSuffix == LocalizableGenerator.DEFAULT_TOKEN) {
138         // We already shot our wad, no classes matched.
139
throw error(logger, "Cannot find a class to bind to argument type "
140             + baseClass.getQualifiedSourceName());
141       } else if (strip == -1) {
142         // Try default.
143
localeSuffix = LocalizableGenerator.DEFAULT_TOKEN;
144       } else {
145         // Try language specific locale.
146
localeSuffix = localeSuffix.substring(0, strip);
147       }
148     }
149     implCache.put(baseName + locale, className);
150     return result.getQualifiedSourceName();
151   }
152 }
153
Popular Tags