Java tutorial
/****************************************************************************** * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is: Jsoda * The Initial Developer of the Original Code is: William Wong (williamw520@gmail.com) * Portions created by William Wong are Copyright (C) 2012 William Wong, All Rights Reserved. * ******************************************************************************/ package wwutil.sys; import java.util.*; import java.lang.annotation.*; import java.lang.reflect.*; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.lang.builder.ToStringStyle; import org.apache.commons.lang.builder.ReflectionToStringBuilder; @SuppressWarnings("unchecked") public class ReflectUtil { private ReflectUtil() { // disable } /** Return the list of fields declared at all level of class hierachy, include super private fields. */ public static List<Field> getAllFields(Class clazz) { return getAllFields(clazz, new ArrayList<Field>()); } private static List<Field> getAllFields(Class clazz, List<Field> list) { for (Field field : clazz.getDeclaredFields()) { // Filter out compiler synthesized fields and static fields. if (!field.isSynthetic() && !Modifier.isStatic(field.getModifiers())) list.add(field); } Class superClazz = clazz.getSuperclass(); if (superClazz != null) getAllFields(superClazz, list); return list; } public static List<Method> getAllMethods(Class clazz) { return getAllMethods(clazz, new ArrayList<Method>()); } public static List<Method> getAllMethods(Class clazz, List<Method> list) { for (Method method : clazz.getDeclaredMethods()) { if (!method.isSynthetic() && !Modifier.isStatic(method.getModifiers())) list.add(method); } Class superClazz = clazz.getSuperclass(); if (superClazz != null) getAllMethods(superClazz, list); return list; } public static List<Class> getAllInterfaces(Class clazz) { return getAllInterfaces(clazz, new ArrayList<Class>()); } private static List<Class> getAllInterfaces(Class clazz, List<Class> list) { for (Class intf : clazz.getInterfaces()) { list.add(intf); } Class superClazz = clazz.getSuperclass(); if (superClazz != null) getAllInterfaces(superClazz, list); return list; } public static String[] getFieldNames(Class clazz) { List<Field> fields = getAllFields(clazz); String[] names = new String[fields.size()]; for (int i = 0; i < fields.size(); i++) { try { names[i] = fields.get(i).getName(); } catch (Exception ignored) { } } return names; } public static Map<String, Field> getFieldMap(Class clazz) { List<Field> fields = getAllFields(clazz); Map<String, Field> map = new HashMap<String, Field>(); for (Field field : fields) { try { map.put(field.getName(), field); } catch (Exception ignored) { } } return map; } /** Get the parameterized type of a generic type GenericType<ParameterizedType> * For method, call method.getGenericParameterTypes() or method.getGenericReturnType() for the parameterizedType. * For field, call field.getGenericType() for the parameterizedType. * e.g. List<String> field1 ==> getGenericParamType1(field11.getGenericType()) => String * Return null for none found. */ public static Class getGenericParamType1(Type parameterizedType) { if (parameterizedType instanceof ParameterizedType) { ParameterizedType type = (ParameterizedType) parameterizedType; Type[] typeArguments = type.getActualTypeArguments(); if (typeArguments.length > 0) return (Class) typeArguments[0]; } return null; } public static Map<String, Object> objToMap(Object obj) { Map<String, Object> map = new HashMap<String, Object>(); for (Field field : getAllFields(obj.getClass())) { try { map.put(field.getName(), field.get(obj)); } catch (Exception ignored) { } } return map; } public static String mapToStr(Map<String, ?> map) { StringBuilder sb = new StringBuilder(); boolean isFirst = true; sb.append("{"); for (Map.Entry<String, ?> entry : map.entrySet()) { if (isFirst) isFirst = false; else sb.append(","); String valueStr = "" + entry.getValue(); sb.append(entry.getKey()).append("=").append(valueStr); } sb.append("}"); return sb.toString(); } public static String dumpObj(Object obj) { if (obj == null) return "null"; return ReflectionToStringBuilder.toString(obj, MyStyle.instance); } public static String dumpToStr(Object obj) { if (obj == null) return "null"; Map<String, Object> map = objToMap(obj); return mapToStr(map); } public static String dumpToStr(List list, String delimiter) { if (list == null) return ""; StringBuilder sb = new StringBuilder(); for (Object obj : list) { if (sb.length() > 0) sb.append(delimiter); sb.append(obj); } return sb.toString(); } public static Object run(Object obj, String methodName, Object[] params) throws Exception { Class[] prototypeParams = null; if (params != null) { prototypeParams = new Class[params.length]; for (int i = 0; i < params.length; i++) { prototypeParams[i] = params[i].getClass(); } } Method method = obj.getClass().getMethod(methodName, prototypeParams); if (method == null) return null; return method.invoke(obj, params); } public static Object run(Object obj, String methodName) throws Exception { return run(obj, methodName, null); } public static Object run(Object obj, String methodName, Object param1) throws Exception { return run(obj, methodName, new Object[] { param1 }); } public static Object run(Object obj, String methodName, Object param1, Object param2) throws Exception { return run(obj, methodName, new Object[] { param1, param2 }); } public static Object run(Object obj, String methodName, Object param1, Object param2, Object param3) throws Exception { return run(obj, methodName, new Object[] { param1, param2, param3 }); } public static Object getFieldValue(Object entity, String fieldName) throws Exception { Field field = entity.getClass().getField(fieldName); if (field != null) return field.get(entity); return null; } /** Convert str value to Object */ public static Object strToObj(String valueStr, Class valueType) { return ConvertUtils.convert(valueStr, valueType); } /** Initialize the fields of an object with the value object * Use with MapUtil.toMap() for initializing an object. * e.g. setFieldStrs(obj, MapUtil.toMap("field1", 123, "field2", 234, "myfield3", new Date() )); */ public static <T> T initObj(T obj, Map<String, Object> fieldValues) throws Exception { if (obj != null && fieldValues != null) { for (Field field : getAllFields(obj.getClass())) { field.set(obj, fieldValues.get(field.getName())); } } return obj; } /** Initialize the fields of an object with the value object, converted from string. * Use with MapUtil.toMap() for initializing an object. */ public static <T> T initObjStrs(T obj, Map<String, String> fieldStrValues) throws Exception { if (obj != null && fieldStrValues != null) { for (Field field : getAllFields(obj.getClass())) { Object value = ConvertUtils.convert(fieldStrValues.get(field.getName()), field.getType()); field.set(obj, value); } } return obj; } public static boolean hasAnnotation(Class objClass, Class annClass) { return (objClass.getAnnotation(annClass) != null); } public static boolean hasAnnotation(Field field, Class annClass) { return (field.getAnnotation(annClass) != null); } public static boolean hasAnnotation(Method method, Class annClass) { return (method.getAnnotation(annClass) != null); } public static String getAnnoValue(Annotation annObj, String valueMethod, String defaultValue) { try { if (annObj != null) return (String) ReflectUtil.run(annObj, valueMethod); } catch (Exception ignored) { } return defaultValue; } public static int getAnnoValue(Annotation annObj, String valueMethod, int defaultValue) { try { if (annObj != null) return (int) (Integer) ReflectUtil.run(annObj, valueMethod); } catch (Exception ignored) { } return defaultValue; } public static char getAnnoValue(Annotation annObj, String valueMethod, char defaultValue) { try { if (annObj != null) return (char) (Character) ReflectUtil.run(annObj, valueMethod); } catch (Exception ignored) { } return defaultValue; } public static boolean getAnnoValue(Annotation annObj, String valueMethod, boolean defaultValue) { try { if (annObj != null) return (boolean) (Boolean) ReflectUtil.run(annObj, valueMethod); } catch (Exception ignored) { } return defaultValue; } public static Object getAnnoValue(Annotation annObj, String valueMethod, Object defaultValue) { try { if (annObj != null) return ReflectUtil.run(annObj, valueMethod); } catch (Exception ignored) { } return defaultValue; } /** Get the value of a class annotation via its method. * e.g. getAnnotationValue(clazz, EPlacemark.class, "latitude", String.class, (String)null); */ public static <T> T getAnnotationValue(Class objClass, Class annClass, String valueMethod, Class<T> valueClass, T defaultValue) throws Exception { Object annObj = objClass.getAnnotation(annClass); if (annObj != null) return (T) ReflectUtil.run(annObj, valueMethod); else return defaultValue; } /** Get the value of a class annotation via its method. Use defaultValue for all exceptions. * e.g. getAnnotationValueEx(clazz, EPlacemark.class, "latitude", Double.class, (Double)0.0); */ public static <T> T getAnnotationValueEx(Class objClass, Class annClass, String valueMethod, Class<T> valueClass, T defaultValue) { try { Object annObj = objClass.getAnnotation(annClass); if (annObj != null) return (T) ReflectUtil.run(annObj, valueMethod); } catch (Exception ignored) { } return defaultValue; } /** Get the String value of a class annotation via its method. Return default if value is "" or null. * e.g. getAnnotationValue(clazz, Table.class, "name", "abc"); */ public static String getAnnotationValue(Class objClass, Class annClass, String valueMethod, String defaultValue) { String value = getAnnotationValueEx(objClass, annClass, valueMethod, String.class, defaultValue); return (value == null || value.length() == 0) ? defaultValue : value; } /** Get the value of a field annotation via its method. * e.g. getAnnotationValue(field, Column.class, "name", String.class, (String)null); */ public static <T> T getAnnotationValue(Field field, Class annClass, String valueMethod, Class<T> valueClass, T defaultValue) throws Exception { Object annObj = field.getAnnotation(annClass); if (annObj != null) return (T) ReflectUtil.run(annObj, valueMethod); else return defaultValue; } /** Get the value of a field annotation via its method. Use defaultValue for all exceptions. * e.g. getAnnotationValue(field, Column.class, "name", String.class, (String)null); */ public static <T> T getAnnotationValueEx(Field field, Class annClass, String valueMethod, Class<T> valueClass, T defaultValue) { try { Object annObj = field.getAnnotation(annClass); if (annObj != null) return (T) ReflectUtil.run(annObj, valueMethod); } catch (Exception ignored) { } return defaultValue; } /** Get the String value of a field annotation via its method. Return default if value is "" or null. * e.g. getAnnotationValue(field, Column.class, "name", "abc"); */ public static String getAnnotationValue(Field field, Class annClass, String valueMethod, String defaultValue) { String value = getAnnotationValueEx(field, annClass, valueMethod, String.class, defaultValue); return (value == null || value.length() == 0) ? defaultValue : value; } /** Find the field of the class having the annotation defined on it. */ public static Field findAnnotatedField(Class clazz, Class fieldAnnClass) { for (Field field : clazz.getFields()) { Object annObj = field.getAnnotation(fieldAnnClass); if (annObj != null) return field; } return null; } public static void incrementField(Object dataObj, Field field, int incrementAmount) throws Exception { if (field.getType() == Integer.class || field.getType() == int.class) { Integer value = (Integer) field.get(dataObj); value = value == null ? new Integer(1) : new Integer(value.intValue() + 1); field.set(dataObj, value); } else if (field.getType() == Long.class || field.getType() == long.class) { Long value = (Long) field.get(dataObj); value = value == null ? new Long(1) : new Long(value.longValue() + 1); field.set(dataObj, value); } else { throw new IllegalArgumentException("Cannot increment non-integer field " + field); } } static class MyStyle extends ToStringStyle { final static ToStringStyle instance = new MyStyle(); public MyStyle() { setArrayContentDetail(true); setUseShortClassName(true); setUseClassName(false); setUseIdentityHashCode(false); setFieldSeparator(", "); } @Override public void appendDetail(StringBuffer buffer, String fieldName, Object value) { if (!value.getClass().getName().startsWith("java")) { buffer.append(ReflectionToStringBuilder.toString(value, instance)); } else { super.appendDetail(buffer, fieldName, value); } } @Override public void appendDetail(StringBuffer buffer, String fieldName, Collection value) { appendDetail(buffer, fieldName, value.toArray()); } } }