com.feilong.lib.xstream.converters.reflection.SortableFieldKeySorter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of feilong Show documentation
Show all versions of feilong Show documentation
feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.
/*
* Copyright (C) 2007, 2009, 2011, 2016 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 10. April 2007 by Guilherme Silveira
*/
package com.feilong.lib.xstream.converters.reflection;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import com.feilong.lib.xstream.converters.ConversionException;
import com.feilong.lib.xstream.core.Caching;
import com.feilong.lib.xstream.core.util.OrderRetainingMap;
/**
* The default implementation for sorting fields. Invoke registerFieldOrder in order to set the field order for an
* specific type.
*
* @author Guilherme Silveira
* @since 1.2.2
*/
public class SortableFieldKeySorter implements FieldKeySorter,Caching{
private final static FieldKey[] EMPTY_FIELD_KEY_ARRAY = {};
private final Map map = new HashMap();
@Override
public Map sort(final Class type,final Map keyedByFieldKey){
if (map.containsKey(type)){
final Map result = new OrderRetainingMap();
final FieldKey[] fieldKeys = (FieldKey[]) keyedByFieldKey.keySet().toArray(EMPTY_FIELD_KEY_ARRAY);
Arrays.sort(fieldKeys, (Comparator) map.get(type));
for (FieldKey fieldKey : fieldKeys){
result.put(fieldKey, keyedByFieldKey.get(fieldKey));
}
return result;
}else{
return keyedByFieldKey;
}
}
/**
* Registers the field order to use for a specific type. This will not affect any of the type's super or sub
* classes. If you skip a field which will be serialized, XStream will thrown a {@link ConversionException} during
* the serialization process.
*
* @param type
* the type
* @param fields
* the field order
*/
public void registerFieldOrder(final Class type,final String[] fields){
map.put(type, new FieldComparator(type, fields));
}
private class FieldComparator implements Comparator{
private final String[] fieldOrder;
private final Class type;
public FieldComparator(final Class type, final String[] fields){
this.type = type;
fieldOrder = fields;
}
public int compare(final String first,final String second){
int firstPosition = -1, secondPosition = -1;
for (int i = 0; i < fieldOrder.length; i++){
if (fieldOrder[i].equals(first)){
firstPosition = i;
}
if (fieldOrder[i].equals(second)){
secondPosition = i;
}
}
if (firstPosition == -1 || secondPosition == -1){
// field not defined!!!
final ConversionException exception = new ConversionException("Incomplete list of serialized fields for type");
exception.add("sort-type", type.getName());
throw exception;
}
return firstPosition - secondPosition;
}
@Override
public int compare(final Object firstObject,final Object secondObject){
final FieldKey first = (FieldKey) firstObject, second = (FieldKey) secondObject;
return compare(first.getFieldName(), second.getFieldName());
}
}
@Override
public void flushCache(){
map.clear();
}
}