/*
* This file is part of ADDIS (Aggregate Data Drug Information System).
* ADDIS is distributed from http://drugis.org/.
* Copyright © 2009 Gert van Valkenhoef, Tommi Tervonen.
* Copyright © 2010 Gert van Valkenhoef, Tommi Tervonen, Tijs Zwinkels,
* Maarten Jacobs, Hanno Koeslag, Florin Schimbinschi, Ahmad Kamal, Daniel
* Reid.
* Copyright © 2011 Gert van Valkenhoef, Ahmad Kamal, Daniel Reid, Florin
* Schimbinschi.
* Copyright © 2012 Gert van Valkenhoef, Daniel Reid, Joël Kuiper, Wouter
* Reckman.
* Copyright © 2013 Gert van Valkenhoef, Joël Kuiper.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.drugis.addis.util.jaxb;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.drugis.addis.entities.AbstractDose;
import org.drugis.addis.entities.Domain;
import org.drugis.addis.entities.DoseUnit;
import org.drugis.addis.entities.Drug;
import org.drugis.addis.entities.FixedDose;
import org.drugis.addis.entities.FlexibleDose;
import org.drugis.addis.entities.UnknownDose;
import org.drugis.addis.entities.data.Edge;
import org.drugis.addis.entities.treatment.Category;
import org.drugis.addis.entities.treatment.ChoiceNode;
import org.drugis.addis.entities.treatment.DecisionTree;
import org.drugis.addis.entities.treatment.DecisionTreeEdge;
import org.drugis.addis.entities.treatment.DecisionTreeEdgeComparator;
import org.drugis.addis.entities.treatment.DecisionTreeNode;
import org.drugis.addis.entities.treatment.DoseQuantityChoiceNode;
import org.drugis.addis.entities.treatment.LeafNode;
import org.drugis.addis.entities.treatment.RangeEdge;
import org.drugis.addis.entities.treatment.TreatmentCategorization;
import org.drugis.addis.entities.treatment.TypeEdge;
import org.drugis.addis.util.jaxb.JAXBConvertor.ConversionException;
import org.drugis.common.EqualsUtil;
public class TreatmentCategorizationsConverter {
public static Class<? extends AbstractDose> getDoseClass(org.drugis.addis.entities.data.DoseType type) {
switch (type) {
case FIXED_DOSE:
return FixedDose.class;
case FLEXIBLE_DOSE:
return FlexibleDose.class;
case UNKNOWN_DOSE:
return UnknownDose.class;
default:
throw new IllegalStateException("Unknown ENUM value " + type);
}
}
public static TreatmentCategorization load(org.drugis.addis.entities.data.TreatmentCategorization t, Domain domain) throws ConversionException {
String name = t.getName();
Drug drug = JAXBConvertor.findNamedItem(domain.getDrugs(), t.getDrug());
DoseUnit unit = JAXBConvertor.convertDoseUnit(t.getUnit(), domain);
TreatmentCategorization tc = TreatmentCategorization.createBare(name, drug, unit);
for (org.drugis.addis.entities.data.Category category : t.getCategory()) {
tc.addCategory(new Category(tc, category.getName()));
}
convertDecisionTree(t.getDecisionTree(), tc.getDecisionTree(), t, tc, domain);
return tc;
}
private static void convertDecisionTree(
org.drugis.addis.entities.data.DecisionTree src,
DecisionTree dest,
org.drugis.addis.entities.data.TreatmentCategorization srcTc,
TreatmentCategorization destTc,
Domain domain) throws ConversionException {
convertSubtree(dest, destTc, src.getRootNode(), dest.getRoot());
}
private static void convertSubtree(DecisionTree dest,
TreatmentCategorization destTc,
org.drugis.addis.entities.data.TypeNode srcParent,
DecisionTreeNode destParent)
throws ConversionException {
convertSubTree(dest, destTc, destParent, srcParent.getTypeEdge());
}
private static void convertSubtree(DecisionTree dest,
TreatmentCategorization destTc,
org.drugis.addis.entities.data.ChoiceNode srcParent,
DecisionTreeNode destParent)
throws ConversionException {
convertSubTree(dest, destTc, destParent, srcParent.getRangeEdge());
}
private static void convertSubTree(DecisionTree dest, TreatmentCategorization destTc, DecisionTreeNode destParent,
List<? extends org.drugis.addis.entities.data.Edge> edges) throws ConversionException {
for (org.drugis.addis.entities.data.Edge e : edges) {
DecisionTreeEdge edge = convertEdge(e);
DecisionTreeNode child;
if (e.getChoiceNode() != null) {
child = convertChoiceNode(e.getChoiceNode(), destTc);
dest.addChild(edge, destParent, child);
convertSubtree(dest, destTc, e.getChoiceNode(), child);
} else {
child = convertLeafNode(e.getLeafNode(), destTc);
dest.addChild(edge, destParent, child);
}
}
}
private static DecisionTreeNode convertLeafNode(org.drugis.addis.entities.data.LeafNode leafNode, TreatmentCategorization destTc) {
Category destCat = null;
for(Category cat : destTc.getCategories()) {
if(leafNode.getCategory() != null && EqualsUtil.equal(cat.getName(), leafNode.getCategory().getName())) {
destCat = cat;
}
}
return new LeafNode(destCat); // if destCat is null, the LeafNode equals to an ExcludeNode
}
private static DecisionTreeNode convertChoiceNode(org.drugis.addis.entities.data.ChoiceNode choiceNode,
TreatmentCategorization destTc) {
return new DoseQuantityChoiceNode(getDoseClass(choiceNode.getObjectType()), choiceNode.getProperty(), destTc.getDoseUnit());
}
private static DecisionTreeEdge convertEdge(Edge e) throws ConversionException {
if (e instanceof org.drugis.addis.entities.data.RangeEdge) {
org.drugis.addis.entities.data.RangeEdge rangeEdge = (org.drugis.addis.entities.data.RangeEdge) e;
return new RangeEdge(
rangeEdge.getRangeLowerBound(),
rangeEdge.isIsRangeLowerBoundOpen(),
rangeEdge.getRangeUpperBound(),
rangeEdge.isIsRangeUpperBoundOpen());
} else if (e instanceof org.drugis.addis.entities.data.TypeEdge) {
org.drugis.addis.entities.data.TypeEdge typeEdge = (org.drugis.addis.entities.data.TypeEdge) e;
return new TypeEdge(getDoseClass(typeEdge.getMatchType()));
}
throw new ConversionException("Illegal edge type (" + e.getClass() + ")");
}
public static org.drugis.addis.entities.data.TreatmentCategorization save(TreatmentCategorization t) {
org.drugis.addis.entities.data.TreatmentCategorization tc = new org.drugis.addis.entities.data.TreatmentCategorization();
tc.setName(t.getName());
tc.setDrug(t.getDrug().getName());
tc.setUnit(JAXBConvertor.convertDoseUnit(t.getDoseUnit()));
for (Category category : t.getCategories()) {
tc.getCategory().add(convertCategory(category));
}
tc.setDecisionTree(convertDecisionTree(t.getDecisionTree()));
return tc;
}
private static org.drugis.addis.entities.data.Category convertCategory(Category category) {
org.drugis.addis.entities.data.Category c = new org.drugis.addis.entities.data.Category();
c.setName(category.getName());
return c;
}
private static org.drugis.addis.entities.data.DecisionTree convertDecisionTree(DecisionTree tree) {
org.drugis.addis.entities.data.DecisionTree t = new org.drugis.addis.entities.data.DecisionTree();
t.setRootNode((org.drugis.addis.entities.data.TypeNode)convertTypeNodeRecursive(tree.getRoot(), tree));
return t;
}
private static org.drugis.addis.entities.data.TypeNode convertTypeNodeRecursive(DecisionTreeNode parent, DecisionTree tree) {
org.drugis.addis.entities.data.TypeNode node = new org.drugis.addis.entities.data.TypeNode();
List<org.drugis.addis.entities.data.TypeEdge> edges = node.getTypeEdge();
List<DecisionTreeEdge> outEdges = new ArrayList<DecisionTreeEdge>(tree.getOutEdges(parent));
Collections.sort(outEdges, new DecisionTreeEdgeComparator());
for(DecisionTreeEdge e : outEdges) {
edges.add(convertTypeEdge(tree, e));
}
return node;
}
private static org.drugis.addis.entities.data.TypeEdge convertTypeEdge(DecisionTree tree, DecisionTreeEdge edge) {
TypeEdge typeEdge = (TypeEdge) edge;
org.drugis.addis.entities.data.TypeEdge e = new org.drugis.addis.entities.data.TypeEdge();
e.setMatchType(org.drugis.addis.entities.data.DoseType.fromValue(typeEdge.getType().getSimpleName()));
convertEdgeTarget(tree, edge, e);
return e;
}
private static org.drugis.addis.entities.data.ChoiceNode convertChoiceNodeRecursive(ChoiceNode parent, DecisionTree tree) {
org.drugis.addis.entities.data.ChoiceNode node = convertChoiceNode(parent);
List<org.drugis.addis.entities.data.RangeEdge> edges = node.getRangeEdge();
List<DecisionTreeEdge> outEdges = new ArrayList<DecisionTreeEdge>(tree.getOutEdges(parent));
Collections.sort(outEdges, new DecisionTreeEdgeComparator());
for(DecisionTreeEdge e : outEdges) {
edges.add(convertRangeEdge(tree, e));
}
return node;
}
private static org.drugis.addis.entities.data.RangeEdge convertRangeEdge(DecisionTree tree, DecisionTreeEdge edge) {
RangeEdge rangeEdge = (RangeEdge) edge;
org.drugis.addis.entities.data.RangeEdge e = new org.drugis.addis.entities.data.RangeEdge();
e.setRangeLowerBound(rangeEdge.getLowerBound());
e.setIsRangeLowerBoundOpen(rangeEdge.isLowerBoundOpen());
e.setRangeUpperBound(rangeEdge.getUpperBound());
e.setIsRangeUpperBoundOpen(rangeEdge.isUpperBoundOpen());
convertEdgeTarget(tree, edge, e);
return e;
}
private static void convertEdgeTarget(DecisionTree tree, DecisionTreeEdge edge,
org.drugis.addis.entities.data.Edge e) {
if (tree.getEdgeTarget(edge) instanceof LeafNode) {
e.setLeafNode(convertLeafNode((LeafNode) tree.getEdgeTarget(edge)));
} else {
e.setChoiceNode(convertChoiceNodeRecursive((ChoiceNode) tree.getEdgeTarget(edge), tree));
}
}
private static org.drugis.addis.entities.data.LeafNode convertLeafNode(LeafNode leafNode) {
org.drugis.addis.entities.data.LeafNode n = new org.drugis.addis.entities.data.LeafNode();
if(leafNode.getCategory() != null) {
n.setCategory(JAXBConvertor.nameReference(leafNode.getName()));
}
return n;
}
private static org.drugis.addis.entities.data.ChoiceNode convertChoiceNode(ChoiceNode choiceNode) {
org.drugis.addis.entities.data.ChoiceNode n = new org.drugis.addis.entities.data.ChoiceNode();
n.setObjectType(org.drugis.addis.entities.data.DoseType.fromValue(choiceNode.getBeanClass().getSimpleName()));
n.setProperty(choiceNode.getPropertyName());
return n;
}
}