com.thoughtworks.xstream.converters.collections.TreeMapConverter Maven / Gradle / Ivy
/*
* Copyright (C) 2004, 2005 Joe Walnes.
* Copyright (C) 2006, 2007 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
* style license a copy of which has been included with this distribution in
* the LICENSE.txt file.
*
* Created on 08. May 2004 by Joe Walnes
*/
package com.thoughtworks.xstream.converters.collections;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.mapper.Mapper;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* Converts a java.util.TreeMap to XML, and serializes
* the associated java.util.Comparator. The converter
* assumes that the entries in the XML are already sorted
* according the comparator.
*
* @author Joe Walnes
* @author Jörg Schaible
*/
public class TreeMapConverter extends MapConverter {
public TreeMapConverter(Mapper mapper) {
super(mapper);
}
public boolean canConvert(Class type) {
return type.equals(TreeMap.class);
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
TreeMap treeMap = (TreeMap) source;
Comparator comparator = treeMap.comparator();
if (comparator == null) {
writer.startNode("no-comparator");
writer.endNode();
} else {
writer.startNode("comparator");
writer.addAttribute("class", mapper().serializedClass(comparator.getClass()));
context.convertAnother(comparator);
writer.endNode();
}
super.marshal(source, writer, context);
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
reader.moveDown();
SortedMap sortedMap;
TreeMap result;
if (reader.getNodeName().equals("comparator")) {
String comparatorClass = reader.getAttribute("class");
Comparator comparator = (Comparator) context.convertAnother(null, mapper().realClass(comparatorClass));
sortedMap = new PresortedMap(comparator);
result = new TreeMap(comparator);
} else if (reader.getNodeName().equals("no-comparator")) {
sortedMap = new PresortedMap();
result = new TreeMap();
} else {
throw new ConversionException("TreeMap does not contain element");
}
reader.moveUp();
super.populateMap(reader, context, sortedMap);
result.putAll(sortedMap); // // internal optimization will not call comparator
return result;
}
private static class PresortedMap implements SortedMap {
private static class ArraySet extends ArrayList implements Set {
}
private final ArraySet set = new ArraySet();
private final Comparator comparator;
PresortedMap() {
this(null);
}
PresortedMap(Comparator comparator) {
this.comparator = comparator;
}
public Comparator comparator() {
return comparator;
}
public Set entrySet() {
return set;
}
public Object firstKey() {
throw new UnsupportedOperationException();
}
public SortedMap headMap(Object toKey) {
throw new UnsupportedOperationException();
}
public Set keySet() {
Set keySet = new ArraySet();
for (final Iterator iterator = set.iterator(); iterator.hasNext();) {
final Entry entry = (Entry)iterator.next();
keySet.add(entry.getKey());
}
return keySet;
}
public Object lastKey() {
throw new UnsupportedOperationException();
}
public SortedMap subMap(Object fromKey, Object toKey) {
throw new UnsupportedOperationException();
}
public SortedMap tailMap(Object fromKey) {
throw new UnsupportedOperationException();
}
public Collection values() {
Set values = new ArraySet();
for (final Iterator iterator = set.iterator(); iterator.hasNext();) {
final Entry entry = (Entry)iterator.next();
values.add(entry.getValue());
}
return values;
}
public void clear() {
throw new UnsupportedOperationException();
}
public boolean containsKey(Object key) {
return false;
}
public boolean containsValue(Object value) {
throw new UnsupportedOperationException();
}
public Object get(Object key) {
throw new UnsupportedOperationException();
}
public boolean isEmpty() {
return set.isEmpty();
}
public Object put(final Object key, final Object value) {
set.add(new Entry(){
public Object getKey() {
return key;
}
public Object getValue() {
return value;
}
public Object setValue(Object value) {
throw new UnsupportedOperationException();
}});
return null;
}
public void putAll(Map m) {
for (final Iterator iter = m.entrySet().iterator(); iter.hasNext();) {
set.add(iter.next());
}
}
public Object remove(Object key) {
throw new UnsupportedOperationException();
}
public int size() {
return set.size();
}
}
}