package org.msh.tb.medicines; import org.msh.tb.entities.Medicine; import org.msh.tb.entities.Source; import java.util.ArrayList; import java.util.List; public class SourceMedicineTree { private List sources = new ArrayList(); public interface ItemTraversing { void traverse(Source source, Medicine medicine, E item); } /** * Return a list with all items children of medicines * @return */ public List getItems() { final List items = new ArrayList(); traverse(new ItemTraversing() { public void traverse(Source source, Medicine medicine, E item) { items.add(item); } }); return items; } /** * Add a new source to the tree * @param source * @return */ public SourceNode addSource(Source source) { for (SourceNode it: sources) { if (it.getSource().equals(source)) return it; } SourceNode grp = new SourceNode(source); sources.add(grp); return grp; } /** * Add a new medicine * @param source * @param med * @return */ public MedicineNode addMedicine(Source source, Medicine med) { SourceNode node = addSource(source); MedicineNode mednode = node.nodeByMedicine(med); if (mednode != null) return mednode; mednode = new MedicineNode(node, med); node.getMedicines().add(mednode); return mednode; } /** * Add an item to the tree * @param source * @param medicine * @param item */ public void addItem(Source source, Medicine medicine, E item) { MedicineNode mg = addMedicine(source, medicine); mg.getBatches().add(item); } /** * Search for a node by its source and medicine. If the node doesn't exist, it returns null * @param source * @param med * @return */ public MedicineNode findMedicineNode(Source source, Medicine med) { return findNodeByMedicineId(source.getId(), med.getId()); } /** * Search for the medicine node by the source and medicine id * @param sourceId * @param medId * @return instance of the {@link MedicineNode} class, otherwise null if the node was not found */ public MedicineNode findNodeByMedicineId(Integer sourceId, Integer medId) { SourceNode sourceNode = findNodeBySourceId(sourceId); if (sourceNode == null) return null; for (MedicineNode node: sourceNode.getMedicines()) { if (node.getMedicine().getId().equals(medId)) return node; } return null; } /** * Search for the source node by the source id * @param sourceId * @return instance of the {@link SourceNode} class, otherwise null if the source was not found */ public SourceNode findNodeBySourceId(Integer sourceId) { for (SourceNode node: sources) { if (node.getSource().getId().equals(sourceId)) return node; } return null; } /** * Traverse the list * @param t */ public void traverse(ItemTraversing t) { for (SourceNode sourceNode: sources) { for (MedicineNode medNode: sourceNode.getMedicines()) { for (Object item: medNode.getBatches()) { t.traverse(sourceNode.getSource(), medNode.getMedicine(), (E)item); } } } } /** * @author Ricardo Memoria * */ public class SourceNode { private Source source; private Object item; private List medicines = new ArrayList(); public SourceNode(Source source) { this.source = source; } /** * Search for a node by its medicine * @param med * @return */ public MedicineNode nodeByMedicine(Medicine med) { for (MedicineNode node: medicines) { if (node.getMedicine().equals(med)) return node; } return null; } /** * @return the item */ public Object getItem() { return item; } /** * @param item the item to set */ public void setItem(Object item) { this.item = item; } /** * @return the medicines */ public List getMedicines() { return medicines; } /** * @return the source */ public Source getSource() { return source; } public String getRowId() { return "s" + (source.getId() != null? source.getId().toString(): ""); } } /** * @author Ricardo Memoria * */ public class MedicineNode { private Medicine medicine; private Object item; private List batches = new ArrayList(); private SourceNode parent; public MedicineNode(SourceNode parent, Medicine medicine) { this.medicine = medicine; this.parent = parent; } /** * Return a unique ID for the node * @return */ public String getNodeId() { return medicine.getId().toString() + (parent != null? "_" + parent.getSource().getId().toString(): ""); } /** * @return the medicine */ public Medicine getMedicine() { return medicine; } /** * @param medicine the medicine to set */ public void setMedicine(Medicine medicine) { this.medicine = medicine; } /** * @return the item */ public Object getItem() { return item; } /** * @param item the item to set */ public void setItem(Object item) { this.item = item; } /** * @return the batches */ public List getBatches() { return batches; } public String getRowId() { return parent.getRowId() + "m" + medicine.getId().toString(); } /** * @return the parent */ public SourceNode getParent() { return parent; } } /** * @return the sources */ public List getSources() { return sources; } }