Package org.araneaframework.backend.util

Source Code of org.araneaframework.backend.util.BeanMapper

/**
* Copyright 2006 Webmedia Group Ltd.
*
* 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.araneaframework.backend.util;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.exception.NestableRuntimeException;
import org.apache.log4j.Logger;

/**
* This class provides a way to manipulate Value Object fields. This class
* assumes that the class passed to constructor (<code>voClass</code>)
* implements the Value Object pattern - that is to open it's fields using
* getters and setters (read-only fields are permitted). The only names
* permitted are those starting with "get", "is" and "set". Another requirement
* is that Value Objects must have a constructor that doesn't take any
* parameters.
*
* @author Jevgeni Kabanov (ekabanov@webmedia.ee)
* @since 1.4.1.20
*/
public class BeanMapper implements Serializable {
  private static Logger log = Logger.getLogger(BeanMapper.class);
 
  //*******************************************************************
  // FIELDS
  //*******************************************************************
 
  /**
   * Holds the Value Object <code>Class</code>.
   */
  private Class voClass;
 
  //*********************************************************************
  //* PUBLIC METHODS
  //*********************************************************************
 
  /**
   * Initializes the VoMapper.
   *
   * @param voClass
   *          the class implementing the Value Object pattern.
   */
  public BeanMapper(Class voClass) {
    this.voClass = voClass;
  }
 
  /**
   * Returns <code>List&lt;String&gt;</code>- the <code>List</code> of VO
   *         field names.
   * @return <code>List&lt;String&gt;</code>- the <code>List</code> of VO
   *         field names.
   */
  public List getBeanFields() {
    List result = new ArrayList();
   
    Method[] voMethods = voClass.getMethods();
    for (int i = 0; i < voMethods.length; i++) {
      Method voMethod = voMethods[i];
      //Checking that method may be a valid getter method
      if (Modifier.isPublic(voMethod.getModifiers()) && (voMethod.getParameterTypes().length == 0) && !(voMethod.getReturnType().isAssignableFrom(Void.class))) {
        //Checking that it's a getter method, and it has a corresponding
        // setter method.
        if (voMethod.getName().startsWith("get") && !"getClass".equals(voMethod.getName())) {
          //Adding the field...
          result.add(voMethod.getName().substring(3, 4).toLowerCase() + voMethod.getName().substring(4));
        }
        else if (voMethod.getName().startsWith("is") && (Boolean.class.equals(voMethod.getReturnType()) || boolean.class.equals(voMethod.getReturnType()))) {
          //Adding the field...
          result.add(voMethod.getName().substring(2, 3).toLowerCase() + voMethod.getName().substring(3));
         
        }
      }
    }
   
    return result;
  }
 
  /**
   * Returns the value of VO field identified with name <code>field</code>
   * for object <code>vo</code>
   *
   * @param vo
   *          Object, which value to return.
   * @param field
   *          The name of VO field.
   * @return The value of the field.
   */
  public Object getBeanFieldValue(Object vo, String fieldName) {
    String mainFieldName = fieldName;
    String subFields = null;
    if (fieldName.indexOf(".") != -1) {
      mainFieldName = fieldName.substring(0, fieldName.indexOf("."));
      subFields = fieldName.substring(mainFieldName.length() + 1);
     
      Object result = null;
      try {
        Method getter = getGetterMethod(mainFieldName);
        result = getter.invoke(vo, null);
        return new BeanMapper(getBeanFieldType(mainFieldName)).getBeanFieldValue(result, subFields);
      }
      catch (InvocationTargetException e) {
        throw new NestableRuntimeException("There was a problem getting field '" + fieldName + "' value", e);
      }
      catch (IllegalAccessException e) {
        throw new NestableRuntimeException("There was a problem getting field '" + fieldName + "' value", e);
      }
    }
   
    Object result = null;
    try {
      Method getter = getGetterMethod(fieldName);
      if (getter != null) {
        result = getter.invoke(vo, null);
      }
    }
    catch (InvocationTargetException e) {
      throw new NestableRuntimeException("There was a problem getting field '" + fieldName + "' value", e);
    }
    catch (IllegalAccessException e) {
      throw new NestableRuntimeException("There was a problem getting field '" + fieldName + "' value", e);
    }
    return result;
  }
 
