001package gudusoft.gsqlparser.dlineage.util; 002 003import gudusoft.gsqlparser.util.json.JSONException; 004import gudusoft.gsqlparser.util.json.JSONField; 005 006import java.beans.IntrospectionException; 007import java.beans.Introspector; 008import java.beans.PropertyDescriptor; 009import java.lang.reflect.Field; 010import java.util.*; 011 012@SuppressWarnings("rawtypes") 013public abstract class BeanUtil { 014 015 private static final Map<String, PropertyDescriptor[]> cacheDescriptors = new WeakHashMap<>(); 016 017 @SuppressWarnings("unchecked") 018 public static LinkedHashMap<String, Object> bean2Map(Object src) { 019 if (src instanceof LinkedHashMap) { 020 return (LinkedHashMap<String, Object>) src; 021 } 022 if (src instanceof Map) { 023 return new LinkedHashMap<>((Map) src); 024 } 025 026 try { 027 LinkedHashMap<String, Object> resultMap = new LinkedHashMap<>(); 028 String typeName = src.getClass().getCanonicalName(); 029 if (!cacheDescriptors.containsKey(typeName)) { 030 Map<String, Integer> fieldOrder = buildFieldOrder(src.getClass()); 031 PropertyDescriptor[] allDescriptors = Introspector.getBeanInfo(src.getClass()).getPropertyDescriptors(); 032 List<PropertyDescriptor> validDescriptors = new ArrayList<>(); 033 for (PropertyDescriptor pd : allDescriptors) { 034 if (!"class".equals(pd.getName()) && pd.getReadMethod() != null) { 035 validDescriptors.add(pd); 036 } 037 } 038 validDescriptors.sort(new Comparator<PropertyDescriptor>() { 039 @Override 040 public int compare(PropertyDescriptor o1, PropertyDescriptor o2) { 041 return compareOrder(fieldOrder, o1.getName(), o2.getName()); 042 } 043 }); 044 cacheDescriptors.put(typeName, validDescriptors.toArray(new PropertyDescriptor[0])); 045 } 046 047 for (PropertyDescriptor pd : cacheDescriptors.get(typeName)) { 048 try { 049 JSONField jsonField = pd.getReadMethod().getAnnotation(JSONField.class); 050 if (jsonField != null && !jsonField.serialize()) { 051 continue; 052 } 053 Object value = pd.getReadMethod().invoke(src); 054 if (value == null) { 055 continue; 056 } 057 if (value instanceof Collection) { 058 List<Object> listValues = new ArrayList<>(); 059 for (Object item : (Collection) value) { 060 if (item instanceof String) { 061 listValues.add(item); 062 } else { 063 listValues.add(bean2Map(item)); 064 } 065 } 066 resultMap.put(pd.getName(), listValues); 067 } else if (value.getClass().isMemberClass()) { 068 resultMap.put(pd.getName(), bean2Map(value)); 069 } else { 070 resultMap.put(pd.getName(), value); 071 } 072 } catch (Exception ex) { 073 throw new JSONException(ex); 074 } 075 } 076 return resultMap; 077 } catch (IntrospectionException e) { 078 throw new JSONException(e); 079 } 080 } 081 082 private static Map<String, Integer> buildFieldOrder(Class target) { 083 Map<String, Integer> orderMap = new HashMap<>(); 084 for (Field f : target.getDeclaredFields()) { 085 orderMap.put(f.getName(), orderMap.size()); 086 } 087 return orderMap; 088 } 089 090 private static int compareOrder(Map<String, Integer> orderMap, String n1, String n2) { 091 if (orderMap.containsKey(n1) && orderMap.containsKey(n2)) { 092 return orderMap.get(n1).compareTo(orderMap.get(n2)); 093 } 094 return 0; 095 } 096}