3

I'm sure this is a rather simple question but I'm at wits end as to how to solve it elegantly (a case statement doesn't sound like the most scalable option).

I have to convert and populate address data of one type and package it up for a webservice that is of a different type. Unfortunately, the types do not align and I will have to somehow map the two.

For instance, I have AddressData which contains String AddressLine1, String State, etc... The other class, Address, which needs to be populated is expecting a particular "StateProviceCode" rather than a String for the state. How can I map the String to a particular StateProviceCode so I can just run the map and inject the correct state code?

If that doesn't make too much sense, I'm attempting to do something like the following:

    Address billingAddress = new Address(); //to be populated
    AddressData billingAddressData = updateStoredCardRequest.getPaymentInfo().getBillingAddress();

    billingAddress.setAddressLine1(billingAddressData.getLine1()); //String->String
    billingAddress.setCity(billingAddressData.getTown()); //String->String
    billingAddress.setPostalCode(billingAddressData.getPostalCode()); //String->String

    //based on the isocode of the billingAddressData.region, set the stateProviceCode of the billingAddress.
    if(billingAddressData.getRegion().getIsocodeShort() == "US-IL"){
        billingAddress.setStateProvinceCode(StateProvinceCode.Illinois);
        }

Any help on ways to do this implementation would be great. Thank you so much.

user1615559
  • 333
  • 2
  • 8
  • 18

2 Answers2

2

I think what you're asking is creating a relationship between a String and an object you've created or are using called a "StateProvinceCode". If this is the case, you can use a "Map" like Kevin suggested. I like to use HashMaps as they are a little easier to deal with:

HashMap<String, StateProvinceCode> map = new HashMap<String, StateProvinceCode>();

You can utilize the HashMap as follows:

map.put("Illinois", StateProvinceCode.Illinois);  


for(Map.Entry m : map.entrySet()){  
    System.out.println(m.getKey() + " " + m.getValue());  
}  

For populating your HashMap, I'm not an expert with Spring, so maybe someone can give you a better answer than this, but you can always just use a loop. If you have a List of each as an example, you can construct your HashMap this way:

List<StateProvinceCode> stateProvinceCodes = new ArrayList<StateProvinceCode>();
List<String> stringsForStateProvinceCodes = new ArrayList<String>();

for( StateProvinceCode spc : stateProvinceCodes ) {
    for( String s : stringsForStateProvinceCodes ) {
        map.put(s, spc);
    }
}

The above is probably not perfect because it's very late here, so apologies. You might need to finagle a little magic to get it working correctly. Let me know if you run into more issues.

Dominic Holt
  • 162
  • 1
  • 12
  • Yes, exactly! How do I populate the HashMap with all the Strings of states and the corresponding StateProvinceCodes? Can I do this with Spring util:map? Also, can I get a String from a StateProvinceCode this way? I apologize for the rookie questions I'm still pretty new to Java. – user1615559 Mar 05 '15 at 09:28
  • I've edited my answer with the additional details. Hope that helps. – Dominic Holt Mar 05 '15 at 09:31
  • That helps a lot! Thank you. Is there a way I can declare this Map ahead of time like via a spring configuration file? Adding over 50+ mappings seems in my method seems a bit extreme. Thanks! – user1615559 Mar 05 '15 at 09:40
  • Added some more clarification. – Dominic Holt Mar 05 '15 at 10:09
  • @user1615559 Sounds like a job for a [static initializer](http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html). – Kevin Krumwiede Mar 05 '15 at 19:03
2

Did you consider using PropertyMap?

So you will have to do something like this -

class AddressMapper extends PropertyMap<AddressData, Address> {

   @Override
   protected void configure(){

     map().setAddressLine1(source.getLine1());
     map().setCity(source.getTown());

   }
}

//Define ModelMapper class in your configuration
    @Bean
    public ModelMapper modelMapper(){
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.addMappings(new AddressMapper());
        return modelMapper;
    }

After that, you just have to call the map method of the ModerMapper -

@Autowired
ModelMapper modelMapper;

modelMapper.map(<AddressData object goes here>, Address.class);
Righto
  • 855
  • 3
  • 11
  • 32