Константы в отображениях бульдозера

Кто-нибудь знает, как поместить постоянное значение в атрибут с помощью dozer? Я ничего не видел об этом в документации бульдозера


person Community    schedule 13.05.2009    source источник


Ответы (6)


Не совсем уверен, что вы имеете в виду - если вы хотите, чтобы Dozer всегда заполнял BeanB.someField константой всякий раз, когда вы сопоставляете BeanA с BeanB?

Вы можете зарегистрировать для этого сопоставления пользовательский преобразователь.

person matt b    schedule 13.05.2009
comment
Да, это именно то, что я хочу. Мне было интересно, можно ли сделать это напрямую без специального конвертера. - person ; 14.05.2009
comment
Спасибо за ответ, кстати. - person ; 14.05.2009
comment
Я считаю, что ваши единственные методы - использовать пользовательское преобразование или делать это вручную, когда вы вызываете Dozer. Dozer на самом деле обрабатывает только сопоставление одного bean-компонента с другим и не дает вам много места для вставки другой логики (что имеет смысл, поскольку он не предназначен для этого). - person matt b; 14.05.2009

Как насчет того, чтобы воспользоваться преимуществами механизма событий?

Таким образом, вы можете зарегистрировать слушателя, который будет устанавливать значение в mappingFinished() вашего слушателя. Подробнее см. в документе dozer по событиям. Конечно, вам придется защищать код настройки каким-то if ... instanceof условием.

person Grzegorz Oledzki    schedule 17.06.2009
comment
Это сработало очень хорошо для меня, хотя я зацепил preWritingDestinationValue, поэтому значения действуют как значения по умолчанию, а не переопределяют то, что уже было сопоставлено. - person tzrlk; 05.03.2014

Последние сборки бульдозера облегчают эту задачу. Вы можете указать оба пользовательских преобразователя, и вы можете указать параметры для этого преобразователя для данного сопоставления полей. Должно быть тривиально создать один «ConstantConverter», который будет принимать входной параметр и помещать его в поле вывода в 100% случаев.

person Jherico    schedule 04.02.2010
comment
На самом деле это не так просто с пользовательскими конвертерами. Вам нужно будет либо написать преобразователь для всего класса, содержащего поле (что в первую очередь противоречит цели использования dozer), либо придумывать уродливые решения, чтобы прикрепить преобразователь к одному полю (а это поле существует только в одном поле). из классов). Однако в некоторых случаях это может быть хорошим подходом (в зависимости от того, как структурированы ваши объекты). - person Lajcik; 11.01.2012

Одна из возможных реализаций:

public class ConstantsCustomConvertor implements ConfigurableCustomConverter{

    private String pararamter;
    @Override
    public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {     
        return pararamter;
    }

    @Override
    public void setParameter(String parameter) {
        this.pararamter = parameter;

    }
}

Пример:

<field custom-converter-param="CONTANT_VALUE" custom-converter="org.yourcompany.ConstantsCustomConvertor">
    <a>a-class-dummyfieldname</a>
    <b>b-class-fieldname</b>
</field>    

Этот пользовательский преобразователь предполагает, что имя поля b-класса имеет тип String.

person Sandeep Jindal    schedule 15.10.2014
comment
Может быть, было бы понятнее переименовать это как OneWayConstantConverter. Можно также рассмотреть возможность создания исключения, если сопоставление выполняется наоборот (т. е. не в одностороннем сопоставлении). - person Steve Chambers; 03.09.2019
comment
Теперь я опубликовал ответ, который делает это аналогичным образом, но гарантирует, что он используется только в одностороннее сопоставление и использует class в качестве исходного поля, чтобы исключить необходимость в фиктивном поле. - person Steve Chambers; 05.09.2019

Это довольно просто с ModelMapper:

ModelMapper modelMapper = new ModelMapper();

modelMapper.addMappings(new PropertyMap<SourceClass, DestClass>() {
  protected void configure() {
    map().setSomeProperty(someConstant);
  }
});

Этот пример сопоставляет someConstant с DestClass.someProperty.

Вы можете ознакомиться с дополнительными примерами и документацией по адресу: http://modelmapper.org.

person Jonathan    schedule 29.06.2011

Предполагая, что вы хотите сделать это только в одностороннем сопоставлении, для константы String будет работать следующее:

/**
 * Custom one-way Dozer converter mapping to constant string value specified by a parameter.
 */
public class OneWayStringConstantConverter extends DozerConverter<Class, String> {

    public OneWayBooleanConstantConverter() {
        super(Class.class, String.class);
    }

    @Override
    public String convertTo(Class aClass, String aString) {
        // Return constant value specified by the parameter (source is ignored)
        return getParameter();
    }

    @Override
    public Class convertFrom(String aString, Class aClass) {
        throw new UnsupportedOperationException(
                "OneWayStringConstantConverter should only be used in one-way mappings");
    }
}

... вызывается:

  <field custom-converter="full.path.to.OneWayStringConstantConverter"
         custom-converter-param="My constant string value">
     <a>class</a> <!-- Source not used: Converter only sets target of a one-way mapping -->
     <b>targetField</b>
  </field>

Рекомендую использовать значение class в качестве фиктивного «исходного поля», поскольку оно еще не используется. Метод getClass() гарантированно существует для любого объекта.

Вместо этого мне нужно было сделать это для логического значения, поэтому я использовал это:

/**
 * Custom one-way Dozer converter which maps to the constant boolean value (true or false)
 * specified by a parameter.
 */
public class OneWayBooleanConstantConverter extends DozerConverter<Class, Boolean> {

    public OneWayBooleanConstantConverter() {
        super(Class.class, Boolean.class);
    }

    @Override
    public Boolean convertTo(Class aClass, Boolean aBoolean) {
        // Return constant boolean value specified by the parameter (source is ignored)
        return Boolean.parseBoolean(getParameter());
    }

    @Override
    public Class convertFrom(Boolean aBoolean, Class aClass) {
        throw new UnsupportedOperationException(
                "OneWayBooleanConstantConverter should only be used in one-way mappings");
    }
}
person Steve Chambers    schedule 05.09.2019