/*
* 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 org.obiba.magma.Attribute;
import org.obiba.magma.Category;
import org.obiba.magma.ValueType;
import org.obiba.magma.Variable;
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;
/**
* Converts an {@code Variable} instance.
* <p/>
* Resulting XML:
* <p/>
* <pre>
* <variable name="HQ.SMOKER" valueType="text" entityType="Participant">
* <attributes>
* <attribute name="label" valueType="text" locale="en">
* <value>Do you smoke?</value>
* </attribute>
* <attribute name="label" valueType="text" locale="fr">
* <value>Fumez-vous?</value>
* </attribute>
* ...
* </attributes>
* <categories>
* <category name="YES" code="1">
* <attributes>
* <attribute name="label" valueType="text" locale="en">
* <value>Yes</value>
* </attribute>
* <attribute name="label" valueType="text" locale="fr">
* <value>Oui</value>
* </attribute>
* </attributes>
* </category>
* ...
* </categories>
* </variable>
* </pre>
*/
public class VariableConverter extends AbstractAttributeAwareConverter {
public VariableConverter(Mapper mapper) {
super(mapper);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public boolean canConvert(Class type) {
return Variable.class.isAssignableFrom(type);
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
Variable variable = (Variable) source;
writer.addAttribute("name", variable.getName());
writer.addAttribute("valueType", variable.getValueType().getName());
writer.addAttribute("entityType", variable.getEntityType());
if(variable.getUnit() != null) {
writer.addAttribute("unit", variable.getUnit());
}
if(variable.getMimeType() != null) {
writer.addAttribute("mimeType", variable.getMimeType());
}
if(variable.getReferencedEntityType()!= null) {
writer.addAttribute("referencedEntityType", variable.getReferencedEntityType());
}
writer.addAttribute("index", Integer.toString(variable.getIndex()));
if(variable.isRepeatable()) {
writer.addAttribute("repeatable", "true");
if(variable.getOccurrenceGroup() != null) {
writer.addAttribute("occurrenceGroup", variable.getOccurrenceGroup());
}
}
marshallAttributes(variable, writer, context);
marshallCategories(variable, writer, context);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Variable.Builder builder = Variable.Builder
.newVariable(reader.getAttribute("name"), ValueType.Factory.forName(reader.getAttribute("valueType")),
reader.getAttribute("entityType"));
if(reader.getAttribute("repeatable") != null) {
try {
if (Boolean.parseBoolean(reader.getAttribute("repeatable"))) {
builder.repeatable().occurrenceGroup(reader.getAttribute("occurrenceGroup"));
}
} catch(Exception e) {}
}
if(reader.getAttribute("unit") != null) {
builder.unit(reader.getAttribute("unit"));
}
if(reader.getAttribute("mimeType") != null) {
builder.mimeType(reader.getAttribute("mimeType"));
}
if(reader.getAttribute("referencedEntityType") != null) {
builder.referencedEntityType(reader.getAttribute("referencedEntityType"));
}
if(reader.getAttribute("index") != null) {
builder.index(reader.getAttribute("index"));
}
unmarshalChildren(reader, context, builder);
return builder.build();
}
private void unmarshalChildren(HierarchicalStreamReader reader, UnmarshallingContext context,
Variable.Builder builder) {
while(reader.hasMoreChildren()) {
reader.moveDown();
if(isAttributesNode(reader.getNodeName())) {
unmarshallAttributes(builder, reader, context);
} else if("categories".equals(reader.getNodeName())) {
while(reader.hasMoreChildren()) {
Category category = readChildItem(reader, context, builder);
builder.addCategory(category);
}
}
reader.moveUp();
}
}
@Override
void addAttribute(Object current, Attribute attribute) {
Variable.Builder builder = (Variable.Builder) current;
builder.addAttribute(attribute);
}
protected void marshallCategories(Variable variable, HierarchicalStreamWriter writer, MarshallingContext context) {
if(variable.hasCategories()) {
writer.startNode("categories");
for(Category c : variable.getCategories()) {
writeItem(c, context, writer);
}
writer.endNode();
}
}
}