Package org.jtester.hamcrest.matcher.property.comparator

Source Code of org.jtester.hamcrest.matcher.property.comparator.HibernateProxyComparator

/*
* Copyright 2008,  Unitils.org
*
* 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 org.jtester.hamcrest.matcher.property.comparator;

import org.jtester.hamcrest.matcher.property.difference.Difference;
import org.jtester.hamcrest.matcher.property.difference.ObjectDifference;
import org.jtester.hamcrest.matcher.property.reflection.ReflectionComparator;

import static org.jtester.hamcrest.matcher.property.reflection.HibernateUtil.*;

/**
* Comparator that can handle Hibernate proxies.
* <p/>
* Special thanks to Tim Peeters for helping us with the implementation.
*
* @author Tim Ducheyne
* @author Filip Neven
* @author Tim Peeters
*/
public class HibernateProxyComparator implements Comparator {


    /**
     * Returns true if one or both of the objects is a Hibernate proxy.
     *
     * @param left  The left object
     * @param right The right object
     * @return True if one is a proxy
     */
    public boolean canCompare(Object left, Object right) {
        return isHibernateProxy(left) || isHibernateProxy(right);
    }


    /**
     * Compares the given objects. If one of the objects is a proxy, the proxy is initialized and the wrapped values
     * are compared. If both objects are proxies and both objects are not yet loaded (initialized) only the idendtifiers
     * are compared. This avoids unitils performing unnecessary loads from the database (potentially retrieving a huge
     * amount of data). If the ids of the proxies are identical, the objects are considered identical, if not the
     * objects are considered different.
     *
     * @param left                 The left object, not null
     * @param right                The right object, not null
     * @param onlyFirstDifference  True if only the first difference should be returned
     * @param reflectionComparator The root comparator for inner comparisons, not null
     * @return A ObjectDifference or null if both maps are equal
     */
    public Difference compare(Object left, Object right, boolean onlyFirstDifference, ReflectionComparator reflectionComparator) {
        if (isUninitialized(left) && isUninitialized(right)) {
            String leftType = getEntitiyName(left);
            String rightType = getEntitiyName(right);
            if (leftType == null || !leftType.equals(rightType)) {
                return new ObjectDifference("Different hibernate proxy types. Left: " + leftType + ", right: " + rightType, left, right);
            }

            Object leftIndentifier = getIdentifier(left);
            Object rightIdentifier = getIdentifier(right);
            Difference identifierDifference = reflectionComparator.getDifference(leftIndentifier, rightIdentifier, onlyFirstDifference);
            if (identifierDifference != null) {
                ObjectDifference difference = new ObjectDifference("Different hibernate proxy values", left, right);
                difference.addFieldDifference("<proxy id>", identifierDifference);
                return difference;
            }
            return null;
        }

        // get the actual value if the value is wrapped by a Hibernate proxy
        Object leftUnproxied = getUnproxiedValue(left);
        Object rightUnproxied = getUnproxiedValue(right);
        return reflectionComparator.getDifference(leftUnproxied, rightUnproxied, onlyFirstDifference);
    }


}
TOP

Related Classes of org.jtester.hamcrest.matcher.property.comparator.HibernateProxyComparator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.