package org.test4j.hamcrest.matcher.property.reflection; import static org.test4j.hamcrest.matcher.property.reflection.EqMode.EQ_STRING; import static org.test4j.hamcrest.matcher.property.reflection.EqMode.IGNORE_DATES; import static org.test4j.hamcrest.matcher.property.reflection.EqMode.IGNORE_DEFAULTS; import static org.test4j.hamcrest.matcher.property.reflection.EqMode.IGNORE_ORDER; import java.util.ArrayList; import java.util.List; import org.test4j.hamcrest.matcher.property.comparator.Comparator; import org.test4j.hamcrest.matcher.property.comparator.EqStringComparator; import org.test4j.hamcrest.matcher.property.comparator.HibernateProxyComparator; import org.test4j.hamcrest.matcher.property.comparator.IgnoreDatesComparator; import org.test4j.hamcrest.matcher.property.comparator.IgnoreDefaultsComparator; import org.test4j.hamcrest.matcher.property.comparator.IgnoreNumberComparator; import org.test4j.hamcrest.matcher.property.comparator.IgnoreOrderComparator; import org.test4j.hamcrest.matcher.property.comparator.ListComparator; import org.test4j.hamcrest.matcher.property.comparator.MapComparator; import org.test4j.hamcrest.matcher.property.comparator.ObjectComparator; import org.test4j.hamcrest.matcher.property.comparator.SimpleCasesComparator; import org.test4j.tools.commons.ListHelper; /** * A factory for creating a reflection comparator. This will assemble the * apropriate comparator chain and constructs a reflection comparator. * <p/> * By default, a strict comparison is performed, but if needed, some leniency * can be configured by setting one or more comparator modes: * <ul> * <li>ignore defaults: all fields that have a default java value for the left * object will be ignored. Eg if the left object contains an int field with * value 0 it will not be compared to the value of the right object.</li> * <li>lenient dates: only check whether both Date objects contain a value or * not, the value itself is not compared. Eg. if the left object contained a * date with value 1-1-2006 and the right object contained a date with value * 2-2-2006 they would still be considered equal.</li> * <li>lenient order: only check whether both collections or arrays contain the * same value, the actual order of the values is not compared. Eg. if the left * object is int[]{ 1, 2} and the right value is int[]{2, 1} they would still be * considered equal. */ public class ReflectionComparatorFactory { /** * The LenientDatesComparator singleton insance */ protected static final Comparator LENIENT_DATES_COMPARATOR = new IgnoreDatesComparator(); /** * The object equals to String comparator */ protected static final Comparator EQ_STRING_COMPARATOR = new EqStringComparator(); /** * The IgnoreDefaultsComparator singleton insance */ protected static final Comparator IGNORE_DEFAULTS_COMPARATOR = new IgnoreDefaultsComparator(); /** * The LenientNumberComparator singleton insance */ protected static final Comparator LENIENT_NUMBER_COMPARATOR = new IgnoreNumberComparator(); /** * The SimpleCasesComparatorsingleton insance */ protected static final Comparator SIMPLE_CASES_COMPARATOR = new SimpleCasesComparator(); /** * The LenientOrderCollectionComparator singleton insance */ protected static final Comparator LENIENT_ORDER_COMPARATOR = new IgnoreOrderComparator(); /** * The CollectionComparator singleton insance */ protected static final Comparator COLLECTION_COMPARATOR = new ListComparator(); /** * The MapComparator singleton insance */ protected static final Comparator MAP_COMPARATOR = new MapComparator(); /** * The HibernateProxyComparator singleton insance */ protected static final Comparator HIBERNATE_PROXY_COMPARATOR = new HibernateProxyComparator(); /** * The ObjectComparator singleton insance */ protected static final Comparator OBJECT_COMPARATOR = new ObjectComparator(); /** * Creates a reflection comparator for the given modes. If no mode is given, * a strict comparator will be created. * * @param modes * The modes, null for strict comparison * @return The reflection comparator, not null */ @SuppressWarnings("unchecked") public static ReflectionComparator createRefectionComparator(EqMode... modes) { List<EqMode> _modes = ListHelper.toList(modes); List<Comparator> comparators = getComparatorChain(_modes); return new ReflectionComparator(comparators); } /** * Creates a comparator chain for the given modes. If no mode is given, a * strict comparator will be created. * * @param modes * The modes, null for strict comparison * @return The comparator chain, not null */ protected static List<Comparator> getComparatorChain(List<EqMode> modes) { List<Comparator> comparatorChain = new ArrayList<Comparator>(); if (modes.contains(IGNORE_DATES)) { comparatorChain.add(LENIENT_DATES_COMPARATOR); } if (modes.contains(EQ_STRING)) { comparatorChain.add(EQ_STRING_COMPARATOR); } if (modes.contains(IGNORE_DEFAULTS)) { comparatorChain.add(IGNORE_DEFAULTS_COMPARATOR); } comparatorChain.add(LENIENT_NUMBER_COMPARATOR); comparatorChain.add(SIMPLE_CASES_COMPARATOR); if (modes.contains(IGNORE_ORDER)) { comparatorChain.add(LENIENT_ORDER_COMPARATOR); } else { comparatorChain.add(COLLECTION_COMPARATOR); } comparatorChain.add(MAP_COMPARATOR); comparatorChain.add(HIBERNATE_PROXY_COMPARATOR); comparatorChain.add(OBJECT_COMPARATOR); return comparatorChain; } }