DeepCompare.java :  » Database-DBMS » db4o-6.4 » com » db4o » test » Java Open Source

Java Open Source » Database DBMS » db4o 6.4 
db4o 6.4 » com » db4o » test » DeepCompare.java
/* Copyright (C) 2004 - 2007  db4objects Inc.  http://www.db4o.com

This file is part of the db4o open source object database.

db4o is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published
by the Free Software Foundation and as clarified by db4objects' GPL 
interpretation policy, available at
http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
Suite 350, San Mateo, CA 94403, USA.

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, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */
package com.db4o.test;
/*
 * Author: Carl Rosenberger
 * 
 * You may use this code in any way you wish, as
 * long as you don't remove the following notice:
 * 
 * Code written for:
 * http://www.db4o.com
 * http://sourceforge.net/projects/sodaquery
 */
import java.lang.reflect.*;
import java.util.*;

import com.db4o.internal.*;

public class DeepCompare {

    public boolean isEqual(Object a_compare, Object a_with) {
        return isEqual(a_compare, a_with, null, null);
    }

    public boolean isEqual(Object a_compare, Object a_with, String a_path, Stack a_stack) {
        if (a_path == null || a_path.length() < 1) {
            if (a_compare != null) {
                a_path = a_compare.getClass().getName() + ":";
            } else {
                if (a_with != null) {
                    a_path = a_with.getClass().getName() + ":";
                }
            }
        }

        String path = a_path;

        if (a_compare == null) {
            return a_with == null;
        }
        if (a_with == null) {
            return false;
        }
        Class clazz = a_compare.getClass();
        if (clazz != a_with.getClass()) {
            return false;
        }

        if (isSimple(clazz)) {
            return a_compare.equals(a_with);
        }

        if (a_stack == null) {
            a_stack = new Stack();
        }

        // takes care of repeating calls to the same object
        if (a_stack.contains(a_compare)) {
            return true;
        }
        a_stack.push(a_compare);

        Field fields[] = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            if (storeableField(clazz, fields[i])) {
                Platform4.setAccessible(fields[i]);
                try {
                    path = a_path + fields[i].getName() + ":";
                    Object compare = fields[i].get(a_compare);
                    Object with = fields[i].get(a_with);
                    if (compare == null) {
                        if (with != null) {
                            return false;
                        }
                    } else if (with == null) {
                        return false;
                    } else {
                        if (compare.getClass().isArray()) {
                            if (!with.getClass().isArray()) {
                                return false;
                            } else {
                                compare = normalizeNArray(compare);
                                with = normalizeNArray(with);
                                int len = Array.getLength(compare);
                                if (len != Array.getLength(with)) {
                                    return false;
                                } else {
                                    for (int j = 0; j < len; j++) {
                                        Object elementCompare = Array.get(compare, j);
                                        Object elementWith = Array.get(with, j);
                                        //                    if (l_persistentArray)
                                        if (!isEqual(elementCompare, elementWith, path, a_stack)) {
                                            return false;
                                        } else if (elementCompare == null) {
                                            if (elementWith != null) {
                                                return false;
                                            }
                                        } else if (elementWith == null) {
                                            return false;
                                        } else {
                                            Class elementCompareClass = elementCompare.getClass();
                                            if (elementCompareClass != elementWith.getClass()) {
                                                return false;
                                            }
                                            if (hasPublicConstructor(elementCompareClass)) {
                                                if (!isEqual(elementCompare,
                                                    elementWith,
                                                    path,
                                                    a_stack)) {
                                                    return false;

                                                }
                                            } else if (!elementCompare.equals(elementWith)) {
                                                return false;
                                            }
                                        }

                                    }

                                }
                            }
                        } else if (hasPublicConstructor(fields[i].getType())) {
                            if (!isEqual(compare, with, path, a_stack)) {
                                return false;
                            }
                        } else {
                            if (!compare.equals(with)) {
                                return false;
                            }
                        }
                    }
                } catch (IllegalAccessException ex) {
                    // probably JDK 1
                    // never mind this field
                    return true;
                } catch (Exception e) {
                    System.err.println("STCompare failure executing path:" + path);
                    e.printStackTrace();
                    return false;
                }
            }
        }
        return true;
    }

    boolean hasPublicConstructor(Class a_class) {
        if (a_class != String.class) {
            try {
                return a_class.newInstance() != null;
            } catch (Throwable t) {
            }
        }
        return false;
    }

    Object normalizeNArray(Object a_object) {
        if (Array.getLength(a_object) > 0) {
            Object first = Array.get(a_object, 0);
            if (first != null && first.getClass().isArray()) {
                int dim[] = arrayDimensions(a_object);
                Object all = new Object[arrayElementCount(dim)];
                normalizeNArray1(a_object, all, 0, dim, 0);
                return all;
            }
        }
        return a_object;
    }

    int normalizeNArray1(Object a_object, Object a_all, int a_next, int a_dim[], int a_index) {
        if (a_index == a_dim.length - 1) {
            for (int i = 0; i < a_dim[a_index]; i++) {
                Array.set(a_all, a_next++, Array.get(a_object, i));
            }
        } else {
            for (int i = 0; i < a_dim[a_index]; i++) {
                a_next =
                    normalizeNArray1(Array.get(a_object, i), a_all, a_next, a_dim, a_index + 1);
            }

        }
        return a_next;
    }

    int[] arrayDimensions(Object a_object) {
        int count = 0;
        for (Class clazz = a_object.getClass();
            clazz.isArray();
            clazz = clazz.getComponentType()) {
            count++;
        }
        int dim[] = new int[count];
        for (int i = 0; i < count; i++) {
            dim[i] = Array.getLength(a_object);
            a_object = Array.get(a_object, 0);
        }
        return dim;
    }

    int arrayElementCount(int a_dim[]) {
        int elements = a_dim[0];
        for (int i = 1; i < a_dim.length; i++) {
            elements *= a_dim[i];
        }
        return elements;
    }

    public boolean storeableField(Class a_class, Field a_field) {
        return (!Modifier.isStatic(a_field.getModifiers()))
            && (!Modifier.isTransient(a_field.getModifiers())
                & !(a_field.getName().indexOf("$") > -1));
    }

    public static boolean isSimple(Class a_class) {
        for (int i = 0; i < SIMPLE_CLASSES.length; i++) {
            if (a_class == SIMPLE_CLASSES[i]) {
                return true;
            }
        }
        return false;
    }

    private static final Class[] SIMPLE_CLASSES =
        {
            Integer.class,
            Long.class,
            Float.class,
            Boolean.class,
            Double.class,
            Byte.class,
            Character.class,
            Short.class,
            String.class,
            java.util.Date.class };

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.