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

com.google.gwt.autobean.server.impl.BeanMethod Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * 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.gwt.autobean.server.impl;

import com.google.gwt.autobean.shared.AutoBean;

import java.beans.Introspector;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * Breakout of method types that an AutoBean shim interface can implement. The
 * order of the values of the enum is important.
 *
 * 

AutoBeans has moved to * com.google.web.bindery.autobeans. This package will be * removed in a future version of GWT.

* * @see com.google.gwt.autobean.rebind.model.JBeanMethod */ @Deprecated public enum BeanMethod { /** * Methods defined in Object. */ OBJECT { @Override public String inferName(Method method) { throw new UnsupportedOperationException(); } @Override Object invoke(SimpleBeanHandler handler, Method method, Object[] args) throws Throwable { if (CALL.matches(handler, method)) { return CALL.invoke(handler, method, args); } return method.invoke(handler, args); } @Override boolean matches(SimpleBeanHandler handler, Method method) { return method.getDeclaringClass().equals(Object.class); } }, /** * Getters. */ GET { @Override public String inferName(Method method) { String name = method.getName(); if (name.startsWith(IS_PREFIX)) { Class returnType = method.getReturnType(); if (Boolean.TYPE.equals(returnType) || Boolean.class.equals(returnType)) { return Introspector.decapitalize(name.substring(2)); } } return super.inferName(method); } @Override Object invoke(SimpleBeanHandler handler, Method method, Object[] args) { String propertyName = inferName(method); Object toReturn = handler.getBean().getValues().get(propertyName); if (toReturn == null && method.getReturnType().isPrimitive()) { toReturn = TypeUtils.getDefaultPrimitiveValue(method.getReturnType()); } return toReturn; } @Override boolean matches(SimpleBeanHandler handler, Method method) { Class returnType = method.getReturnType(); if (method.getParameterTypes().length != 0 || Void.TYPE.equals(returnType)) { return false; } String name = method.getName(); if (Boolean.TYPE.equals(returnType) || Boolean.class.equals(returnType)) { if (name.startsWith(IS_PREFIX) && name.length() > 2 || name.startsWith(HAS_PREFIX) && name.length() > 3) { return true; } } return name.startsWith(GET_PREFIX) && name.length() > 3; } }, /** * Setters. */ SET { @Override Object invoke(SimpleBeanHandler handler, Method method, Object[] args) { handler.getBean().getValues().put(inferName(method), args[0]); return null; } @Override boolean matches(SimpleBeanHandler handler, Method method) { String name = method.getName(); return name.startsWith(SET_PREFIX) && name.length() > 3 && method.getParameterTypes().length == 1 && method.getReturnType().equals(Void.TYPE); } }, /** * A setter that returns a type assignable from the interface in which the * method is declared to support chained, builder-pattern setters. For * example, {@code foo.setBar(1).setBaz(42)}. */ SET_BUILDER { @Override Object invoke(SimpleBeanHandler handler, Method method, Object[] args) { handler.getBean().getValues().put(inferName(method), args[0]); return handler.getBean().as(); } @Override boolean matches(SimpleBeanHandler handler, Method method) { String name = method.getName(); return name.startsWith(SET_PREFIX) && name.length() > 3 && method.getParameterTypes().length == 1 && method.getReturnType().isAssignableFrom(method.getDeclaringClass()); } }, /** * Domain methods. */ CALL { @Override public String inferName(Method method) { throw new UnsupportedOperationException(); } @Override Object invoke(SimpleBeanHandler handler, Method method, Object[] args) throws Throwable { if (args == null) { args = EMPTY_OBJECT; } Method found = findMethod(handler, method); if (found != null) { Object[] realArgs = new Object[args.length + 1]; realArgs[0] = handler.getBean(); System.arraycopy(args, 0, realArgs, 1, args.length); return found.invoke(null, realArgs); } throw new RuntimeException("Could not find category implementation of " + method.toGenericString()); } @Override boolean matches(SimpleBeanHandler handler, Method method) { return handler.getBean().isWrapper() || !handler.getBean().getConfiguration().getCategories().isEmpty() && findMethod(handler, method) != null; } }; public static final String GET_PREFIX = "get"; public static final String HAS_PREFIX = "has"; public static final String IS_PREFIX = "is"; public static final String SET_PREFIX = "set"; private static final Object[] EMPTY_OBJECT = new Object[0]; static Method findMethod(SimpleBeanHandler handler, Method method) { Class[] declaredParams = method.getParameterTypes(); Class[] searchParams = new Class[declaredParams.length + 1]; searchParams[0] = AutoBean.class; System.arraycopy(declaredParams, 0, searchParams, 1, declaredParams.length); Class autoBeanType = handler.getBean().getType(); for (Class clazz : handler.getBean().getConfiguration().getCategories()) { try { Method found = clazz.getMethod(method.getName(), searchParams); if (!Modifier.isStatic(found.getModifiers())) { continue; } // Check the AutoBean parameterization of the 0th argument Class foundAutoBean = TypeUtils.ensureBaseType(TypeUtils.getSingleParameterization( AutoBean.class, found.getGenericParameterTypes()[0])); if (!foundAutoBean.isAssignableFrom(autoBeanType)) { continue; } return found; } catch (NoSuchMethodException expected) { } catch (IllegalArgumentException e) { throw new RuntimeException(e); } } return null; } public String inferName(Method method) { return Introspector.decapitalize(method.getName().substring(3)); } /** * Convenience method, not valid for {@link BeanMethod#CALL}. */ public boolean matches(Method method) { return matches(null, method); } /** * Invoke the method. */ abstract Object invoke(SimpleBeanHandler handler, Method method, Object[] args) throws Throwable; /** * Determine if the method maches the given type. */ abstract boolean matches(SimpleBeanHandler handler, Method method); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy