Monday, April 26, 2010
Well, nothing
We've got no reply yet. Should have marked it as needs review, however we didn't have that ability, like permissions or some fun stuff like that. Anyway, it's submitted for review now. Fun.
Friday, April 23, 2010
Done... or are we
We submitted our patch. We'll see if it gets accepted.
Goooooooooooooo openMRS!
Ticket 1150
Goooooooooooooo openMRS!
Ticket 1150
Monday, April 19, 2010
Completely Phased Out
Soooooooo... we got an email from Darius. He was actually quite helpful, however the first part of the email was troubling. Apparently CohortReportsFromControler has been completely phased out due to a better reporting module. Well... woulda been nice to know. Anyway,
The helpful part was that if we still should complete this task, we found out some good stuff about the refactroing that we're doing. It seems that the onSubmit method we pulled out needs to be pulled out, however they just want the meat of the method pulled out. They would like it if the method onSubmit stayed in place even though it isn't called by anything outside cohortReportsFormController. That's obviously doable, so I'm not really all that worried if Darius says he wants it done that way for 100% real. Also, they want the method itself broken down more... or refacored. Bad a. I can finally do what I've been trying to do all semester.
Freakin WOOT.
The End.
For Now.
Or IS ITTTTTTTTT????!!!?!?!???!?!?!!!!!
Ya, it is.
Bye.
The helpful part was that if we still should complete this task, we found out some good stuff about the refactroing that we're doing. It seems that the onSubmit method we pulled out needs to be pulled out, however they just want the meat of the method pulled out. They would like it if the method onSubmit stayed in place even though it isn't called by anything outside cohortReportsFormController. That's obviously doable, so I'm not really all that worried if Darius says he wants it done that way for 100% real. Also, they want the method itself broken down more... or refacored. Bad a. I can finally do what I've been trying to do all semester.
Freakin WOOT.
The End.
For Now.
Or IS ITTTTTTTTT????!!!?!?!???!?!?!!!!!
Ya, it is.
Bye.
Monday, April 12, 2010
Success
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;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.Location;
import org.openmrs.api.ReportService;
import org.openmrs.api.context.Context;
import org.openmrs.cohort.CohortDefinition;
import org.openmrs.cohort.CohortUtil;
import org.openmrs.module.reportingcompatibility.ReportingCompatibilityConstants;
import org.openmrs.report.CohortDataSetDefinition;
import org.openmrs.report.DataSetDefinition;
import org.openmrs.report.Parameter;
import org.openmrs.report.ReportSchema;
import org.openmrs.report.ReportSchemaXml;
import org.openmrs.reporting.AbstractReportObject;
import org.openmrs.reporting.PatientSearchReportObject;
import org.openmrs.reporting.ReportObjectService;
import org.openmrs.util.OpenmrsConstants;
import org.openmrs.util.OpenmrsUtil;
import org.simpleframework.xml.Serializer;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
/**
* 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");
command.setReportId(id);
command.setName(schema.getName());
command.setDescription(schema.getDescription());
command.getParameters().addAll(schema.getReportParameters());
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
MapnameToStrategy = new LinkedHashMap ();
Node strategies = crxml.findChild(temp, "strategies"); //calls findChild method in CohortReportXMLBuilder
if (strategies != null) {
NodeList nl = strategies.getChildNodes();
// each is aname strategy
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);
}
}
}
MapnameToDescription = new LinkedHashMap ();
Node descriptions = crxml.findChild(temp, "descriptions"); //calls findChild method in CohortReportXMLBuilder
if (descriptions != null) {
NodeList nl = descriptions.getChildNodes();
// each is aname descr
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);
}
}
}
LinkedHashSetnames = new LinkedHashSet ();
names.addAll(nameToStrategy.keySet());
names.addAll(nameToDescription.keySet());
Listrows = 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 MapreferenceData(HttpServletRequest request) throws Exception {
Mapret = new HashMap ();
List> classes = new ArrayList >();
classes.add(Date.class);
classes.add(Integer.class);
classes.add(Double.class);
classes.add(Location.class);
ret.put("parameterClasses", classes);
ReportObjectService rs = (ReportObjectService) Context.getService(ReportObjectService.class);
Listsearches = rs.getReportObjectsByType(
OpenmrsConstants.REPORT_OBJECT_TYPE_PATIENTSEARCH);
Mapmap = new LinkedHashMap ();
for (AbstractReportObject o : searches) {
if (o instanceof PatientSearchReportObject) {
StringBuilder searchName = new StringBuilder(o.getName());
Listparameters = ((PatientSearchReportObject) o).getPatientSearch().getParameters();
if (parameters != null && !parameters.isEmpty()) {
searchName.append("|");
for (Iteratori = parameters.iterator(); i.hasNext();) {
Parameter p = i.next();
searchName.append(p.getName()).append("=${?}");
if (i.hasNext()) {
searchName.append(",");
}
}
}
map.put(searchName.toString(), o.getDescription());
} else {
map.put(o.getName(), o.getDescription());
}
}
ret.put("patientSearches", map);
ReportService rptSvc = (ReportService) Context.getService(ReportService.class);
Properties macros = rptSvc.getReportXmlMacros();
map = new LinkedHashMap();
for (Map.Entry
CohortReportXMLBuilder:
package org.openmrs.web.controller.report;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.openmrs.api.ReportService;
import org.openmrs.api.context.Context;
import org.openmrs.report.DataSetDefinition;
import org.openmrs.report.ReportSchema;
import org.openmrs.report.ReportSchemaXml;
import org.openmrs.util.OpenmrsUtil;
import org.openmrs.web.controller.report.CohortReportFormController.CohortReportRow;
import org.openmrs.web.controller.report.CohortReportFormController.CommandObject;
import org.simpleframework.xml.Serializer;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
public class CohortReportXMLBuilder extends SimpleFormController {
@Override
protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object commandObj,
BindException errors) throws Exception {
CommandObject command = (CommandObject) commandObj;
// do simpleframework serialization of everything but 'rows', and add those via handcoded xml, since
// serializing them is not reversible
ReportSchema rs = new ReportSchema();
rs.setReportSchemaId(command.getReportId());
rs.setName(command.getName());
rs.setDescription(command.getDescription());
rs.setReportParameters(command.getParameters());
rs.setDataSetDefinitions(new ArrayList());
Serializer serializer = OpenmrsUtil.getSerializer();
StringWriter sw = new StringWriter();
serializer.write(rs, sw);
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();
ReportService rptSvc = (ReportService) Context.getService(ReportService.class);
if (rsx.getReportSchemaId() != null) {
rptSvc.saveReportSchemaXml(rsx);
} else {
rptSvc.saveReportSchemaXml(rsx);
}
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;
}
}
Frustration
I'm getting more and more frustrated with this, but hopefully we're almost at an end with the problems. Today we'll be refactoring the code in yet another build. I'll post the results.
Subscribe to:
Posts (Atom)