/*
* Copyright (c) 2017 OBiBa. All rights reserved.
*
* This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.obiba.magma.xstream.converter;
import java.util.Arrays;
import org.obiba.magma.Value;
import org.obiba.magma.ValueSequence;
import org.obiba.magma.ValueType;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.DataHolder;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
public class ValueSequenceConverter implements Converter {
public ValueSequenceConverter() {
}
@Override
@SuppressWarnings("rawtypes")
public boolean canConvert(Class type) {
return ValueSequence.class.equals(type);
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
ValueSequence sequence = (ValueSequence) source;
ContextHelper.startSequence(context);
try {
writer.addAttribute("valueType", sequence.getValueType().getName());
if(!sequence.isNull()) {
writer.addAttribute("size", Integer.toString(sequence.getSize()));
int order = 0;
for(Value value : sequence.getValue()) {
ContextHelper.setCurrentOrder(context, order++);
writer.startNode("value");
context.convertAnother(value);
writer.endNode();
}
}
} finally {
ContextHelper.endSequence(context);
}
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
String valueType = reader.getAttribute("valueType");
String size = reader.getAttribute("size");
if(!reader.hasMoreChildren()) {
return ValueType.Factory.forName(valueType).nullSequence();
}
ContextHelper.startSequence(context);
Value[] values = new Value[Integer.valueOf(size)];
while(reader.hasMoreChildren()) {
reader.moveDown();
Value value = (Value) context.convertAnother(context.currentObject(), Value.class);
int order = ContextHelper.getCurrentOrder(context);
values[order] = value;
reader.moveUp();
}
ContextHelper.endSequence(context);
return ValueType.Factory.forName(valueType).sequenceOf(Arrays.asList(values));
}
static class ContextHelper {
private ContextHelper() {}
static public void startSequence(DataHolder holder) {
holder.put(ValueSequence.class, new Object());
}
static public void setCurrentOrder(DataHolder holder, int order) {
Object key = holder.get(ValueSequence.class);
holder.put(key, order);
}
static public int getCurrentOrder(DataHolder holder) {
Object key = holder.get(ValueSequence.class);
return (Integer) holder.get(key);
}
static public void endSequence(DataHolder holder) {
holder.put(ValueSequence.class, null);
}
public static boolean isSequence(DataHolder holder) {
return holder.get(ValueSequence.class) != null;
}
}
}