Сопоставление строки Dozer с перечислением

У меня есть такое перечисление:

public enum PartnershipIndicator {
    VENDOR("VENDOR"), COPARTNER("COPARTNER"), BUYER("BUYER");

    String code;

    private PartnershipIndicator(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public static PartnershipIndicator valueOfCode(String code) {
        for (PartnershipIndicator status : values()) {
            if (status.getCode().equals(code)) {
                return status;
            }
        }
        throw new IllegalArgumentException(
            "Partnership status cannot be resolved for code " + code);
    }

    @Override
    public String toString() {
        return code;
    }
}

Мне нужно преобразовать его в строку и наоборот. Теперь это делается с помощью пользовательского конвертера. Но я хочу сделать это с помощью сопоставления бульдозеров (если это возможно). Если я не пишу никаких отображений в конфиг бульдозера, я получаю

org.dozer.MappingException: java.lang.NoSuchMethodException: by.dev.madhead.demo.test_java.model.PartnershipIndicator.<init>()

исключение. Я не могу добавить общедоступный конструктор по умолчанию в перечисление, так как это невозможно. Итак, я написал трюк с внутренним кодом и valueOfCode()/toString(). Это не работает. Затем я сопоставил его в конфигурации бульдозера:

<mapping>
    <class-a>java.lang.String</class-a>
    <class-b create-method="valueOfCode">by.dev.madhead.demo.test_java.model.PartnershipIndicator</class-b>
</mapping>

Это не работает. Я пробовал valueOfCode(), односторонние сопоставления. Ничего не работает. Преобразование Enum в String тоже не работает, я получаю пустые строки. Любые идеи?


person madhead    schedule 25.11.2011    source источник
comment
Я добавил свой собственный преобразователь в dozer master. Так что никто из 5.4 с этой проблемой не столкнется :)   -  person madhead    schedule 18.01.2013
comment
@all Может ли кто-нибудь изучить этот вопрос   -  person 09Q71AO534    schedule 10.01.2015


Ответы (2)


Не уверен, что это все еще проблема, но, возможно, поможет тем, кто ищет. Но здесь реализовано решение этого:

@Override
public Object convert(Object destination, Object source, Class<?> destinationClass,    Class<?> sourceClass) {
    if(source == null)
        return null;
    if(destinationClass != null){
        if(destinationClass.getSimpleName().equalsIgnoreCase("String")){
            return this.getString(source);
        }else if( destinationClass.isEnum()){

            return this.getEnum(destinationClass, source);

        }else{
            throw new MappingException(new StrBuilder("Converter ").append(this.getClass().getSimpleName())
                       .append(" was used incorrectly. Arguments were: ")
                       .append(destinationClass.getClass().getName())
                       .append(" and ")
                       .append(source).toString());
        }
    }
    return null;
}

private Object getString(Object object){
    String value = object.toString();
    return value;
}
private Object getEnum(Class<?> destinationClass, Object source){
    Object enumeration = null;

    Method [] ms = destinationClass.getMethods();
    for(Method m : ms){
        if(m.getName().equalsIgnoreCase("valueOf")){
            try {
                enumeration = m.invoke( destinationClass.getClass(), (String)source);
            }
            catch (IllegalArgumentException e) {
                e.printStackTrace();
            }
            catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            return enumeration;
        }
    }
    return null;
}

Класс StrBuilder при построении сообщения об исключении взят из общих библиотек apache. Но кроме этого простое отражение для решения этой проблемы. Просто добавьте в класс, который реализует CustomConverter, а затем в xml-файл сопоставления бульдозера добавьте следующую конфигурацию:

<configuration>
    <custom-converters>
        <converter type="com.yourcompany.manager.utils.dozer.converters.EnumStringBiDirectionalDozerConverter">
            <class-a>java.lang.Enum</class-a>
            <class-b>java.lang.String</class-b>
        </converter>
    </custom-converters>
</configuration>

Обратите внимание, что вы можете перечислить конфигурацию только один раз между всеми вашими файлами сопоставления (если у вас их несколько), иначе dozer будет жаловаться. Что я обычно делаю, так это помещаю свои пользовательские конфигурации конвертера в один файл для простоты. Надеюсь это поможет!

person Christopher    schedule 15.05.2012

В Dozer нет перечисления по умолчанию для сопоставления строк. См. преобразование типов данных в документации Dozer. Итак, у вас есть два варианта:

  • Вы можете написать собственный преобразователь, который использует дженерики для обработки любого перечисления.
  • Или вы можете отправить патч в Dozer, чтобы добавить сопоставление enum‹->String к сопоставлениям по умолчанию.
person Andrew Spencer    schedule 06.12.2011
comment
Похоже, что это все еще верно в 2018 году. Проект Dozer, похоже, бездействует. Мы используем ModelMapper в нашем текущем проекте. - person Andrew Spencer; 30.01.2018