/*
* Copyright 2002-2008 the original author or authors.
*
* 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 org.gwtoolbox.bean.rebind;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JField;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JType;
import org.gwtoolbox.bean.client.annotation.Bean;
import org.gwtoolbox.commons.collections.client.Pair;
import org.gwtoolbox.commons.util.client.StringUtils;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @author Uri Boness
*/
public class BeanGeneratorUtils {
private final static String GET_CLASS_METHOD = "getClass";
private final static String SET_PREFIX = "set";
private final static String GET_PREFIX = "get";
private final static String IS_PREFIX = "is";
public static String[] extractPropertyNames(JClassType beanType) {
Set<String> officials = new HashSet<String>();
JClassType currentType = beanType;
while (currentType != null) {
JMethod[] methods = currentType.getMethods();
for (JMethod method : methods) {
String methodName = method.getName();
if (GET_CLASS_METHOD.equals(methodName)) {
continue;
}
String propertyName = null;
if (methodName.startsWith(SET_PREFIX) && method.getParameters().length == 1) {
propertyName = StringUtils.uncapitalize(methodName.substring(3));
}
else if (methodName.startsWith(GET_PREFIX) && method.getParameters().length == 0) {
propertyName = StringUtils.uncapitalize(methodName.substring(3));
}
else if (methodName.startsWith(IS_PREFIX) && method.getParameters().length == 0) {
propertyName = StringUtils.uncapitalize(methodName.substring(2));
}
if (propertyName != null) {
officials.add(propertyName);
}
}
currentType = currentType.getSuperclass();
}
return officials.toArray(new String[officials.size()]);
}
public static JType getPropertyType(JClassType type, String propertyName) {
JMethod method = findGetterMethod(type, propertyName);
if (method != null) {
return method.getReturnType();
}
method = findSetterMethod(type, propertyName);
return (method == null) ? null : method.getParameters()[0].getType();
}
public static JField findField(JClassType type, String propertyName) {
JField field = null;
JClassType currentType = type;
while (currentType != null) {
field = currentType.findField(propertyName);
if (field != null) {
break;
}
currentType = currentType.getSuperclass();
}
return field;
}
public static JMethod findGetterMethod(JClassType type, String propertyName) {
JMethod method = null;
JClassType currentType = type;
while (currentType != null) {
method = currentType.findMethod(createGetGetterName(propertyName), new JType[0]);
if (method != null) {
break;
}
method = currentType.findMethod(createIsGetterName(propertyName), new JType[0]);
if (method != null) {
break;
}
currentType = currentType.getSuperclass();
}
return method;
}
public static JMethod findSetterMethod(JClassType type, String propertyName) {
String setterName = createSetterName(propertyName);
JMethod method = null;
JClassType currentType = type;
while (currentType != null) {
JMethod[] methods = currentType.getMethods();
for (JMethod m : methods) {
if (m.getName().equals(setterName) && m.getParameters().length == 1) {
return m;
}
}
currentType = currentType.getSuperclass();
}
return null;
}
public static String createSetterName(String propertyName) {
return "set" + StringUtils.capitalize(propertyName);
}
public static String createGetGetterName(String propertyName) {
return "get" + StringUtils.capitalize(propertyName);
}
public static String createIsGetterName(String propertyName) {
return "is" + StringUtils.capitalize(propertyName);
}
public static boolean isBean(JType type) {
JClassType classType = type.isClass();
return classType != null && classType.isAnnotationPresent(Bean.class);
}
public static JClassType findCollectionElementType(JType colType, GeneratorContext context) {
JClassType collectionType = context.getTypeOracle().findType(Collection.class.getName()).getErasedType();
Set<? extends JClassType> allSuperTypes = colType.isClassOrInterface().getFlattenedSupertypeHierarchy();
for (JClassType superType : allSuperTypes) {
if (collectionType.equals(superType.getErasedType())) {
return superType.isParameterized().getTypeArgs()[0];
}
}
throw new IllegalArgumentException("Type '" + colType.getQualifiedSourceName() + "' is not of a java.util.Collection type");
}
public static Pair<JClassType, JClassType> findMapKeyValueTypes(JType colType, GeneratorContext context) {
JClassType mapType = context.getTypeOracle().findType(Map.class.getName()).getErasedType();
Set<? extends JClassType> allSuperTypes = colType.isClassOrInterface().getFlattenedSupertypeHierarchy();
for (JClassType superType : allSuperTypes) {
if (mapType.equals(superType.getErasedType())) {
JClassType[] paramTypes = superType.isParameterized().getTypeArgs();
return new Pair<JClassType, JClassType>(paramTypes[0], paramTypes[1]);
}
}
throw new IllegalArgumentException("Type '" + colType.getQualifiedSourceName() + "' is not of a java.util.Collection type");
}
}