2011-11-25 14 views
15

Ho una tale enum:Dozer Stringa da enum mappatura

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; 
    } 
} 

ho bisogno di convertirlo in stringa e viceversa. Ora, è fatto dal convertitore personalizzato. Ma voglio farlo tramite mappature dozer (se è possibile). Se non scrivo alcuna mappatura al dozer confing, ottengo

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

eccezione. Non riesco ad aggiungere il costruttore pubblico predefinito a enum, poiché non è possibile. Quindi, ho scritto un trucco con codice interno e valueOfCode()/toString(). Non funziona. Quindi, l'ho mappato in dozer config:

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

Non funziona. Ho provato valueOfCode(), mappature unidirezionali. Niente funziona. Anche la conversione da Enum a String non funziona, ricevo Stringhe vuote. Qualche idea?

+1

Ho aggiunto il mio convertitore personalizzato al dozer master. Quindi nessuno dalla 5.4 non affronterà questo problema :) – madhead

+0

@all Qualcuno può dare un'occhiata a questa [Domanda] (http://stackoverflow.com/questions/27864640/dozer-string-to-date-field-level-mapping-for -a-list) – 09Q71AO534

risposta

19

Non sono sicuro se questo è ancora un problema, ma può essere di aiuto per chiunque cerchi. Ma qui è implementato soluzione a questo:

@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; 
} 

La classe StrBuilder quando si costruisce il messaggio di eccezione da Apache comuni-lang libs. Ma oltre a questo una semplice riflessione per risolvere questo problema. Basta aggiungere a una classe che implementa CustomConverter e poi nel file XML di mapping dozer aggiungere la seguente configurazione:

<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> 

Si noti che è possibile elencare solo una configurazione di una volta tra tutti i tuoi file di mapping (se si dispone di più) altrimenti dozer si lamenterà. Quello che faccio di solito è posizionare le configurazioni personalizzate del convertitore in un unico file per semplicità. Spero che questo ti aiuti!

4

Non esiste un enum predefinito per la mappatura delle stringhe in Dozer. Vedere Data type conversion da documenti Dozer. Quindi avete due opzioni:

  • È possibile scrivere un convertitore personalizzato che utilizza i generici per gestire qualsiasi enum.
  • Oppure, è possibile inviare una patch a Dozer per aggiungere enum < -> Associazione di stringhe ai mapping predefiniti.
+0

Sembra che questo sia ancora vero nel 2018. Il progetto Dozer sembra essere inattivo. Utilizziamo ModelMapper nel nostro attuale progetto. –