  /**
   * Sets the value of VO field identified by name <code>field</code> for
   * object <code>vo</code>.
   *
   * @param vo
   *          vo Object, which value to set.
   * @param field
   *          The name of VO field.
   * @param value
   *          The new value of the field.
   */
  public void setBeanFieldValue(Object vo, String fieldName, Object value) {
    try {
      Method setter = getSetterMethod(fieldName);
      if (setter != null) {
        setter.invoke(vo, new Object[] { value });
      }
    }
    catch (InvocationTargetException e) {
      throw new NestableRuntimeException("There was a problem setting field '" + fieldName + "' to value " + value, e);
    }
    catch (IllegalAccessException e) {
      throw new NestableRuntimeException("There was a problem setting field '" + fieldName + "' to value " + value, e);
    }
  }
 
  /**
   * Returns type of VO field identified by name <code>field</code>.
   *
   * @param field
   *          The name of VO field.
   * @return The type of the field.
   */
  public Class getBeanFieldType(String fieldName) {
    Class result = null;
    Method getter = getGetterMethod(fieldName);
    if (getter != null) {
      result = getter.getReturnType();
    }
    return result;
  }
 
  /**
   * Checks that the field identified by <code>fieldName</code> is a valid
   * Value Object field.
   *
   * @param fieldName
   *          Value Object field name.
   * @return if this field is in Value Object.
   */
  public boolean fieldExists(String fieldName) {
    return (getGetterMethod(fieldName) != null);
  }
 
  /**
   * Checks that the field identified by <code>fieldName</code> is a writable
   * Value Object field.
   *
   * @param fieldName
   *          Value Object field name.
   * @return if this field is in Value Object.
   */
  public boolean fieldIsWritable(String fieldName) {
    return (getSetterMethod(fieldName) != null);
  }
 
  //*********************************************************************
  //* PRIVATE HELPER METHODS
  //*********************************************************************
 
  /**
   * Returns getter from field name.
   */
  private Method getGetterMethod(String fieldName) {
    String mainFieldName = fieldName;
    String subFields = null;
    if (fieldName.indexOf(".") != -1) {
      mainFieldName = fieldName.substring(0, fieldName.indexOf("."));
      subFields = fieldName.substring(mainFieldName.length() + 1);
    }
   
    String getterName = "get" + mainFieldName.substring(0, 1).toUpperCase() + mainFieldName.substring(1);
    try {
      Method method = voClass.getMethod(getterName, null);
      if (subFields != null) {
        return new BeanMapper(method.getReturnType()).getGetterMethod(subFields);
      }
      return method;
    }
    catch (NoSuchMethodException e) {
      //There is not 'get' method for this field
    }
   
    getterName = "is" + mainFieldName.substring(0, 1).toUpperCase() + mainFieldName.substring(1);
    try {
      Method method = voClass.getMethod(getterName, null);
      if (subFields != null) {
        return new BeanMapper(method.getReturnType()).getGetterMethod(subFields);
      }
      return method;
    }
    catch (NoSuchMethodException e) {
      //There is not 'is' method for this field
    }
   
    return null;
  }
 
  /**
   * Returns setter from field name.
   */
  private Method getSetterMethod(String fieldName) {
   
    String mainFieldName = fieldName;
    String subFields = null;
    if (fieldName.indexOf(".") != -1) {
      mainFieldName = fieldName.substring(0, fieldName.indexOf("."));
      subFields = fieldName.substring(mainFieldName.length());
      return new BeanMapper(getBeanFieldType(mainFieldName)).getSetterMethod(subFields);
    }
   
    String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    try {
      return voClass.getMethod(setterName, new Class[] { getBeanFieldType(fieldName)});
    }
    catch (NoSuchMethodException e) {
      //There is not 'set' method for this field
    }
   
    return null;
  }
 
  /**
   * Returns whether the given object type is a Value Object type.
   * @param objectType object type.
   * @return whether the given object type is a Value Object type.
   */
  public static boolean isBean(Class objectType) {
    BeanMapper beanMapper = new BeanMapper(objectType);
    return beanMapper.getBeanFields().size() != 0;
  }
}
TOP

Related Classes of org.araneaframework.backend.util.BeanMapper

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.