/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ package com.db4o.internal; import java.lang.reflect.*; import com.db4o.foundation.*; /** * @exclude * * Use the methods in this class for system classes only, since they * are not ClassLoader or Reflector-aware. * * TODO: this class should go to foundation.reflect, along with ReflectException and ReflectPlatform */ public class Reflection4 { public static Object invokeStatic(Class clazz, String methodName) { return invoke(clazz, methodName, null, null, null); } public static Object invoke (Object obj, String methodName) throws ReflectException { return invoke(obj.getClass(), methodName, null, null, obj ); } public static Object invoke (Object obj, String methodName, Object[] params) throws ReflectException { Class[] paramClasses = new Class[params.length]; for (int i = 0; i < params.length; i++) { paramClasses[i] = params[i].getClass(); } return invoke(obj.getClass(), methodName, paramClasses, params, obj ); } public static Object invoke (Object obj, String methodName, Class[] paramClasses, Object[] params) throws ReflectException { return invoke(obj.getClass(), methodName, paramClasses, params, obj ); } public static Object invoke (Class clazz, String methodName, Class[] paramClasses, Object[] params) throws ReflectException { return invoke(clazz, methodName, paramClasses, params, null); } private static Object invoke(Class clazz, String methodName, Class[] paramClasses, Object[] params, Object onObject) { return invoke(params, onObject, getMethod(clazz, methodName, paramClasses)); } public static Object invoke(String className, String methodName, Class[] paramClasses, Object[] params, Object onObject) throws ReflectException { Method method = getMethod(className, methodName, paramClasses); return invoke(params, onObject, method); } public static Object invoke(Object[] params, Object onObject, Method method) throws ReflectException { if(method == null) { return null; } Platform4.setAccessible(method); try { return method.invoke(onObject, params); } catch (InvocationTargetException e) { throw new ReflectException(e.getTargetException()); } catch (IllegalArgumentException e) { throw new ReflectException(e); } catch (IllegalAccessException e) { throw new ReflectException(e); } } /** * calling this method "method" will break C# conversion with the old converter */ public static Method getMethod(String className, String methodName, Class[] paramClasses) { Class clazz = ReflectPlatform.forName(className); if (clazz == null) { return null; } return getMethod(clazz, methodName, paramClasses); } public static Method getMethod(Class clazz, String methodName, Class[] paramClasses) { Class curclazz=clazz; while(curclazz!=null) { try { return curclazz.getDeclaredMethod(methodName, paramClasses); } catch (Exception e) { } curclazz=curclazz.getSuperclass(); } return null; } public static Object invoke(final Object obj, String methodName, Class signature, Object value) throws ReflectException { return invoke(obj, methodName, new Class[] { signature }, new Object[] { value }); } public static Field getField(final Class clazz,final String name) { Class curclazz=clazz; while(curclazz!=null) { try { Field field=curclazz.getDeclaredField(name); Platform4.setAccessible(field); if(field != null){ return field; } } catch (Exception e) { } curclazz=curclazz.getSuperclass(); } return null; } public static Object getFieldValue(final Object obj, final String fieldName) throws ReflectException { try { return getField(obj.getClass(), fieldName).get(obj); } catch (Exception e) { throw new ReflectException(e); } } public static Object newInstance(Object template) { try { return template.getClass().newInstance(); } catch (Exception e) { throw new ReflectException(e); } } public static String dump(Object obj){ return dumpPreventRecursion(obj, new IdentitySet4(), 2); } private static String dumpPreventRecursion(Object obj, IdentitySet4 dumped, int stackLimit) { stackLimit--; if(obj == null){ return "null"; } Class clazz = obj.getClass(); if(Platform4.isSimple(clazz)){ return obj.toString(); } StringBuffer sb = new StringBuffer(); sb.append(clazz.getName()); sb.append(" ("); sb.append(System.identityHashCode(obj)); sb.append(")"); if(dumped.contains(obj) || stackLimit <= 0){ return sb.toString(); } dumped.add(obj); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { Platform4.setAccessible(field); try { if( field.get(null) == field.get(obj) ){ continue; // static field.getModifiers() wouldn't sharpen } } catch (Exception e) { } sb.append("\n"); sb.append("\t"); sb.append(field.getName()); sb.append(": "); try { sb.append(dumpPreventRecursion(field.get(obj), dumped, stackLimit)); } catch (Exception e) { sb.append("Exception caught: "); sb.append(e); } } return sb.toString(); } }