So we got CohortReportFormController refactored successfully. See code below:
CohortReportFormController:
/**
* The contents of this file are subject to the OpenMRS Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://license.openmrs.org
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* Copyright (C) OpenMRS, LLC. All Rights Reserved.
*/
package org.openmrs.web.controller.report;
/**
* This form lets you create or edit a report with a single CohortDataSetDefinition. You should
* not use this form to edit other types of reports.
*/
public class CohortReportFormController extends SimpleFormController implements Validator {
Log log = LogFactory.getLog(getClass());
/**
* Creates a command object and tries to fill it with data from the saved report schema with the
* id given by the 'reportId' parameter.
*
* @see org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest)
*/
protected Object formBackingObject(HttpServletRequest request) throws Exception {
CommandObject command = new CommandObject();
if (Context.isAuthenticated() && !isFormSubmission(request)) {
// if this is an existing report, get its data
String idString = request.getParameter("reportId");
if (idString != null) {
Integer id = Integer.valueOf(idString);
ReportService rs = (ReportService) Context.getService(ReportService.class);
ReportSchemaXml schemaXml = rs.getReportSchemaXml(id);
ReportSchema schema = rs.getReportSchema(schemaXml);
CohortDataSetDefinition cohorts = null;
if (schema.getDataSetDefinitions() == null)
schema.setDataSetDefinitions(new ArrayList());
if (schema.getDataSetDefinitions().size() == 0)
schema.getDataSetDefinitions().add(new CohortDataSetDefinition());
for (DataSetDefinition d : schema.getDataSetDefinitions()) {
if (d instanceof CohortDataSetDefinition) {
if (cohorts != null)
throw new Exception(
"You may not edit a report that contains more than one Cohort Dataset Definition");
cohorts = (CohortDataSetDefinition) d;
} else {
throw new Exception(
"You may not edit a report that contains datasets besides Cohort Dataset Definition");
}
}
if (cohorts == null)
throw new Exception("You may only edit a report that has exactly one Cohort Dataset Definition");
CohortReportXMLBuilder crxml = new CohortReportXMLBuilder(); //Make new instance of CohortReportXMLBuilder called crxml
// populate command.rows, directly from XML
Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
new InputSource(new StringReader(schemaXml.getXml())));
// xml looks like ...... // TODO: do this with xpath
Node temp = crxml.findChild(xml, "reportSchema"); //calls findChild method in CohortReportXMLBuilder
temp = crxml.findChild(temp, "dataSets"); //calls findChild method in CohortReportXMLBuilder
temp = crxml.findChildWithAttribute(temp, "dataSetDefinition", "class",
"org.openmrs.report.CohortDataSetDefinition"); //calls findChildWithAttribute method in CohortReportXMLBuilder
Map nameToStrategy = new LinkedHashMap();
Node strategies = crxml.findChild(temp, "strategies"); //calls findChild method in CohortReportXMLBuilder
if (strategies != null) {
NodeList nl = strategies.getChildNodes();
// each is a namestrategy for (int i = 0; i < nl.getLength(); ++i) {
Node node = nl.item(i);
if ("entry".equals(node.getNodeName())) {
String name = crxml.findChild(node, "string").getFirstChild().getNodeValue(); //calls findChild method in CohortReportXMLBuilder
String strategy = crxml.findChild(crxml.findChild(node, "cohort"), "specification").getFirstChild() //calls findChild method in CohortReportXMLBuilder
.getNodeValue();
nameToStrategy.put(name, strategy);
}
}
}
Map nameToDescription = new LinkedHashMap();
Node descriptions = crxml.findChild(temp, "descriptions"); //calls findChild method in CohortReportXMLBuilder
if (descriptions != null) {
NodeList nl = descriptions.getChildNodes();
// each is a namedescr for (int i = 0; i < nl.getLength(); ++i) {
Node node = nl.item(i);
if ("entry".equals(node.getNodeName())) {
String name = crxml.findChild(node, "string").getFirstChild().getNodeValue(); //calls findChild method in CohortReportXMLBuilder
String descr = crxml.findChild(node, "string", 2).getFirstChild().getNodeValue(); //calls findChild method in CohortReportXMLBuilder
nameToDescription.put(name, descr);
}
}
}
LinkedHashSet names = new LinkedHashSet();
names.addAll(nameToStrategy.keySet());
names.addAll(nameToDescription.keySet());
List rows = new ArrayList();
for (String name : names) {
String descr = nameToDescription.get(name);
String strat = nameToStrategy.get(name);
CohortReportRow row = new CohortReportRow();
row.setName(name);
row.setDescription(descr);
row.setQuery(strat);
rows.add(row);
}
command.setRows(rows);
}
}
return command;
}
/**
* @see org.springframework.web.servlet.mvc.SimpleFormController#referenceData(javax.servlet.http.HttpServletRequest)
*/
@Override
protected Map referenceData(HttpServletRequest request) throws Exception {
Map ret = new HashMap();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document xml = db.parse(new InputSource(new StringReader(
"" + sw.toString())));
Node node = findChild(xml, "reportSchema");
node = findChild(node, "dataSets");
Element dsd = xml.createElement("dataSetDefinition");
dsd.setAttribute("name", "cohorts");
dsd.setAttribute("class", "org.openmrs.report.CohortDataSetDefinition");
node.appendChild(dsd);
Element strategies = xml.createElement("strategies");
strategies.setAttribute("class", "java.util.LinkedHashMap");
dsd.appendChild(strategies);
Element descriptions = xml.createElement("descriptions");
descriptions.setAttribute("class", "java.util.LinkedHashMap");
dsd.appendChild(descriptions);
for (CohortReportRow row : command.getRows()) {
if (StringUtils.hasText(row.getQuery())) {
Element entry = xml.createElement("entry");
strategies.appendChild(entry);
Element nameEl = xml.createElement("string");
Text val = xml.createTextNode(row.getName());
val.setNodeValue(row.getName());
nameEl.appendChild(val);
entry.appendChild(nameEl);
Element cohort = xml.createElement("cohort");
entry.appendChild(cohort);
cohort.setAttribute("class", "org.openmrs.reporting.PatientSearch");
Element strategyEl = xml.createElement("specification");
val = xml.createTextNode(row.getQuery());
val.setNodeValue(row.getQuery());
strategyEl.appendChild(val);
cohort.appendChild(strategyEl);
}
if (StringUtils.hasText(row.getDescription())) {
Element entry = xml.createElement("entry");
descriptions.appendChild(entry);
Element el = xml.createElement("string");
Text val = xml.createTextNode(row.getName());
val.setNodeValue(row.getName());
el.appendChild(val);
entry.appendChild(el);
el = xml.createElement("string");
val = xml.createTextNode(row.getDescription());
val.setNodeValue(row.getDescription());
el.appendChild(val);
entry.appendChild(el);
}
}
// now turn this into an xml string
System.setProperty("javax.xml.transform.TransformerFactory",
"com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
trans.setOutputProperty(OutputKeys.METHOD, "xml");
StringWriter out = new StringWriter();
StreamResult result = new StreamResult(out);
DOMSource source = new DOMSource(xml);
trans.transform(source, result);
String schemaXml = out.toString();
ReportSchemaXml rsx = new ReportSchemaXml();
rsx.populateFromReportSchema(rs);
rsx.setXml(schemaXml);
rsx.updateXmlFromAttributes();
return new ModelAndView(new RedirectView(getSuccessView() + "?reportId=" + rsx.getReportSchemaId()));
}
Node findChild(Node parent, String name) {
NodeList list = parent.getChildNodes();
for (int i = 0; i < list.getLength(); ++i) {
Node node = list.item(i);
if (node.getNodeName().equals(name))
return node;
}
return null;
}
/**
* finds the ith occurrence of a child with the given name
*/
protected Node findChild(Node parent, String name, int index) {
int soFar = 0;
NodeList list = parent.getChildNodes();
for (int i = 0; i < list.getLength(); ++i) {
Node node = list.item(i);
if (node.getNodeName().equals(name)) {
++soFar;
if (soFar == index)
return node;
}
}
return null;
}
protected Node findChildWithAttribute(Node parent, String name, String attrName, String attrValue) {
NodeList list = parent.getChildNodes();
for (int i = 0; i < list.getLength(); ++i) {
Node node = list.item(i);
if (node.getNodeName().equals(name)) {
Node attr = node.getAttributes().getNamedItem(attrName);
if (attr != null && attr.getNodeValue().equals(attrValue))
return node;
}
}
return null;
}
wrap your code in a <pre> tag to make the indentation remain.
ReplyDeleteya, that looks better.
ReplyDeleteThanks.