Как Orika решает, когда использовать конвертер

Я пытаюсь понять, когда Orika использует конвертеры для отображения по сравнению с прямым литьем.

У меня есть следующее сопоставление:

Class A {
  Map<String, Object> props;

}

Class B {
   String bStr;
   int bInt;

}

Мое отображение определяется как props['aStr'] => bStr и props['aInt'] => bInt

Когда я смотрю на сгенерированный код, я вижу, что для случая String он использует преобразователь и вызывает его метод convert для преобразования:

destination.setBStr("" + ((ma.glasnost.orika.Converter)usedConverters[0]).convert(
        ((java.lang.Object) ((java.util.Map) source.getProps().get("aStr"),
        (ma.glasnost.orika.metadata.Type) usedTypes[0]))

Но для целочисленного случая он прямо бросает это так:

 destination.setBInt((java.lang.Integer)(java.lang.Object) ((java.util.Map)
     source.getProps().get("aInt")))

Приведенная выше строка кода приводит к исключению приведения класса.

Чтобы решить эту проблему, я думал об использовании специального конвертера, но если в приведенной выше строке кода конвертер не используется, это не сработает.

Конечно, я всегда могу сделать это в своем собственном картографе, но просто пытаюсь понять, как генерируется код для преобразования типов.

Спасибо!!


person bsam    schedule 26.02.2014    source источник


Ответы (1)


В Orika есть два этапа: время конфигурации и время выполнения, поскольку оптимизация Orika разрешает все используемые преобразователи во время конфигурации и кэширует их в каждый сгенерированный преобразователь, поэтому он будет доступен напрямую O (1), но во время конфигурации он попытается чтобы найти в списке O(n) зарегистрированных конвертеров, которые "canConvert" между двумя заданными типами, canConvert - это метод в интерфейсе Converter.

Таким образом, это решение предлагает лучшее из двух миров:

  • Очень гибкий способ регистрации конвертера с произвольными условиями
  • Эффективное разрешение и операция преобразования во время выполнения.

Orika по умолчанию использует существование .toString в каждом объекте, чтобы предлагать неявное принуждение к String для каждого объекта. Проблема здесь в том, что нет преобразователя из объекта в целое число.

Возможно, это может быть проблемой сообщения об ошибках. В идеале Orika должна сообщить, что объект должен быть преобразован в целое число, а соответствующий преобразователь не зарегистрирован.

person Sidi    schedule 26.02.2014
comment
Спасибо за быстрый ответ! У меня есть преобразователь StringToInteger, который расширяет базовый класс CustomConverter. Я зарегистрировал этот конвертер глобально, но он никогда не срабатывает. Как Orika решает, использовать ли .toString() по умолчанию или использовать конвертер? - person bsam; 27.02.2014
comment
Как я уже сказал, он перебирает все зарегистрированные преобразователи и вызывает .canConvert(), чтобы убедиться, что преобразователь может обрабатывать случай (тип источника и тип назначения). В этом случае вы должны использовать Object‹->Integer Converter, а не StringToInteger - person Sidi; 28.02.2014
comment
Спасибо еще раз! Использование Object to Integer Converter устранило проблему для меня. - person bsam; 03.03.2014
comment
Я столкнулся с аналогичной проблемой, решил ее с помощью этого примера, но затем обнаружил, что вместо этого я могу установить fieldMap(a, b).aElementType(String.class).add(), чтобы подсказать тип A, и мне не нужно сворачивать пользовательский преобразователь . - person Joel Wickard; 07.03.2014