blob: 71f72602f29251f3429e1742ea0ca39d7df8fead [file] [log] [blame]
/*
* 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.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.i18n.rebind.AbstractResource.ResourceList;
import com.google.gwt.i18n.shared.GwtLocale;
import com.google.gwt.user.rebind.AbstractGeneratorClassCreator;
import com.google.gwt.user.rebind.AbstractMethodCreator;
import com.google.gwt.user.rebind.AbstractSourceCreator;
import java.text.MessageFormat;
/**
* Method creator to call the correct Map for the given Dictionary.
*/
class LookupMethodCreator extends AbstractMethodCreator {
/**
* Used partition size if no one is specified.
*
* Used in constructor without a partition size.
*/
private static final int DEFAULT_PARTITIONS_SIZE = 500;
private JType returnType;
private final int partitionsSize;
/**
* Constructor for <code>LookupMethodCreator</code>. The default partition size of 500 is used.
*
* @param classCreator parent class creator
* @param returnType associated return type
*
* @see LookupMethodCreator#DEFAULT_PARTITIONS_SIZE
*/
public LookupMethodCreator(AbstractGeneratorClassCreator classCreator, JType returnType) {
this(classCreator, returnType, DEFAULT_PARTITIONS_SIZE);
this.returnType = returnType;
}
/**
* Constructor for <code>LookupMethodCreator</code>.
*
* @param classCreator parent class creator
* @param returnType associated return type
* @param partitionsSize max numbers of lookups per method.
*/
public LookupMethodCreator(AbstractGeneratorClassCreator classCreator, JType returnType,
int partitionsSize) {
super(classCreator);
this.returnType = returnType;
this.partitionsSize = partitionsSize;
}
@Override
public void createMethodFor(TreeLogger logger, JMethod targetMethod, String key,
ResourceList resourceList, GwtLocale locale) {
createMethodFor(targetMethod);
}
/**
* Returns a {@code String} containing the return type name.
*/
protected String getReturnTypeName() {
String type;
JPrimitiveType s = returnType.isPrimitive();
if (s != null) {
type = AbstractSourceCreator.getJavaObjectTypeFor(s);
} else {
type = returnType.getParameterizedQualifiedSourceName();
}
return type;
}
void printLookup(String methodName) {
String body = "if(arg0.equals(" + wrap(methodName) + ")) {";
println(body);
indent();
printFound(methodName);
outdent();
println("}");
}
void createMethodFor(JMethod targetMethod) {
String template = "{0} target = ({0}) cache.get(arg0);";
String returnTypeName = getReturnTypeName();
String lookup = MessageFormat.format(template, new Object[] {returnTypeName});
println(lookup);
println("if (target != null) {");
indent();
printReturnTarget();
outdent();
println("}");
JMethod[] methods = ((ConstantsWithLookupImplCreator) currentCreator).allInterfaceMethods;
final int partitions = (methods.length / partitionsSize) + 1;
println(returnTypeName + " tmp;");
for (int i = 0; i < partitions; i++) {
println("tmp = " + targetMethod.getName() + i + "(arg0);");
println("if (tmp != null) {");
indent();
println("return tmp;");
outdent();
println("}");
}
String format = "throw new java.util.MissingResourceException(\"Cannot find constant ''\" +"
+ "{0} + \"''; expecting a method name\", \"{1}\", {0});";
String result = MessageFormat.format(format, "arg0", this.currentCreator.getTarget()
.getQualifiedSourceName());
println(result);
outdent();
println("}");
println("");
final String argument0Type = targetMethod.getParameterTypes()[0].getQualifiedSourceName();
for (int p = 0; p < partitions; p++) {
final String templateNewMethod = "private {0} {1}{2}({3} arg0) '{";
final String header = MessageFormat.format(templateNewMethod, new Object[] {
returnTypeName, targetMethod.getName(), p, argument0Type});
println(header);
indent();
final JType erasedType = returnType.getErasedType();
for (int i = 0 + p * partitionsSize; i < methods.length && i < (p + 1)
* partitionsSize; i++) {
final JMethod method = methods[i];
if (method.getReturnType().getErasedType().equals(erasedType) && method != targetMethod) {
String methodName = method.getName();
printLookup(methodName);
}
}
println("return null;");
if (p < partitions - 1) {
outdent();
println("}");
println("");
}
}
}
void printFound(String methodName) {
println(MessageFormat.format(returnTemplate(), new Object[] {methodName}));
}
void printReturnTarget() {
println("return target;");
}
String returnTemplate() {
return "return {0}();";
}
}