All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.thksystems.persistence.xstream.converters.MapToAttributesConverter Maven / Gradle / Ivy

There is a newer version: 1.1.1
Show newest version
/*
 * tksCommons
 * 
 * Author : Thomas Kuhlmann (ThK-Systems, http://oss.thk-systems.de) License : LGPL (https://www.gnu.org/licenses/lgpl.html)
 */
package de.thksystems.persistence.xstream.converters;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import com.thoughtworks.xstream.XStreamException;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

/**
 * 

Converts a map to a list of xml-attributes.

The key of the {@link Map} becomes the name of the xml-attribute, and the value of * the {@link Map} becomes the value of the xml-attribute. *

* For example *

* The following {@link Map} named 'myMap': *

    *
  • firstname -> homer
  • *
  • lastname -> simpson
  • *
  • spouse- > marge
  • *
* will be converted to the following XML: * *
 * {@code
 * 
 * }
 * 
* * Usage *

* Use the converter by adding a {@link XStreamConverter} annotation, like: *

* @XStreamConverter(MapToAttributesConverter.class) *

*
*

* Allowed Parameter Types *

* The default use of the converter is for {@link Map} of {@link String},{@link String}. The type of the key must be {@link String}. *

* As the value type another type may be choosen. This type must be 'convertable' to {@link String}, so it must have a usable * {@link #toString()} method and a constructor which takes a single {@link String} as its only argument. (Example types: {@link Integer}, * {@link Long}, {@link BigDecimal}.) You need to specify the value type to the {@link XStreamConverter} annotation like this: *

* @XStreamConverter(value = MapToAttributesConverter.class, useImplicitType = false, types = { Integer.class }). */ public class MapToAttributesConverter implements Converter { protected static final Class TARGET_CLASS = Map.class; private Class valueClass = String.class; private Constructor valueClassConstructor; public MapToAttributesConverter() { this(String.class); } public MapToAttributesConverter(Class valueClass) { if (!TARGET_CLASS.isAssignableFrom(valueClass)) { this.valueClass = valueClass; checkValueClass(); } } private void checkValueClass() { if (!String.class.isAssignableFrom(valueClass)) { Class[] parameterTypes = new Class[] { String.class }; try { valueClassConstructor = valueClass.getConstructor(parameterTypes); } catch (NoSuchMethodException e) { throw new IllegalArgumentException("Value class cannot be converted to string: " + valueClass); } catch (SecurityException e) { throw new IllegalArgumentException("Cannot check value class: " + e.getMessage(), e); } } } @SuppressWarnings("rawtypes") @Override public boolean canConvert(Class type) { return TARGET_CLASS.isAssignableFrom(type); } @Override @SuppressWarnings({ "unchecked" }) public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { Map map = (Map) source; for (Map.Entry entry : map.entrySet()) { writer.addAttribute(entry.getKey(), entry.getValue().toString()); } } @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { Map map = new HashMap<>(); for (int i = 0; i < reader.getAttributeCount(); i++) { String key = reader.getAttributeName(i); String valueString = reader.getAttribute(key); Object valueObject; if (valueClassConstructor != null) { try { valueObject = valueClassConstructor.newInstance(valueString); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new XStreamException(String.format("Cannot convert string value '%s' to class '%s': %s", valueString, valueClass, e.getMessage()), e); } } else { valueObject = valueString; } map.put(key, valueObject); } return map; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy