Search code examples
javadozer

With dozer is it possible to map several fields to one field?


We have some legacy data we are attempting to map... The legacy data has fields for month day year...

Is it possible to convert

MyObject.day
MyObject.year
MyObject.month

to

MyOtherObject.date

I could not find any documentation on this subject. Any would be appreciated.


Solution

  • I know that this is an old post, but I could not find a satisfying answer, spent a lot of time and then discovered this (I think) easy method. You can use a ConfigurableCustomConver in combination with the 'this' reference in your mapping.xml.

    For example:

    public class Formatter implements ConfigurableCustomConverter
    {
       private String format;
       private String[] fields;
    
       @Override
       public Object convert(Object existingDestinationFieldValue, Object           sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {
          List valueList = new ArrayList();
    
          for (String field : fields){
            try {
               valueList.add(sourceClass.getMethod(field).invoke(sourceFieldValue));
            }
            catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
               throw new RuntimeException("Reflection error during mapping", e);
            }
         }
         return MessageFormat.format(format, valueList.toArray());
      }
    
      @Override
      public void setParameter(String parameter)
      {
         String[] parameters = parameter.split("\\|");
         format = parameters[0];
         fields = Arrays.copyOfRange( parameters, 1, parameters.length);
      }
    }
    

    and in your mapping.xml:

    <mapping type="one-way">
        <class-a>test.model.TestFrom</class-a>
        <class-b>test.model.TestTo</class-b>
    
        <field custom-converter="nl.nxs.dozer.Formatter" custom-converter-param="{0}{1}|getFirstValue|getSecondValue">
            <a>this</a>
            <b>combinedValue</b>
        </field>
    </mapping>
    

    classes:

    public class TestFrom
    {
       private String firstValue;
       private String secondValue;
    
       public String getFirstValue()
       {
          return firstValue;
       }
    
       public void setFirstValue(String firstValue)
       {
          this.firstValue = firstValue;
       }
    
       public String getSecondValue()
       {
          return secondValue;
       }
    
       public void setSecondValue(String secondValue)
       {
          this.secondValue = secondValue;
       } 
    }
    public class TestTo
    {
       private String combinedValue;  
    
       public String getCombinedValue(){
          return combinedValue;
       } 
    
       public void setCombinedValue(String combinedValue){
          this.combinedValue = combinedValue;
       }
    }