| /* |
| * Copyright 2010 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.web.bindery.autobean.gwt.rebind.model; |
| |
| import com.google.web.bindery.autobean.shared.AutoBean.PropertyName; |
| import com.google.gwt.core.ext.typeinfo.JClassType; |
| import com.google.gwt.core.ext.typeinfo.JEnumConstant; |
| import com.google.gwt.core.ext.typeinfo.JEnumType; |
| import com.google.gwt.core.ext.typeinfo.JMethod; |
| import com.google.gwt.core.ext.typeinfo.JType; |
| import com.google.gwt.core.ext.typeinfo.TypeOracle; |
| import com.google.gwt.editor.rebind.model.ModelUtils; |
| |
| import java.util.Collection; |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| |
| /** |
| * Describes a method implemented by an AutoBean. |
| */ |
| public class AutoBeanMethod { |
| /** |
| * Creates AutoBeanMethods. |
| */ |
| public static class Builder { |
| private AutoBeanMethod toReturn = new AutoBeanMethod(); |
| |
| public AutoBeanMethod build() { |
| if (toReturn.action.equals(JBeanMethod.GET) |
| || toReturn.action.equals(JBeanMethod.SET) |
| || toReturn.action.equals(JBeanMethod.SET_BUILDER)) { |
| PropertyName annotation = toReturn.method.getAnnotation(PropertyName.class); |
| if (annotation != null) { |
| toReturn.propertyName = annotation.value(); |
| } else { |
| toReturn.propertyName = toReturn.action.inferName(toReturn.method); |
| } |
| } |
| |
| try { |
| return toReturn; |
| } finally { |
| toReturn = null; |
| } |
| } |
| |
| public void setAction(JBeanMethod action) { |
| toReturn.action = action; |
| } |
| |
| public void setMethod(JMethod method) { |
| toReturn.method = method; |
| TypeOracle oracle = method.getEnclosingType().getOracle(); |
| |
| JType returnType = method.getReturnType(); |
| toReturn.isValueType = ModelUtils.isValueType(oracle, returnType); |
| |
| if (!toReturn.isValueType) { |
| // See if it's a collection or a map |
| JClassType returnClass = returnType.isClassOrInterface(); |
| JClassType collectionInterface = oracle.findType(Collection.class.getCanonicalName()); |
| JClassType mapInterface = oracle.findType(Map.class.getCanonicalName()); |
| if (collectionInterface.isAssignableFrom(returnClass)) { |
| JClassType[] parameterizations = ModelUtils.findParameterizationOf( |
| collectionInterface, returnClass); |
| toReturn.elementType = parameterizations[0]; |
| maybeProcessEnumType(toReturn.elementType); |
| } else if (mapInterface.isAssignableFrom(returnClass)) { |
| JClassType[] parameterizations = ModelUtils.findParameterizationOf( |
| mapInterface, returnClass); |
| toReturn.keyType = parameterizations[0]; |
| toReturn.valueType = parameterizations[1]; |
| maybeProcessEnumType(toReturn.keyType); |
| maybeProcessEnumType(toReturn.valueType); |
| } |
| } else { |
| maybeProcessEnumType(returnType); |
| } |
| } |
| |
| public void setNoWrap(boolean noWrap) { |
| toReturn.isNoWrap = noWrap; |
| } |
| |
| public void setStaticImp(JMethod staticImpl) { |
| toReturn.staticImpl = staticImpl; |
| } |
| |
| /** |
| * Call {@link #processEnumType(JEnumType)} if {@code type} is a |
| * {@link JEnumType}. |
| */ |
| private void maybeProcessEnumType(JType type) { |
| assert type != null : "type == null"; |
| JEnumType enumType = type.isEnum(); |
| if (enumType != null) { |
| processEnumType(enumType); |
| } |
| } |
| |
| /** |
| * Adds a JEnumType to the AutoBeanMethod's enumMap so that the |
| * AutoBeanFactoryGenerator can embed extra metadata about the enum values. |
| */ |
| private void processEnumType(JEnumType enumType) { |
| Map<JEnumConstant, String> map = toReturn.enumMap; |
| if (map == null) { |
| map = toReturn.enumMap = new LinkedHashMap<JEnumConstant, String>(); |
| } |
| for (JEnumConstant e : enumType.getEnumConstants()) { |
| String name = getEnumName(e); |
| map.put(e, name); |
| } |
| } |
| } |
| |
| static String getEnumName(JEnumConstant e) { |
| String name; |
| PropertyName annotation = e.getAnnotation(PropertyName.class); |
| if (annotation == null) { |
| name = e.getName(); |
| } else { |
| name = annotation.value(); |
| } |
| return name; |
| } |
| |
| private JBeanMethod action; |
| private JClassType elementType; |
| private Map<JEnumConstant, String> enumMap; |
| private JClassType keyType; |
| private JMethod method; |
| private boolean isNoWrap; |
| private boolean isValueType; |
| private String propertyName; |
| private JMethod staticImpl; |
| private JClassType valueType; |
| |
| private AutoBeanMethod() { |
| } |
| |
| public JBeanMethod getAction() { |
| return action; |
| } |
| |
| public JClassType getElementType() { |
| return elementType; |
| } |
| |
| public Map<JEnumConstant, String> getEnumMap() { |
| return enumMap; |
| } |
| |
| public JClassType getKeyType() { |
| return keyType; |
| } |
| |
| public JMethod getMethod() { |
| return method; |
| } |
| |
| public String getPropertyName() { |
| return propertyName; |
| } |
| |
| /** |
| * If the AutoBean method was declared in a type containing a |
| * {@link com.google.gwt.editor.client.AutoBean.Category Category} annotation, |
| * this method will return the static implementation. |
| */ |
| public JMethod getStaticImpl() { |
| return staticImpl; |
| } |
| |
| public JClassType getValueType() { |
| return valueType; |
| } |
| |
| public boolean hasEnumMap() { |
| return enumMap != null; |
| } |
| |
| public boolean isCollection() { |
| return elementType != null; |
| } |
| |
| public boolean isMap() { |
| return keyType != null; |
| } |
| |
| public boolean isNoWrap() { |
| return isNoWrap; |
| } |
| |
| public boolean isValueType() { |
| return isValueType; |
| } |
| |
| /** |
| * For debugging use only. |
| */ |
| @Override |
| public String toString() { |
| return method.toString(); |
| } |
| } |