Package org.reverspring.strategy.annotation

Source Code of org.reverspring.strategy.annotation.AnnotationDescriptionStrategy

/*
* Copyright 2007 Luigi Dell'Aquila (luigi.dellaquila@assetdata.it)
*
* 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.reverspring.strategy.annotation;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.reverspring.annotations.SpringConstructor;
import org.reverspring.annotations.SpringDescribe;
import org.reverspring.strategy.DescriptionStrategy;

/**
* this class defines a strategy based on {@link SpringDescribe} and {@link SpringConstructor} annotations
* to describe attributes and constructor to be used in the XML
* @author Luigi Dell'Aquila
*
*/
public class AnnotationDescriptionStrategy implements DescriptionStrategy {

  public String getDesiredId(Object obj) {
    if (obj == null)
      return null;

    Method idMethod = null;
    for (Method method : obj.getClass().getMethods()) {

      SpringDescribe describe = method.getAnnotation(SpringDescribe.class);
      if (describe != null && describe.isIdSource() && method.getGenericParameterTypes().length == 0) {
        idMethod = method;
        break;
      }
    }

    if (idMethod == null)
      return null;

    try {
      Object id = idMethod.invoke(obj, new Object[0]);
      if (id != null && !id.toString().trim().equals(""))
        return id.toString();
      else
        return null;
    } catch (IllegalArgumentException e) {
      return null;
    } catch (IllegalAccessException e) {
      return null;
    } catch (InvocationTargetException e) {
      return null;
    }
  }

  public Set<String> getPropertyNames(Object obj) {
    Set<String> included = new HashSet<String>();
    boolean defaultInclude = false;
    SpringDescribe classAnnotation = (SpringDescribe) obj.getClass().getAnnotation(SpringDescribe.class);
    if (classAnnotation != null)
      defaultInclude = classAnnotation.included();

    // look for getters
    Method[] methods = obj.getClass().getMethods();
    for (Method method : methods) {
      if (method.getName().equals("getClass"))
        continue;
      boolean methodInclude = defaultInclude;
      String methodName = method.getName();
      if (!isValidGetter(method))
        continue;
      if (!existsSetterForGetter(method, obj.getClass()))
        continue;
      SpringDescribe annotation = (SpringDescribe) method.getAnnotation(SpringDescribe.class);

      if (annotation != null)
        methodInclude = annotation.included();
      if (!methodInclude)
        continue;
      String propertyName;
      if (methodName.startsWith("get"))
        propertyName = methodName.substring(3); // getXXX
      else
        propertyName = methodName.substring(2); // isXXX
      propertyName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1);
      included.add(propertyName);

    }
    return included;
  }

  private static boolean isValidGetter(Method method) {
    if (!Modifier.isPublic(method.getModifiers()))
      return false;
    Class<?> attributeType = method.getReturnType();
    if (attributeType == null)
      return false;
    if (method.getParameterTypes().length > 0)
      return false;
    String name = method.getName();
    if ((!name.startsWith("get")) && (!name.startsWith("is")))
      return false; // invalid getter
    if (name.startsWith("get"))
      name = name.substring(3); // getXXX
    else {
      name = name.substring(2); // isXXX
    }
    if (name.substring(0, 1).toLowerCase().equals(name.substring(0, 1)))
      return false; // after "get" there is a lowercase: ignore
    return true;
  }

  private static boolean existsSetterForGetter(Method getter, Class<?> clazz) {
    if (getter == null)
      return false;
    String setterName = getter.getName();
    if (setterName.length() < 4)
      return false;
    if (setterName.startsWith("get")) // getXXX -> setXXX
      setterName = "s" + setterName.substring(1);
    else
      setterName = "set" + setterName.substring(2); // isXXX -> setXXX
    try {
      Method setter = clazz.getMethod(setterName, getter.getReturnType());
      if (setter == null)
        return false;
    } catch (Exception e) {
      return false;
    }
    return true;
  }

  public boolean nested(Object obj, String propertyName) {
    if(obj instanceof Map<?, ?>)
      return true;
    if(obj instanceof List<?>)
      return true;
    if(obj instanceof Set<?>)
      return true;
    Class<?> clazz = obj.getClass();
    Method method = null;
    try {
      method = clazz.getMethod(
          "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1), new Class[0]);
    } catch (Exception e) {
    }
    if (method == null) {
      try {
        method = clazz.getMethod("is" + propertyName.substring(0, 1).toUpperCase()
            + propertyName.substring(1), new Class[0]);
      } catch (Exception e) {
      }
    }
    if (method == null)
      return false;
    SpringDescribe annotation = method.getAnnotation(SpringDescribe.class);
    if (annotation == null) {
      SpringDescribe classAnnotation = clazz.getAnnotation(SpringDescribe.class);
      if (classAnnotation == null)
        return false;
      return classAnnotation.nested();
    }
    return annotation.nested();
  }

  public Constructor<?> getConstructor(Object obj) {
    // check annotations
    Constructor<?>[] constructors = obj.getClass().getConstructors();
    for (Constructor<?> constructor : constructors) {
      if (constructor.getAnnotation(SpringConstructor.class) != null)
        return constructor;
    }

    // no annotations found, check for empty constructor
    try {
      Constructor<?> constructor = obj.getClass().getConstructor();
      if (Modifier.isPublic(constructor.getModifiers()))
        return constructor;
    } catch (Exception e) {
      return null;
    }
    return null;
  }

  public Object[] getConstructorArgs(Object obj) throws Exception{
    if (obj instanceof String)
      return new String[] { obj.toString() };
    if (obj instanceof Integer)
      return new String[] { obj.toString() };
    if (obj instanceof Long)
      return new String[] { obj.toString() };
    if (obj instanceof Short)
      return new String[] { obj.toString() };
    if (obj instanceof Float)
      return new String[] { obj.toString() };
    if (obj instanceof Double)
      return new String[] { obj.toString() };
    if (obj instanceof Boolean)
      return new String[] { obj.toString() };

    List<Object> params = new ArrayList<Object>();

    Constructor<?> constructor = getConstructor(obj);
    SpringConstructor constructorAnnotation = constructor.getAnnotation(SpringConstructor.class);
    if (constructorAnnotation != null && constructorAnnotation.constructorParamsGetters() != null) {
      for (String paramGetter : constructorAnnotation.constructorParamsGetters()) {
        Object paramValue = obj.getClass().getMethod(paramGetter, new Class<?>[0]).invoke(obj, new Object[0]);
        params.add(paramValue);
      }
    }
    return params.toArray();
  }

}
TOP

Related Classes of org.reverspring.strategy.annotation.AnnotationDescriptionStrategy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.