All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sk.antons.jaul.pojo.Dumper Maven / Gradle / Ivy

/*
 * Copyright 2015 Anton Straka
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sk.antons.jaul.pojo;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Generates dump of POJO instance.
 * @author antons
 */
public class Dumper {

    public static Dumper instance() { return new Dumper(); }
    public String dump(Object value) { 
		if(value == null) return null;
        StringBuilder sb = new StringBuilder("instance of ").append(value.getClass()).append(" hash: ").append(value.hashCode()).append('\n');
        dump(sb, "", value, new ArrayList());
        return sb.toString();
    }


    private void dumpMedssage(StringBuilder sb, String path, String message) {
        sb.append(path).append(": ").append(message).append('\n');
    }
    
    private void dump(StringBuilder sb, String path, Object o, List stack) {
        if(o == null) {
            sb.append("null");
            return;
        }
		
		if(stack.contains(o)) return;
		stack.add(o);

        Class clazz = o.getClass();
        
        if(isSimpleClass(clazz)) {
            String s = o.toString();
            if(s != null) s = s.replace('\n', ' ');
            dumpMedssage(sb, path, s);
			stack.remove(stack.size()-1);
            return;
        }
        
        if(clazz.isArray()) {
            dumpArray(sb, path, clazz, o, stack);
			stack.remove(stack.size()-1);
            return;
        }
        
        if(Collection.class.isAssignableFrom(clazz)) {
            dumpCollection(sb, path, clazz, o, stack);
			stack.remove(stack.size()-1);
            return;
        }
        
        if(Map.class.isAssignableFrom(clazz)) {
            dumpMap(sb, path, clazz, o, stack);
			stack.remove(stack.size()-1);
            return;
        }

        dumpObject(sb, path, clazz, o, stack);
		stack.remove(stack.size()-1);
    }

    private boolean isSimpleClass(Class clazz) {
        if(clazz.equals(String.class)) return true;
        
        if(clazz.equals(int.class)) return true;
        if(clazz.equals(long.class)) return true;
        if(clazz.equals(byte.class)) return true;
        if(clazz.equals(short.class)) return true;
        if(clazz.equals(double.class)) return true;
        if(clazz.equals(float.class)) return true;
        if(clazz.equals(boolean.class)) return true;
        if(clazz.equals(char.class)) return true;
        
        if(clazz.equals(Integer.class)) return true;
        if(clazz.equals(Long.class)) return true;
        if(clazz.equals(Byte.class)) return true;
        if(clazz.equals(Short.class)) return true;
        if(clazz.equals(Double.class)) return true;
        if(clazz.equals(Float.class)) return true;
        if(clazz.equals(Boolean.class)) return true;
        if(clazz.equals(Character.class)) return true;
       
        if(clazz.isEnum()) return true;
        
        if(clazz.equals(LocalDateTime.class)) return true;
        if(clazz.equals(LocalDate.class)) return true;
        if(clazz.equals(Date.class)) return true;
        
        return false;
    }
    
    private void dumpArray(StringBuilder sb, String path, Class clazz, Object o, List stack) {
        if(clazz.isArray()) {
            int size = arraySize(clazz, o);
            dumpMedssage(sb, path+".size", ""+size);
            for(int i = 0; i < size; i++) {
                Object oo = arrayItem(clazz, o, i);
                dump(sb, path+"["+i+"]", oo, stack);
            }
        }
    }
    
    private void dumpCollection(StringBuilder sb, String path, Class clazz, Object o, List stack) {
        if(Collection.class.isAssignableFrom(clazz)) {
            Collection list = (Collection)o;
            int size = list.size();
            dumpMedssage(sb, path+".size", ""+size);
            int i = 0;
            Iterator iter = list.iterator();
            while(iter.hasNext()) {
                Object oo = iter.next();
                dump(sb, path+'['+i+']', oo, stack);
                i++;
            }
        }
    }
    
    
    private void dumpMap(StringBuilder sb, String path, Class clazz, Object o, List stack) {
        if(Map.class.isAssignableFrom(clazz)) {
            Map map = (Map)o;
            int size = map.size();
            dumpMedssage(sb, path+".size", ""+size);
            for(Object key : map.keySet()) {
                dump(sb, path+'['+key+']', map.get(key), stack);
            }
        }
    }
    private FieldCopmarator comp = FieldCopmarator.instance(); 
    private void dumpObject(StringBuilder sb, String path, Class clazz, Object o, List stack) {
        List fields = allFields(clazz);
        Collections.sort(fields, comp);
        if(fields == null) return;
        for(Field field : fields) {
            if(Modifier.isStatic(field.getModifiers())) continue;
            Object oo = value(clazz, o, field);
            if(oo == null) continue;
            dump(sb, path+'.'+field.getName(), oo, stack);
        }
        
    }

    private int arraySize(Class clazz, Object o) {
        return ((Object[])o).length;
    }

    private Object arrayItem(Class clazz, Object o, int index) {
        return Array.get(o, index);
    }


    private List allFields(Class clazz) {
        List list = new ArrayList();
        allFields(clazz, list);
        return list;
    }
    private void allFields(Class clazz, List list) {
        if(clazz == null) return;
        Field[] fields = clazz.getDeclaredFields();
        if(fields == null) return;
        for(Field field : fields) {
            list.add(field);
        }
        allFields(clazz.getSuperclass(), list);
    }
    private Field field(Class clazz, String name) {
        if(clazz == null) return null;
        Field field = null;
        try {
            field = clazz.getDeclaredField(name);
        } catch(Exception e) {
        }
        if(field != null) return field;
        return field(clazz.getSuperclass(), name);
    }
    private Object valueOld(Class clazz, Object object, Field field) {
        field.setAccessible(true);
        Object o = null;
        try {
            o = field.get(object);
        } catch(Exception e) {
        }
        return o;
    }
    private Object value(Class clazz, Object object, Field field) {
        Object o = null;
        boolean ok = false;
        try {
            String name = field.getName();
            String accessor = "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
            Method m = clazz.getMethod(accessor, new Class[]{});
            if(m != null) {
                o = m.invoke(object, new Object[]{});
                ok = true;
            }
        } catch(Exception e) {
        }
        if(ok) return o;
        try {
            String name = field.getName();
            String accessor = "is" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
            Method m = clazz.getMethod(accessor, new Class[]{});
            if(m != null) {
                o = m.invoke(object, new Object[]{});
                ok = true;
            }
        } catch(Exception e) {
        }
        return o;
    }

    private static class FieldCopmarator implements Comparator {

        @Override
        public int compare(Field o1, Field o2) {
            String name1 = null;
            String name2 = null;
            name1 = o1.getName();
            name2 = o2.getName();
            if(name1 == null) name1 = "";
            if(name2 == null) name2 = "";
            return name1.compareTo(name2);
        }

        public static FieldCopmarator instance() { return new FieldCopmarator(); }
    
    }

//    public static void main(String[] argv) {
//        Person p = Messer.instance().map(Address.class, CompleteAddress.class).junk(Person.class);
//        System.out.println(" -- " + p);
//    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy