/***************************************************************************** * * * This file is part of the tna framework distribution. * * Documentation and updates may be get from biaoping.yin the author of * * this framework * * * * Sun Public License Notice: * * * * The contents of this file are subject to the Sun Public License Version * * 1.0 (the "License"); you may not use this file except in compliance with * * the License. A copy of the License is available at http://www.sun.com * * * * The Original Code is tag. The Initial Developer of the Original * * Code is biaoping yin. Portions created by biaoping yin are Copyright * * (C) 2000. All Rights Reserved. * * * * GNU Public License Notice: * * * * Alternatively, the contents of this file may be used under the terms of * * the GNU Lesser General Public License (the "LGPL"), in which case the * * provisions of LGPL are applicable instead of those above. If you wish to * * allow use of your version of this file only under the terms of the LGPL * * and not to allow others to use your version of this file under the SPL, * * indicate your decision by deleting the provisions above and replace * * them with the notice and other provisions required by the LGPL. If you * * do not delete the provisions above, a recipient may use your version of * * this file under either the SPL or the LGPL. * * * * biaoping.yin (yin-bp@163.com) * * * *****************************************************************************/ package com.frameworkset.util; import java.beans.Introspector; import java.beans.PropertyChangeEvent; import java.beans.PropertyDescriptor; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import org.frameworkset.util.ClassUtil; import org.frameworkset.util.ClassUtil.ClassInfo; import org.frameworkset.util.ClassUtil.PropertieDescription; import org.frameworkset.util.beans.PropertyAccessException; /** * 实现对象之间属性值的复制功能,map与对象之间属性值的拷贝,hashTable/properties与对象之间属性值的拷贝 * @author biaoping.yin * @version 1.0 */ public class TransferObjectFactory { private static final Logger log = Logger.getLogger(TransferObjectFactory.class); /** * Use a HashMap to cache class information for * Transfer Object classes */ private static HashMap classDataInfo = new HashMap(); /** * Create a Transfer Object for the given object. The * given object must be an EJB Implementation and have * a superclass that acts as the class for the entity's * Transfer Object. Only the fields defined in this * superclass are copied in to the Transfer Object. */ public static Serializable createTransferObject( Object ejb, String whichTOType, String completeTOType) { try { // Get the class data for the complete // Transfer Object type ClassData cData = getClassData(completeTOType); // Get class data for the requested TO type ClassData voCData = getClassData(whichTOType); // Create the Transfer Object of the requested // Transfer Object type... Object whichTO = Class.forName(whichTOType).newInstance(); // get the TO fields for the requested TO // from the ClassData for the requested TO Field[] voFields = voCData.arrFields; // get all fields for the complete TO // from the ClassData for complete TO Field[] beanFields = cData.arrFields; if (voFields == null || voFields.length == 0 || beanFields == null || beanFields.length == 0) { return (Serializable) createTransferObject(ejb, whichTO); } // copy the common fields from the complete TO // to the fields of the requested TO for (int i = 0; i < voFields.length; i++) { try { String voFieldName = voFields[i].getName(); for (int j = 0; j < beanFields.length; j++) { // if the field names are same, copy value if (voFieldName.equals(beanFields[j].getName())) { // Copy value from matching field // from the bean instance into the new // Transfer Object created earlier voFields[i].set(whichTO, beanFields[j].get(ejb)); break; } } } catch (Exception e) { // handle exceptions that may be thrown // by the reflection methods... } } // return the requested Transfer Object return (java.io.Serializable) whichTO; } catch (Exception ex) { ex.printStackTrace(); // Handle all exceptions here... } return null; } // /** // * added by biaoping.yin 2005.8.13 // * 将map中包含的属性值复制到对象中,对应属性的名称和类型必须一致 // * @param completeVO 有属性值的map对象 // * @param whichToVO 空对象 // * @return Object // */ // public static Object createTransferObject( // Map completeVO, // Object whichToVO) // { // if (completeVO == null || whichToVO == null) // return null; // Method[] wMethods = whichToVO.getClass().getMethods(); // //Class cClazz = completeVO.getClass(); // if (wMethods == null || wMethods.length == 0) // { // return whichToVO; // } // for (int i = 0; i < wMethods.length; i++) // { // String wmName = wMethods[i].getName(); // if (!wmName.startsWith("set")) // { // continue; // } // String wmPrex = wmName.substring(0, 3); // String wfield = wmName.substring(3); // Object value = null; // //Method cMethod = null; // try // { // value = completeVO.get(wfield); //// cMethod = //// cClazz.getMethod( //// ValueObjectUtil.getMethodName(wfield), //// null); // if(value == null) // { // log.info( // new StringBuffer("warning:[") // .append(wfield) // .append(" not found in hashmap") // .append("]!") // .toString()); // continue; // } // Class retType = value.getClass(); // Class paramType = wMethods[i].getParameterTypes()[0]; // // if (retType == paramType) // { // ValueObjectUtil.invoke( // whichToVO, // wMethods[i], // new Object[] { // value}); // //wMethods[i].invoke(whichToVO,new Object[] {cMethod.invoke( // //completeVO, null)}); // } // else // { // try // { // Object obj = // ValueObjectUtil.typeCast( // value, // retType, // paramType); // ValueObjectUtil.invoke( // whichToVO, // wMethods[i], // new Object[] { obj }); // } // catch (NoSupportTypeCastException e) // { // throw e; // //System.out.println("warning ParamTypeNotMatchException:<" + cMethod + "><" + wMethods[i] + "> return value type not match the param type!" ); // } // //System.out.println("warning ParamTypeNotMatchException:<" + cMethod + "><" + wMethods[i] + "> return value type not match the param type!" ); // } // } // catch (NullPointerException e) // { // log.info( // new StringBuffer("warning NullPointerException:[") // .append(wfield) // .append("] not found in [map]!") // .toString()); // continue; // } // catch (NoSuchMethodException e) // { // log.info( // new StringBuffer("warning NoSuchMethodException:[") // .append(e.getMessage()) // .append("]") // .toString()); // //e.printStackTrace(); // continue; // } // catch (SecurityException securitye) // { // log.info( // new StringBuffer("warning SecurityException:[") // .append(securitye.getMessage()) // .append("]") // .toString()); // //securitye.printStackTrace(); // continue; // } // catch (NoSupportTypeCastException castException) // { // log.info( // new StringBuffer("warning NoSupportTypeCastException:[") // .append(wfield).append("][") // .append(wMethods[i]) // .append("] return value type not match the param type!") // .toString()); // continue; // } // catch (NumberFormatException e) // { // log.info( // new StringBuffer("warning NumberFormatException:[") // .append(e.getMessage()) // .append("]") // .toString()); // //e.printStackTrace(); // continue; // } // catch (IllegalArgumentException e) // { // log.info( // new StringBuffer("warning IllegalArgumentException:[") // .append(e.getMessage()) // .append("]") // .toString()); // //e.printStackTrace(); // continue; // } // catch (Exception e) // { // log.info( // new StringBuffer("warning Exception:[") // .append(e.getMessage()) // .append("]") // .toString()); // //e.printStackTrace(); // continue; // } // } // return whichToVO; // } /** * added by biaoping.yin 2005.8.13 * 将map中包含的属性值复制到对象中,对应属性的名称和类型必须一致 * @param completeVO 有属性值的map对象 * @param whichToVO 空对象 * @return Object */ public static Object createTransferObject( Map completeVO, Object whichToVO) { if (completeVO == null || whichToVO == null) return null; ClassInfo beanInfo = null; try { beanInfo = ClassUtil.getClassInfo(whichToVO.getClass()); } catch (Exception e) { throw new PropertyAccessException(new PropertyChangeEvent(whichToVO, "", null, null),"获取bean 信息失败",e); } List<PropertieDescription> attributes = beanInfo.getPropertyDescriptors(); Set keys = completeVO.entrySet(); Iterator keyItr = keys.iterator(); while(keyItr.hasNext()) { Map.Entry entry = (Map.Entry)keyItr.next(); String name = String.valueOf(entry.getKey()); Object pvalue = entry.getValue(); for(PropertieDescription property :attributes) { if(name.equals(property.getName())) { Class type = property.getPropertyType(); // Object pvalue = completeVO.get(name); Object value = null; Method writeMethod = property.getWriteMethod(); // if (editor == null) if(pvalue != null) { EditorInf editor = property.getWriteMethodEditor(); if(editor == null) value = ValueObjectUtil.typeCast(pvalue, pvalue .getClass(), type); else { value = ValueObjectUtil.typeCast(pvalue, editor); } } try { writeMethod.invoke(whichToVO, new Object[]{value}); break; } catch (IllegalArgumentException e) { throw new PropertyAccessException(new PropertyChangeEvent(whichToVO, name, null, value),"设置属性失败",e); } catch (IllegalAccessException e) { throw new PropertyAccessException(new PropertyChangeEvent(whichToVO, name, null, value),"设置属性失败",e); } catch (InvocationTargetException e) { throw new PropertyAccessException(new PropertyChangeEvent(whichToVO, name, null, value),"设置属性失败",e); } // else // { // value = pvalue; // // value = ValueObjectUtil.typeCast(pvalue, // // pro.getEditorInf()); // } } } } return whichToVO; } // public final static EditorInf getParamEditor(Method writeMethod) // { // if(writeMethod == null) // return null; // Annotation[] annotations = writeMethod.getAnnotations(); // if(annotations == null || annotations.length == 0) // return null; // for(Annotation annotation:annotations) // { // if(annotation instanceof RequestParam) // { // RequestParam param = (RequestParam)annotation; // String editor = param.editor(); // if(editor != null && !editor.equals("")) // { // return (EditorInf) BeanUtils.instantiateClass(editor); // } // } // } // return null; // } /** * added by biaoping.yin 2005.8.13 * 将Hashtable中包含的属性值复制到对象中,对应属性的名称和类型必须一致 * @param completeVO 有属性值的Hashtable对象 * @param whichToVO 空对象 * @return Object */ public static Object createTransferObject( Hashtable completeVO, Object whichToVO) { if (completeVO == null || whichToVO == null) return null; Method[] wMethods = whichToVO.getClass().getMethods(); //Class cClazz = completeVO.getClass(); if (wMethods == null || wMethods.length == 0) { return whichToVO; } for (int i = 0; i < wMethods.length; i++) { String wmName = wMethods[i].getName(); if (!wmName.startsWith("set")) { continue; } String wmPrex = wmName.substring(0, 3); String wfield = wmName.substring(3); Object value = null; //Method cMethod = null; try { value = completeVO.get(wfield); // cMethod = // cClazz.getMethod( // ValueObjectUtil.getMethodName(wfield), // null); if(value == null) { log.info( new StringBuffer("warning:[") .append(wfield) .append(" not found in hashmap") .append("]!") .toString()); continue; } Class retType = value.getClass(); Class paramType = wMethods[i].getParameterTypes()[0]; if (retType == paramType) { ValueObjectUtil.invoke( whichToVO, wMethods[i], new Object[] { value}); //wMethods[i].invoke(whichToVO,new Object[] {cMethod.invoke( //completeVO, null)}); } else { try { Object obj = ValueObjectUtil.typeCast( value, retType, paramType); ValueObjectUtil.invoke( whichToVO, wMethods[i], new Object[] { obj }); } catch (NoSupportTypeCastException e) { throw e; //System.out.println("warning ParamTypeNotMatchException:<" + cMethod + "><" + wMethods[i] + "> return value type not match the param type!" ); } //System.out.println("warning ParamTypeNotMatchException:<" + cMethod + "><" + wMethods[i] + "> return value type not match the param type!" ); } } catch (NullPointerException e) { log.info( new StringBuffer("warning NullPointerException:[") .append(wfield) .append("] not found in [map]!") .toString()); continue; } catch (NoSuchMethodException e) { log.info( new StringBuffer("warning NoSuchMethodException:[") .append(e.getMessage()) .append("]") .toString()); //e.printStackTrace(); continue; } catch (SecurityException securitye) { log.info( new StringBuffer("warning SecurityException:[") .append(securitye.getMessage()) .append("]") .toString()); //securitye.printStackTrace(); continue; } catch (NoSupportTypeCastException castException) { log.info( new StringBuffer("warning NoSupportTypeCastException:[") .append(wfield).append("][") .append(wMethods[i]) .append("] return value type not match the param type!") .toString()); continue; } catch (NumberFormatException e) { log.info( new StringBuffer("warning NumberFormatException:[") .append(e.getMessage()) .append("]") .toString()); //e.printStackTrace(); continue; } catch (IllegalArgumentException e) { log.info( new StringBuffer("warning IllegalArgumentException:[") .append(e.getMessage()) .append("]") .toString()); //e.printStackTrace(); continue; } catch (Exception e) { log.info( new StringBuffer("warning Exception:[") .append(e.getMessage()) .append("]") .toString()); //e.printStackTrace(); continue; } } return whichToVO; } /** * added by biaoping.yin 2004.5.20 * 将一个对象属性复制到另一个对象中,对应属性的名称和类型必须一致 * @param completeVO 有属性值的对象 * @param whichToVO 空对象 * @return Object */ public static Object createTransferObject( Object completeVO, Object whichToVO) { if (completeVO == null || whichToVO == null) return null; Method[] wMethods = whichToVO.getClass().getMethods(); Class cClazz = completeVO.getClass(); if (wMethods == null || wMethods.length == 0) { return whichToVO; } for (int i = 0; i < wMethods.length; i++) { String wmName = wMethods[i].getName(); if (!wmName.startsWith("set")) { continue; } String wmPrex = wmName.substring(0, 3); String wfield = wmName.substring(3); Method cMethod = null; try { try { cMethod = cClazz.getMethod(ValueObjectUtil .getMethodName(wfield), null); } catch (Exception e) { // TODO: handle exception } if(cMethod == null) { try { cMethod = cClazz.getMethod(ValueObjectUtil .getBooleanMethodName(wfield), null); if(cMethod == null) { log.info( new StringBuffer("warning:[") .append(wMethods[i]) .append("]") .append(ValueObjectUtil.getMethodName(wfield)) .append(" not found in [") .append(cClazz) .append("]!") .toString()); continue; } } catch (Exception e) { log.info( new StringBuffer("warning:[") .append(wMethods[i]) .append("]") .append(ValueObjectUtil.getMethodName(wfield)) .append(" not found in [") .append(cClazz) .append("]!") .toString()); continue; } } Class retType = cMethod.getReturnType(); Class paramType = wMethods[i].getParameterTypes()[0]; if (retType == paramType) { ValueObjectUtil.invoke( whichToVO, wMethods[i], new Object[] { ValueObjectUtil.invoke( completeVO, cMethod, null)}); //wMethods[i].invoke(whichToVO,new Object[] {cMethod.invoke( //completeVO, null)}); } else { try { Object obj = ValueObjectUtil.typeCast( ValueObjectUtil.invoke( completeVO, cMethod, null), retType, paramType); ValueObjectUtil.invoke( whichToVO, wMethods[i], new Object[] { obj }); } catch (NoSupportTypeCastException e) { throw e; //System.out.println("warning ParamTypeNotMatchException:<" + cMethod + "><" + wMethods[i] + "> return value type not match the param type!" ); } //System.out.println("warning ParamTypeNotMatchException:<" + cMethod + "><" + wMethods[i] + "> return value type not match the param type!" ); } } catch (NullPointerException e) { log.info( new StringBuffer("warning NullPointerException:[") .append(wMethods[i]) .append("] not found in [") .append(cClazz) .append("]!") .toString()); continue; } catch (NoSuchMethodException e) { log.info( new StringBuffer("warning NoSuchMethodException:[") .append(e.getMessage()) .append("]") .toString()); //e.printStackTrace(); continue; } catch (SecurityException securitye) { log.info( new StringBuffer("warning SecurityException:[") .append(securitye.getMessage()) .append("]") .toString()); //securitye.printStackTrace(); continue; } catch (NoSupportTypeCastException castException) { log.info( new StringBuffer("warning NoSupportTypeCastException:[") .append(cMethod).append("][") .append(wMethods[i]) .append("] return value type not match the param type!"+ castException.getMessage()) .toString(),castException); continue; } catch (NumberFormatException e) { log.info( new StringBuffer("warning NumberFormatException:[") .append(e.getMessage()) .append("]") .toString()); //e.printStackTrace(); continue; } catch (IllegalArgumentException e) { log.info( new StringBuffer("warning IllegalArgumentException:[") .append(e.getMessage()) .append("]") .toString()); //e.printStackTrace(); continue; } catch (Exception e) { log.info( new StringBuffer("warning Exception:[") .append(e.getMessage()) .append("]") .toString()); //e.printStackTrace(); continue; } } return whichToVO; } /** * Return a ClassData object that contains the * information needed to create * a Transfer Object for the given class. This information * is only obtained from the * class using reflection once, after that it will be * obtained from the classDataInfo HashMap. */ private static ClassData getClassData(String className) { ClassData cData = (ClassData) classDataInfo.get(className); try { if (cData == null) { // Get the class of the given object and the // Transfer Object to be created Field[] arrFields; Class ejbTOClass = Class.forName(className); // Determine the fields that must be copied arrFields = ejbTOClass.getFields(); cData = new ClassData( ejbTOClass, arrFields, ejbTOClass.getMethods()); classDataInfo.put(className, cData); } } catch (Exception e) { // handle exceptions here... } return cData; } public static void main(String[] args) { //Logger log = Logger.getLogger(TransferObjectFactory.class); log.debug("debug:aaaaa"); log.info("info:bbbbbbb"); log.warn("warn:bbbbbbb"); log.error("error:bbbbbbb"); } } /** * Inner Class that contains class data for the * Transfer Object classes */ class ClassData { // Transfer Object Class public Class clsTransferObject; // Transfer Object fields public Field[] arrFields; //Transfer Object methods public Method[] arrMethods; // Constructor public ClassData(Class cls, Field[] fields, Method[] methods) { clsTransferObject = cls; arrFields = fields; arrMethods = methods; } }