Игнорирование регистра в строках с unitils ReflectionComparator

Я использую инструмент unitils для глубокого сравнения объектов через ReflectionComparator:

ReflectionComparatorMode[] modes = {ReflectionComparatorMode.LENIENT_ORDER, ReflectionComparatorMode.IGNORE_DEFAULTS};
ReflectionComparator comparator = ReflectionComparatorFactory.createRefectionComparator(modes);
Difference difference = comparator.getDifference(oldObject, newObject);

Оказывается, это ReflectionComparator не игнорирует регистр в значениях String полей. И для этого в ReflectionComparatorMode enum нет специального режима:

public enum ReflectionComparatorMode {
    IGNORE_DEFAULTS,
    LENIENT_DATES,
    LENIENT_ORDER
}

Любые идеи, как это может быть достигнуто?


person Andremoniy    schedule 21.04.2015    source источник


Ответы (2)


ReflectionComparatorMode не имеет режима для имитации поведения ignore_case. Вы не указываете типы oldObject и newObject, но я думаю, вы можете либо «нормализовать» их перед передачей в ReflectionComparator (преобразовать все поля String либо в верхний, либо в нижний регистр) или реализовать свой собственный компаратор Java на основе конкретного типа oldObject и newObject.

Ознакомьтесь с этим.

person aviad    schedule 21.04.2015
comment
Спасибо, но я не могу. Я имею дело с множеством разных классов, и если бы я мог нормализовать их все, было бы намного проще сравнивать вручную без какого-либо инструмента unitils. - person Andremoniy; 21.04.2015
comment
Почувствуй свою боль. Возможно, вы можете использовать ReflectionUtils unitils.org/apidocs/org/unitils/util/ReflectionUtils .html для массажа обоих объектов перед передачей их в ReflectionComparator? - person aviad; 21.04.2015
comment
Еще раз спасибо за идею, но я нашел действительно работающее универсальное решение. Если интересно, посмотри мой ответ - person Andremoniy; 21.04.2015
comment
@avaid Я имею в виду универсальность в том смысле, что можно избежать нормализации кода вручную для всех объектов. - person Andremoniy; 21.04.2015

Изучение того, как работает ReflectionComparator, дало мне это работоспособное решение. Короче говоря, мы должны добавить еще один специальный объект Comparator для работы с объектами String в цепочке компараторов.

Кроме того, мы должны сделать некоторый бедлам с извлечением одного необходимого protected статического метода из ReflectionComparatorFactory, чтобы уменьшить дублирование кода.

ReflectionComparatorMode[] modes = {ReflectionComparatorMode.LENIENT_ORDER, ReflectionComparatorMode.IGNORE_DEFAULTS};

List<org.unitils.reflectionassert.comparator.Comparator> comparators = new ArrayList<>();
    comparators.add(new Comparator() {
         @Override
         public boolean canCompare(Object left, Object right) {
               return left instanceof String && right instanceof String;
         }

         @Override
         public Difference compare(Object left, Object right, boolean onlyFirstDifference, ReflectionComparator reflectionComparator) {
               return  ((String) left).equalsIgnoreCase((String) right) ? null : new Difference("Non equal values: ", left, right);
         }
});

comparators.addAll(
    new ReflectionComparatorFactory() {
        public List<Comparator> getComparatorChainNonStatic(Set<ReflectionComparatorMode> modes) {
               return getComparatorChain(modes);
        }
    }.getComparatorChainNonStatic(asSet(modes)));

ReflectionComparator comparator = new ReflectionComparator(comparators);
person Andremoniy    schedule 21.04.2015