001package gudusoft.gsqlparser.dlineage.util;
002
003import java.beans.IntrospectionException;
004import java.beans.Introspector;
005import java.beans.PropertyDescriptor;
006import java.lang.reflect.Field;
007import java.util.ArrayList;
008import java.util.Collection;
009import java.util.Collections;
010import java.util.Comparator;
011import java.util.HashMap;
012import java.util.LinkedHashMap;
013import java.util.List;
014import java.util.Map;
015import java.util.WeakHashMap;
016
017import gudusoft.gsqlparser.util.json.JSONException;
018import gudusoft.gsqlparser.util.json.JSONField;
019
020@SuppressWarnings("rawtypes")
021public abstract class BeanUtil {
022
023        private static final Map<String, PropertyDescriptor[]> classPropertyDescriptorMap = new WeakHashMap<String, PropertyDescriptor[]>();
024
025        @SuppressWarnings("unchecked")
026        public static LinkedHashMap<String, Object> bean2Map(Object sourceBean) {
027                if (sourceBean instanceof LinkedHashMap) {
028                        return (LinkedHashMap<String, Object>) sourceBean;
029                }
030                else if (sourceBean instanceof Map) {
031                        return new LinkedHashMap<String, Object>((Map) sourceBean);
032                }
033
034                try {
035                        LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
036                        String className = sourceBean.getClass().getCanonicalName();
037                        if (!classPropertyDescriptorMap.containsKey(className)) {
038                                final Map<String, Integer> sortMap = sortFieldsMap(sourceBean.getClass());
039                                PropertyDescriptor[] descriptors = Introspector.getBeanInfo(sourceBean.getClass())
040                                                .getPropertyDescriptors();
041                                List<PropertyDescriptor> filterDescriptors = new ArrayList<PropertyDescriptor>();
042                                for (int i = 0; i < descriptors.length; i++) {
043                                        PropertyDescriptor descriptor = descriptors[i];
044                                        if (!descriptor.getName().equals("class") && descriptor.getReadMethod() != null) {
045                                                filterDescriptors.add(descriptor);
046                                        }
047                                }
048
049                                Collections.sort(filterDescriptors, new Comparator<PropertyDescriptor>() {
050                                        public int compare(PropertyDescriptor d1, PropertyDescriptor d2) {
051                                                return sort(sortMap, d1.getName(), d2.getName());
052                                        }
053                                });
054                                classPropertyDescriptorMap.put(className, filterDescriptors.toArray(new PropertyDescriptor[0]));
055                        }
056
057                        PropertyDescriptor[] descriptors = classPropertyDescriptorMap.get(className);
058                        for (PropertyDescriptor descriptor : descriptors) {
059                                try {
060                                        JSONField field = descriptor.getReadMethod().getAnnotation(JSONField.class);
061                                        if (field != null && !field.serialize()) {
062                                                continue;
063                                        }
064                                        Object tempObj = descriptor.getReadMethod().invoke(sourceBean);
065                                        if (tempObj == null)
066                                                continue;
067                                        if (tempObj instanceof Collection) {
068                                                List maps = new ArrayList();
069                                                Collection collection = (Collection) tempObj;
070                                                for (Object obj : collection) {
071                                                        if(obj instanceof String){
072                                                                maps.add(obj);
073                                                        }
074                                                        else{
075                                                                maps.add(bean2Map(obj));
076                                                        }
077                                                }
078                                                map.put(descriptor.getName(), maps);
079                                        } else if (tempObj.getClass().isMemberClass())
080                                                map.put(descriptor.getName(), bean2Map(tempObj));
081                                        else
082                                                map.put(descriptor.getName(), tempObj);
083                                } catch (Exception e) {
084                                        throw new JSONException(e);
085                                }
086                        }
087                        return map;
088                } catch (IntrospectionException e) {
089                        throw new JSONException(e);
090                }
091        }
092
093        private static Map<String, Integer> sortFieldsMap(Class targetClass) {
094                Map<String, Integer> sortMap = new HashMap<String, Integer>();
095                Field[] fields = targetClass.getDeclaredFields();
096                for (int i = 0; i < fields.length; i++) {
097                        Field field = fields[i];
098                        sortMap.put(field.getName(), sortMap.size());
099                }
100                return sortMap;
101        }
102
103        private static int sort(Map<String, Integer> sortMap, String firstName, String secondName) {
104                if (sortMap.containsKey(firstName) && sortMap.containsKey(secondName))
105                        return sortMap.get(firstName).compareTo(sortMap.get(secondName));
106                return 0;
107        }
108}