package plugins.catalogueTreeNewVersion; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.json.JSONException; import org.json.JSONObject; import org.molgenis.framework.db.Database; import org.molgenis.framework.db.DatabaseException; import org.molgenis.framework.db.Query; import org.molgenis.framework.db.QueryRule; import org.molgenis.framework.db.QueryRule.Operator; import org.molgenis.framework.ui.html.JQueryTreeViewElement; import org.molgenis.pheno.Category; import org.molgenis.pheno.Measurement; import org.molgenis.pheno.ObservedValue; import org.molgenis.protocol.Protocol; import org.molgenis.util.Tuple; public class catalogueTreeComponent { private JQueryTreeViewElement protocolsTree = null; private HashMap<String, JSONObject> descriptions = new HashMap<String, JSONObject>(); private HashMap<String, Protocol> nameToProtocol = new HashMap<String, Protocol>(); private HashMap<String, JQueryTreeViewElement> protocolsAndMeasurementsinTree = new HashMap<String, JQueryTreeViewElement>(); private HashMap<String, List<JQueryTreeViewElement>> findNodes = new HashMap<String, List<JQueryTreeViewElement>>(); private List<String> listOfProtocols = new ArrayList<String>(); private List<String> topProtocols = new ArrayList<String>(); private int loadingProcess = 0; private String investigationName = ""; public catalogueTreeComponent(String investigationName) { this.investigationName = investigationName; initializeTree(); } public JSONObject requestHandle(Tuple request, Database db, OutputStream out) throws JSONException, DatabaseException { JSONObject json = new JSONObject(); if ("download_json_loadingTree".equals(request.getAction())) { if (topProtocols.size() == 0) { topProtocols = getTopProtocols(investigationName, db); } int increment = topProtocols.size() / 5; int upperLimit = topProtocols.size() < (loadingProcess + 1) * increment ? topProtocols.size() : (loadingProcess + 1) * increment; for (int i = loadingProcess * increment; i < upperLimit; i++) { String protocolName = topProtocols.get(i); JQueryTreeViewElement childTree = null; if (!protocolsAndMeasurementsinTree.containsKey(protocolName)) { Protocol protocol = nameToProtocol.get(protocolName); // The tree first time is being created. childTree = new JQueryTreeViewElement(protocolName, Protocol.class.getSimpleName() + protocol.getId().toString(), protocolsTree); protocolsAndMeasurementsinTree.put(protocolName.replaceAll(" ", "_"), childTree); } createNodesForChild(childTree, db); } loadingProcess++; json.put("result", loadingProcess); if (loadingProcess == 5) { json.put("status", true); } else { json.put("status", false); } } else if (request.getAction().equals("download_json_refreshModel")) { String selectedModel = request.getString("selectedModel"); Protocol p = db.find(Protocol.class, new QueryRule(Protocol.NAME, Operator.EQUALS, selectedModel)).get(0); json.put("result", p.getFeatures_Name()); } else if (request.getAction().equals("download_json_showInformation")) { System.out.println("showVariableInformation------------" + request); String nodeIdentifier = request.getString("variableName"); JQueryTreeViewElement node = protocolsAndMeasurementsinTree.get(nodeIdentifier); json.put("result", node.getHtmlValue()); } else if ("download_json_toggleNode".equals(request.getAction())) { String nodeIdentifier = request.getString("nodeIdentifier"); protocolsAndMeasurementsinTree.get(nodeIdentifier).toggleNode(); } else if ("download_json_clearSearch".equals(request.getAction())) { String tree = protocolsTree.toHtml(); json.put("result", tree); } else if ("download_json_search".equals(request.getAction())) { String searchToken = request.getString("searchToken"); List<JQueryTreeViewElement> listOfNodes = new ArrayList<JQueryTreeViewElement>(); Query<Measurement> query = null; // Search in the name of measurements { query = db.query(Measurement.class); query.addRules(new QueryRule(Measurement.INVESTIGATION_NAME, Operator.EQUALS, investigationName)); query.addRules(new QueryRule(Measurement.NAME, Operator.LIKE, searchToken)); for (Measurement m : query.find()) { System.out.println(findNodes.get(m.getName())); if (findNodes.get(m.getName()) != null) { listOfNodes.addAll(findNodes.get(m.getName())); } } } // Search in the description of the variables { query = db.query(Measurement.class); query.addRules(new QueryRule(Measurement.INVESTIGATION_NAME, Operator.EQUALS, investigationName)); query.addRules(new QueryRule(Measurement.DESCRIPTION, Operator.LIKE, searchToken)); for (Measurement m : query.find()) { System.out.println(findNodes.get(m.getName())); if (findNodes.get(m.getName()) != null) { listOfNodes.addAll(findNodes.get(m.getName())); } } } // search in the name of protocols { Query<Protocol> queryProtocol = db.query(Protocol.class); queryProtocol.addRules(new QueryRule(Protocol.INVESTIGATION_NAME, Operator.EQUALS, investigationName)); queryProtocol.addRules(new QueryRule(Protocol.NAME, Operator.LIKE, searchToken)); for (Protocol p : queryProtocol.find()) { System.out.println(findNodes.get(p.getName())); if (findNodes.get(p.getName()) != null) { listOfNodes.addAll(findNodes.get(p.getName())); } } } String tree = searchForInTree(protocolsTree, listOfNodes); json.put("result", tree); } else if ("download_json_getChildren".equals(request.getAction())) { String nodeIdentifier = request.getString("nodeIdentifier"); JQueryTreeViewElement node = protocolsAndMeasurementsinTree.get(nodeIdentifier); node.toggleNode(); StringBuilder addedNodes = new StringBuilder(); if (!node.isCollapsed()) { for (JQueryTreeViewElement child : node.getChildren()) { addedNodes.append(child.toHtml()); } } json.put("result", addedNodes.toString()); } else if ("download_json_getPosition".equals(request.getAction())) { String measurementName = request.getString("measurementName"); List<JQueryTreeViewElement> nodes = findNodes.get(measurementName); List<String> identifier = new ArrayList<String>(); for (JQueryTreeViewElement element : nodes) { identifier.add(element.getName()); while (element.getParent() != null) { element = element.getParent(); element.setCollapsed(false); } } json.put("treeView", protocolsTree.toHtml()); json.put("identifier", identifier.get(0)); } return json; } private String searchForInTree(JQueryTreeViewElement parentNode, List<JQueryTreeViewElement> listOfNodes) { StringBuilder stringBuilder = new StringBuilder(); String returnString = ""; boolean parentCollapse = parentNode.isCollapsed(); parentNode.setCollapsed(false); for (JQueryTreeViewElement childNode : parentNode.getChildren()) { if (listOfNodes.contains(childNode)) { boolean collapse = childNode.isCollapsed(); childNode.setCollapsed(false); stringBuilder.append(childNode.toHtml()); childNode.setCollapsed(collapse); } else { stringBuilder.append(searchForInTree(childNode, listOfNodes)); } } returnString = stringBuilder.toString(); if (!stringBuilder.toString().equals("")) { returnString = parentNode.toHtml(stringBuilder.toString()); } parentNode.setCollapsed(parentCollapse); return returnString; } private void createNodesForChild(JQueryTreeViewElement parentNode, Database db) throws DatabaseException, JSONException { if (nameToProtocol.containsKey(parentNode.getLabel())) { Protocol p = nameToProtocol.get(parentNode.getLabel()); String parentName = p.getName(); // Check subProtocols for (String subProtocolName : p.getSubprotocols_Name()) { JQueryTreeViewElement childTree = null; StringBuilder uniqueName = new StringBuilder(); uniqueName.append(parentName).append("_").append(subProtocolName); if (!protocolsAndMeasurementsinTree.containsKey(uniqueName.toString())) { Protocol protocol = nameToProtocol.get(subProtocolName); // The tree first time is being created. StringBuilder nodeIdentifier = new StringBuilder(); childTree = new JQueryTreeViewElement(uniqueName.toString(), subProtocolName, nodeIdentifier .append(Protocol.class.getSimpleName()).append(protocol.getId().toString()).toString(), parentNode); protocolsAndMeasurementsinTree.put(uniqueName.toString().replaceAll(" ", "_"), childTree); } List<JQueryTreeViewElement> treeNodes = null; if (findNodes.containsKey(subProtocolName)) { treeNodes = findNodes.get(subProtocolName); } else { treeNodes = new ArrayList<JQueryTreeViewElement>(); } treeNodes.add(childTree); findNodes.put(subProtocolName, treeNodes); createNodesForChild(childTree, db); } // There are not subprotocols, therefore check features of this // protocol if (p.getFeatures_Name().size() > 0) { for (Measurement feature : db.find(Measurement.class, new QueryRule(Measurement.NAME, Operator.IN, p.getFeatures_Name()))) { if (!descriptions.containsKey(feature)) { JSONObject data = new JSONObject(); data.put("name", feature.getName()); data.put("label", feature.getLabel()); data.put("description", feature.getDescription()); data.put("dataType", feature.getDataType()); data.put("category", feature.getCategories_Name()); descriptions.put(feature.getName(), data); } String labelName = (feature.getLabel() != null ? feature.getLabel() : feature.getName()); String featureName = feature.getName(); JQueryTreeViewElement childTree = null; StringBuilder uniqueName = new StringBuilder(); uniqueName.append(parentName).append("_").append(featureName); if (!protocolsAndMeasurementsinTree.containsKey(uniqueName.toString())) { StringBuilder nodeIdentifier = new StringBuilder(); childTree = new JQueryTreeViewElement(uniqueName.toString(), labelName, nodeIdentifier .append(Measurement.class.getSimpleName()).append(feature.getId().toString()) .toString(), parentNode); childTree.setIsbottom(true); String htmlValue = htmlTableForTreeInformation(db, feature, featureName); childTree.setHtmlValue(htmlValue); protocolsAndMeasurementsinTree.put(uniqueName.toString().replaceAll(" ", "_"), childTree); } List<JQueryTreeViewElement> treeNodes = null; if (findNodes.containsKey(featureName)) { treeNodes = findNodes.get(featureName); } else { treeNodes = new ArrayList<JQueryTreeViewElement>(); } treeNodes.add(childTree); findNodes.put(featureName, treeNodes); } } } } public void initializeTree() { loadingProcess = 0; topProtocols.clear(); listOfProtocols.clear(); findNodes.clear(); nameToProtocol.clear(); protocolsAndMeasurementsinTree.clear(); try { // Create the first node of the tree StringBuilder nodeIdentifier = new StringBuilder(); protocolsTree = new JQueryTreeViewElement(nodeIdentifier.append("Study_").append(investigationName) .toString(), "", null); protocolsTree.setLabel(nodeIdentifier.toString()); protocolsAndMeasurementsinTree.put(protocolsTree.getName().replaceAll(" ", "_"), protocolsTree); } catch (Exception e) { e.printStackTrace(); } } public String htmlTableForTreeInformation(Database db, Measurement measurement, String nodeName) throws DatabaseException { List<String> categoryNames = measurement.getCategories_Name(); String measurementDescription = measurement.getDescription(); String measurementDataType = measurement.getDataType(); String displayName = measurement.getName(); if (measurement.getLabel() != null && !measurement.getLabel().equals("")) { displayName = measurement.getLabel(); } StringBuilder htmlValue = new StringBuilder(); htmlValue.append("<table style='border-spacing: 2px; width: 100%;' class='MeasurementDetails' id = '") .append(nodeName).append("_table'>") .append("<tr><td class='box-body-label'>Current selection:</th><td id=\"").append(nodeName) .append("_itemName\"style=\"cursor:pointer\">").append(displayName).append("</td></tr>"); if (categoryNames.size() > 0) { List<Category> listOfCategory = db.find(Category.class, new QueryRule(Category.NAME, Operator.IN, categoryNames)); htmlValue.append("<tr id='").append(nodeName) .append("_category'><td class='box-body-label'>Category:</td><td><table>"); StringBuilder missingCategory = new StringBuilder(); missingCategory.append("<tr><td class='box-body-label'>Missing category:</td><td><table>"); for (Category c : listOfCategory) { StringBuilder codeString = new StringBuilder(); codeString.append(c.getCode_String()); if (!codeString.equals("")) { codeString.append(" = "); } if (!c.getIsMissing()) { htmlValue.append("<tr><td>").append(codeString).append(c.getDescription()).append("</td></tr>"); } else { missingCategory.append("<tr><td>").append(codeString).append(c.getDescription()) .append("</td></tr>"); } } htmlValue.append("</table></td></tr>").append(missingCategory.toString()).append("</table>"); } htmlValue.append("<tr id='").append(nodeName) .append("_description'><td class='box-body-label'>Description:</td><td>") .append((measurementDescription == null ? "not provided" : measurementDescription)) .append("</td></tr>").append("<tr id='").append(nodeName) .append("_dataType'><td class='box-body-label'>Data type:</th><td>").append(measurementDataType) .append("</td></tr>"); Query<ObservedValue> queryDetailInformation = db.query(ObservedValue.class); queryDetailInformation .addRules(new QueryRule(ObservedValue.TARGET_NAME, Operator.EQUALS, measurement.getName())); if (!queryDetailInformation.find().isEmpty()) { for (ObservedValue ov : queryDetailInformation.find()) { String featureName = ov.getFeature_Name(); String value = ov.getValue(); if (featureName.startsWith("SOP")) { htmlValue.append("<tr><td class='box-body-label'>").append(featureName).append("</td><td><a href=") .append(value).append(">").append(value).append("</a></td></tr>"); } else { if (featureName.startsWith("display name")) { featureName = "display name"; } } } } htmlValue.append("</table>"); return htmlValue.toString(); } public List<String> getTopProtocols(String investigationName, Database db) throws DatabaseException { List<String> topProtocols = new ArrayList<String>(); List<String> bottomProtocols = new ArrayList<String>(); List<String> middleProtocols = new ArrayList<String>(); for (Protocol p : db.find(Protocol.class, new QueryRule(Protocol.INVESTIGATION_NAME, Operator.EQUALS, investigationName))) { if (!p.getName().equalsIgnoreCase("generic")) { List<String> subNames = p.getSubprotocols_Name(); // keep a record of each protocol in a hashmap. Later on we // could reference to the Protocol by name if (!nameToProtocol.containsKey(p.getName())) { nameToProtocol.put(p.getName(), p); } if (!subNames.isEmpty()) { if (!topProtocols.contains(p.getName())) { topProtocols.add(p.getName()); } for (String subProtocol : subNames) { if (!middleProtocols.contains(subProtocol)) { middleProtocols.add(subProtocol); } } } else { if (!bottomProtocols.contains(p.getName())) { bottomProtocols.add(p.getName()); } } } middleProtocols.removeAll(bottomProtocols); topProtocols.removeAll(middleProtocols); } if (topProtocols.size() == 0) { return bottomProtocols; } else { return topProtocols; } } public String getTreeView() { return protocolsTree.toHtml(null); } public List<String> getListOfProtocols() { return listOfProtocols; } public JSONObject getDescriptions(String measurementName) { return descriptions.get(measurementName); } }