Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can generic XmlAdapter be written

I know, that I can use Raw types to write XMLAdapter, but can I use generic types. I tried reading the API ( link ), but did not even notice a clue about this.

For example map:

I want to use, something like:

@XmlJavaTypeAdapter(GenericMapAdapter<String, Double>.class)//
private final HashMap<String, Double> depWageSum = //
new HashMap<String, Double>();

to get

<depWageSum>
    <entry key="RI">289.001</entry>
    <entry key="VT">499.817</entry>
    <entry key="HI">41.824</entry>
    ...
<depWageSum>

And class itself would probably look something in the lines of:

@SuppressWarnings("serial") public class GenericMapAdapter<K, V> extends XmlAdapter<GenericMapAdapter.MapType<K, V>, Map<K, V>> {
    public static class MapType<K, V> {
        @XmlValue protected final List<MapTypeEntry<K, V>> entry = new ArrayList<MapTypeEntry<K, V>>();
        public static class MapTypeEntry<K, V> {
            @XmlAttribute protected K key;
            @XmlValue protected V value;
            
            private MapTypeEntry() {};
            public static <K, V> MapTypeEntry<K, V> of(final K k, final V v) {
                return new MapTypeEntry<K, V>() {{this.key = k; this.value = v;}};
    }   }   }
    @Override public Map<K, V> unmarshal(final GenericMapAdapter.MapType<K, V> v) throws Exception {
        return new HashMap<K, V>() {{ for (GenericMapAdapter.MapType.MapTypeEntry<K, V> myEntryType : v.entry)
                    this.put(myEntryType.key, myEntryType.value);}};
    }
    @Override public MapType<K, V> marshal(final Map<K, V> v) throws Exception {
        return new GenericMapAdapter.MapType<K, V>() {{for (K key : v.keySet())
                    this.entry.add(MapTypeEntry.of(key, v.get(key)));}};
}   }
like image 990
Margus Avatar asked Dec 02 '10 18:12

Margus


1 Answers

You will not be able to do this as described. The type parameters will not be retained by the class. However you could introduce some simple subclasses that could leverage the logic from your GenericMapAdapter:

public class StringDoubleMapAdapter extends GenericMapAdapter<String, Double> {
}

Then use the adapter sub class on the property:

@XmlJavaTypeAdapter(StringDoubleMapAdapter.class)//
private final HashMap<String, Double> depWageSum = //
new HashMap<String, Double>();

For more information on XmlAdapter see:

  • http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html
like image 83
bdoughan Avatar answered Sep 28 '22 23:09

bdoughan