Package org.dcm4che3.conf.api.generic.adapters

Source Code of org.dcm4che3.conf.api.generic.adapters.MapTypeAdapter

package org.dcm4che3.conf.api.generic.adapters;

import java.lang.reflect.Field;
import java.lang.reflect.MalformedParameterizedTypeException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.naming.NamingException;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.ModificationItem;

import org.dcm4che3.conf.api.ConfigurationException;
import org.dcm4che3.conf.api.generic.ConfigField;
import org.dcm4che3.conf.api.generic.ReflectiveConfig;
import org.dcm4che3.conf.api.generic.ReflectiveConfig.ConfigReader;
import org.dcm4che3.conf.api.generic.ReflectiveConfig.ConfigTypeAdapter;
import org.dcm4che3.conf.api.generic.ReflectiveConfig.ConfigWriter;
import org.dcm4che3.net.TransferCapability;

/**
* Map<br>
*
* Key type must have String as serialized representation and must not use field when serializing/deserializing!
*
*/

public class MapTypeAdapter<K, V> implements ConfigTypeAdapter<Map<K, V>, Map<String,Object>> {

    @Override
    public boolean isWritingChildren(Field field) {
        return true;
    }

    private ConfigTypeAdapter<V, ?> getValueAdapter(Field field, ReflectiveConfig config) {
        ParameterizedType pt = (ParameterizedType) field.getGenericType();

        Type[] ptypes = pt.getActualTypeArguments();

        // there must be only 2 parameterized types
        if (ptypes.length != 2)
            throw new MalformedParameterizedTypeException();

        // figure out the classes of declared generic parameters and
        // get value adapter
        return config.lookupTypeAdapter((Class<V>) ptypes[1]);

    }

    private ConfigTypeAdapter<V, ?> getKeyAdapter(Field field, ReflectiveConfig config) {
        ParameterizedType pt = (ParameterizedType) field.getGenericType();

        Type[] ptypes = pt.getActualTypeArguments();

        // there must be only 2 parameterized types
        if (ptypes.length != 2)
            throw new MalformedParameterizedTypeException();

        // figure out the classes of declared generic parameters and
        // get key adapter
        return config.lookupTypeAdapter((Class<V>) ptypes[0]);

    }

    @SuppressWarnings("unchecked")
    @Override
    public Map<String,Object> read(ReflectiveConfig config, ConfigReader reader, Field field) throws ConfigurationException {
        ConfigField fieldAnno = field.getAnnotation(ConfigField.class);

        Map<String,Object> cnode = new HashMap<String,Object>();

        // read collection
        ConfigReader collectionReader = reader.getChildReader(getCollectionName(fieldAnno));
        Map<String, ConfigReader> map = collectionReader.readCollection(fieldAnno.mapKey());

        ConfigTypeAdapter<V, Object> valueAdapter = (ConfigTypeAdapter<V, Object>) getValueAdapter(field, config);

        // for each element, read it using the value adapter
        for (Entry<String, ConfigReader> e : map.entrySet()) {
            cnode.put(e.getKey(), valueAdapter.read(config, e.getValue(), field));
        }
        return cnode;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Map<K, V> deserialize(Map<String,Object> serialized, ReflectiveConfig config, Field field) throws ConfigurationException {

        if (serialized == null) return null;
       
        ConfigTypeAdapter<V, Object> valueAdapter = (ConfigTypeAdapter<V, Object>) getValueAdapter(field, config);
        ConfigTypeAdapter<K, String> keyAdapter = (ConfigTypeAdapter<K, String>) getKeyAdapter(field, config);

        // deserialize entries
        Map<K, V> map = new HashMap<K, V>();
        for (Entry<String, Object> e : serialized.entrySet()) {
            map.put(keyAdapter.deserialize(e.getKey(), config, null), valueAdapter.deserialize(e.getValue(), config, field));
        }

        return map;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Map<String,Object> serialize(Map<K, V> obj, ReflectiveConfig config, Field field) throws ConfigurationException {

        if (obj == null) return null;
       
        Map<String,Object> cnode = new HashMap<String,Object>();

        ConfigTypeAdapter<V, Object> valueAdapter = (ConfigTypeAdapter<V, Object>) getValueAdapter(field, config);
        ConfigTypeAdapter<K, String> keyAdapter = (ConfigTypeAdapter<K, String>) getKeyAdapter(field, config);

        for (Entry<K, V> e : obj.entrySet()) {
            cnode.put(keyAdapter.serialize(e.getKey(), config, null), valueAdapter.serialize(e.getValue(), config, field));
        }

        return cnode;
    }

    private String getCollectionName(ConfigField fieldAnno) {
        return (fieldAnno.mapName().equals("N/A") ? fieldAnno.name() : fieldAnno.mapName());
    }

    @SuppressWarnings("unchecked")
    @Override
    public void write(Map<String,Object> serialized, ReflectiveConfig config, ConfigWriter writer, Field field) throws ConfigurationException {
        ConfigField fieldAnno = field.getAnnotation(ConfigField.class);

        // getValueAdapter
        ConfigTypeAdapter<V, Object> valueAdapter = (ConfigTypeAdapter<V, Object>) getValueAdapter(field, config);

        ConfigWriter collectionWriter = writer.createCollectionChild(getCollectionName(fieldAnno), field);

        if (serialized == null) return;
       
        for (Entry<String, Object> e : serialized.entrySet()) {

            ConfigWriter elementWriter = collectionWriter.getCollectionElementWriter(fieldAnno.mapKey(), e.getKey(), field);
            valueAdapter.write(e.getValue(), config, elementWriter, field);
            elementWriter.flushWriter();
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public void merge(Map<K, V> prev, Map<K, V> curr, ReflectiveConfig config, ConfigWriter diffwriter, Field field) throws ConfigurationException {
        ConfigField fieldAnno = field.getAnnotation(ConfigField.class);

        ConfigTypeAdapter<V, Object> valueAdapter = (ConfigTypeAdapter<V, Object>) getValueAdapter(field, config);
        ConfigTypeAdapter<K, String> keyAdapter = (ConfigTypeAdapter<K, String>) getKeyAdapter(field, config);

        ConfigWriter collectionWriter = diffwriter.getChildWriter(getCollectionName(fieldAnno), field);

        // remove nodes that were deleted since prev
        for (Entry<K, V> e : prev.entrySet())
            if (curr.get(e.getKey()) == null)
                collectionWriter.removeCollectionElement(fieldAnno.mapKey(), keyAdapter.serialize(e.getKey(), config, null));

        // add new nodes and merge existing
        for (Entry<K, V> e : curr.entrySet()) {

            // serialize key
            String serializedKey = keyAdapter.serialize(e.getKey(), config, null);
            // if new node
            if (prev.get(e.getKey()) == null) {
                ConfigWriter elementWriter = collectionWriter.getCollectionElementWriter(fieldAnno.mapKey(), serializedKey, field);
                // serialize
                Object serialized = valueAdapter.serialize(e.getValue(), config, field);
                valueAdapter.write(serialized, config, elementWriter, field);
                elementWriter.flushWriter();
            }
            // existing node
            else {
                ConfigWriter elementWriter = collectionWriter.getCollectionElementDiffWriter(fieldAnno.mapKey(), serializedKey);
                valueAdapter.merge(prev.get(e.getKey()), e.getValue(), config, elementWriter, field);
                elementWriter.flushDiffs();
            }
        }
    }
   
    @Override
    public Map<String, Object> getMetadata(ReflectiveConfig config, Field field) throws ConfigurationException {
        ConfigField fieldAnno = field.getAnnotation(ConfigField.class);

        Map<String, Object> metadata =  new HashMap<String, Object>();
        Map<String, Object> keyMetadata =  new HashMap<String, Object>();
        Map<String, Object> valueMetadata =  new HashMap<String, Object>();
       
        metadata.put("type", "Map");
       
        // get adapters
        ConfigTypeAdapter<V, Object> valueAdapter = (ConfigTypeAdapter<V, Object>) getValueAdapter(field, config);
        ConfigTypeAdapter<K, String> keyAdapter = (ConfigTypeAdapter<K, String>) getKeyAdapter(field, config);

        // fill in key and value metadata
        keyMetadata.putAll(keyAdapter.getMetadata(config, field));
        metadata.put("keyMetadata", keyMetadata);
       
        valueMetadata.putAll(valueAdapter.getMetadata(config, field));
        metadata.put("elementMetadata", valueMetadata);

        return metadata;
    }
}
TOP

Related Classes of org.dcm4che3.conf.api.generic.adapters.MapTypeAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.