tag node.
+ Node clonedAttributeQDMNode = attributeNode.cloneNode(false);
+ clonedAttributeQDMNode.setUserData(
+ ATTRIBUTE_NAME, attributeNode.getAttributes().getNamedItem(NAME).getNodeValue(), null);
+ clonedAttributeQDMNode.setUserData(
+ ATTRIBUTE_MODE, attributeNode.getAttributes().getNamedItem("mode").getNodeValue(), null);
+ clonedAttributeQDMNode.setUserData(
+ ATTRIBUTE_UUID,
+ attributeNode.getAttributes().getNamedItem("attrUUID").getNodeValue(),
+ null);
+ String attrDate = "";
+ if (attributeNode.getAttributes().getNamedItem("attrDate") != null) {
+ attrDate = attributeNode.getAttributes().getNamedItem("attrDate").getNodeValue();
+ }
+ clonedAttributeQDMNode.setUserData(ATTRIBUTE_DATE, attrDate, null);
+
+ createXmlForDataCriteria(
+ qdmNode, dataCriteriaXMLProcessor, simpleXmlprocessor, clonedAttributeQDMNode);
+ }
+ }
+
+ /**
+ * Create xml for data criteria.
+ *
+ * @param qdmNode the qdm node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param attributeQDMNode the attribute qdm node
+ * @return void
+ */
+ private void createXmlForDataCriteria(
+ Node qdmNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ Node attributeQDMNode) {
+ String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+
+ XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(4.3);
+ String xPathForTemplate = "/templates/template[text()='" + dataType.toLowerCase() + "']";
+ String actNodeStr = "";
+ try {
+
+ Node templateNode =
+ templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xPathForTemplate);
+ if (templateNode != null) {
+ String attrClass = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
+ String xpathForAct = "/templates/acts/act[@a_id='" + attrClass + "']";
+ Node actNode =
+ templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xpathForAct);
+ if (actNode != null) {
+ actNodeStr = actNode.getTextContent();
+ }
+
+ createDataCriteriaElementTag(
+ actNodeStr,
+ templateNode,
+ qdmNode,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ templateXMLProcessor,
+ attributeQDMNode);
+ }
+
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Gets the creates the data create element tag.
+ *
+ * @param actNodeStr the act node str
+ * @param templateNode the template node
+ * @param qdmNode the qdm node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param templateXMLProcessor - templateXmlProcessor
+ * @param attributeQDMNode - Attribute QDM Node.
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void createDataCriteriaElementTag(
+ String actNodeStr,
+ Node templateNode,
+ Node qdmNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ XmlProcessor templateXMLProcessor,
+ Node attributeQDMNode)
+ throws XPathExpressionException {
+ String oidValue = templateNode.getAttributes().getNamedItem(OID).getNodeValue();
+ String classCodeValue = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
+ String moodValue = templateNode.getAttributes().getNamedItem(MOOD).getNodeValue();
+ String statusValue = templateNode.getAttributes().getNamedItem("status").getNodeValue();
+ String rootValue = qdmNode.getAttributes().getNamedItem(ID).getNodeValue();
+ String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String qdmOidValue = qdmNode.getAttributes().getNamedItem(OID).getNodeValue();
+
+ String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ String qdmTaxonomy = qdmNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
+ String entryCommentText = dataType;
+ // Local variable changes.
+ String qdmLocalVariableName = qdmName + "_" + dataType;
+ String localVariableName = qdmLocalVariableName;
+ if (qdmNode.getAttributes().getNamedItem("instance") != null) {
+ qdmLocalVariableName =
+ qdmNode.getAttributes().getNamedItem("instance").getNodeValue()
+ + "_"
+ + qdmLocalVariableName;
+ localVariableName =
+ qdmNode.getAttributes().getNamedItem("instance").getNodeValue()
+ + "of"
+ + localVariableName;
+ }
+ qdmLocalVariableName = StringUtils.deleteWhitespace(qdmLocalVariableName);
+ if (attributeQDMNode != null) {
+ if (attributeQDMNode.getUserData(ATTRIBUTE_UUID) != null) {
+ qdmLocalVariableName = (String) attributeQDMNode.getUserData(ATTRIBUTE_UUID);
+ }
+ if (attributeQDMNode.getUserData(ATTRIBUTE_NAME) != null) {
+ entryCommentText = entryCommentText + " - " + attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ localVariableName = localVariableName + "_" + attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ }
+ if (attributeQDMNode.getUserData(ATTRIBUTE_MODE) != null) {
+ entryCommentText =
+ entryCommentText + " With " + attributeQDMNode.getUserData(ATTRIBUTE_MODE);
+ localVariableName = localVariableName + "_" + attributeQDMNode.getUserData(ATTRIBUTE_MODE);
+ }
+ }
+ localVariableName = StringUtils.deleteWhitespace(localVariableName);
+
+ Element dataCriteriaSectionElem =
+ (Element)
+ dataCriteriaXMLProcessor
+ .getOriginalDoc()
+ .getElementsByTagName("dataCriteriaSection")
+ .item(0);
+ Element componentElem =
+ (Element)
+ dataCriteriaXMLProcessor.getOriginalDoc().getElementsByTagName("component").item(0);
+ Attr nameSpaceAttr = dataCriteriaXMLProcessor.getOriginalDoc().createAttribute("xmlns:xsi");
+ nameSpaceAttr.setNodeValue(nameSpace);
+ componentElem.setAttributeNodeNS(nameSpaceAttr);
+ Attr qdmNameSpaceAttr = dataCriteriaXMLProcessor.getOriginalDoc().createAttribute("xmlns:qdm");
+ qdmNameSpaceAttr.setNodeValue("urn:hhs-qdm:hqmf-r2-extensions:v1");
+ componentElem.setAttributeNodeNS(qdmNameSpaceAttr);
+ // creating Entry Tag
+ Element entryElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement("entry");
+ entryElem.setAttribute(TYPE_CODE, "DRIV");
+ // Local Variable Name Tag - Inside Entry tag.
+ Element localVarElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement("localVariableName");
+ localVarElem.setAttribute(VALUE, localVariableName + "_" + UUIDUtilClient.uuid(5));
+ entryElem.appendChild(localVarElem);
+ Element dataCriteriaElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(actNodeStr);
+ entryElem.appendChild(dataCriteriaElem);
+ dataCriteriaElem.setAttribute(CLASS_CODE, classCodeValue);
+ dataCriteriaElem.setAttribute(MOOD_CODE, moodValue);
+ Element templateId = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
+ dataCriteriaElem.appendChild(templateId);
+ Element itemChild = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ITEM);
+ itemChild.setAttribute(ROOT, oidValue);
+ if (templateNode.getAttributes().getNamedItem("addExtensionInTemplate") == null) {
+
+ itemChild.setAttribute("extension", extensionValue);
+ }
+ templateId.appendChild(itemChild);
+ Element idElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ID);
+ idElem.setAttribute(ROOT, rootValue);
+ idElem.setAttribute("extension", qdmLocalVariableName);
+ dataCriteriaElem.appendChild(idElem);
+
+ boolean appendEntryElem = false;
+ String occurString = dataType + "-" + qdmOidValue;
+
+ if (qdmNode.getAttributes().getNamedItem("instance") != null) {
+ generateOutboundForOccur(
+ templateNode,
+ qdmNode,
+ dataCriteriaElem,
+ occurString,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor);
+ entryCommentText =
+ qdmNode.getAttributes().getNamedItem("instance").getNodeValue() + " " + entryCommentText;
+ appendEntryElem = true;
+ } else if (!occurrenceMap.containsKey(occurString) || (attributeQDMNode != null)) {
+
+ String isAddCodeTag = templateNode.getAttributes().getNamedItem("addCodeTag").getNodeValue();
+ if ("true".equalsIgnoreCase(isAddCodeTag)) { // Add Code Element to DataCriteria Element.
+ addCodeElementToDataCriteriaElement(
+ templateNode, dataCriteriaXMLProcessor, qdmNode, dataCriteriaElem);
+ }
+ Element titleElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TITLE);
+ titleElem.setAttribute(VALUE, dataType);
+ dataCriteriaElem.appendChild(titleElem);
+ Element statusCodeElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement("statusCode");
+ statusCodeElem.setAttribute(CODE, statusValue);
+ dataCriteriaElem.appendChild(statusCodeElem);
+ // Add value tag in entry element.
+ String addValueSetElement =
+ templateNode.getAttributes().getNamedItem("addValueTag").getNodeValue();
+ if ("true".equalsIgnoreCase(addValueSetElement)) {
+ Element valueElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(VALUE);
+ Node valueTypeAttr = templateNode.getAttributes().getNamedItem("valueType");
+ if (valueTypeAttr != null) {
+ valueElem.setAttribute(XSI_TYPE, valueTypeAttr.getNodeValue());
+ }
+
+ Node valueCodeSystem = templateNode.getAttributes().getNamedItem("valueCodeSystem");
+ Node valueCode = templateNode.getAttributes().getNamedItem("valueCode");
+ Node valueDisplayName = templateNode.getAttributes().getNamedItem("valueDisplayName");
+ Node valueCodeSystemName = templateNode.getAttributes().getNamedItem("valueCodeSystemName");
+
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ if ((valueCode != null) && (valueCodeSystem != null)) {
+ valueElem.setAttribute("code", valueCode.getNodeValue());
+ valueElem.setAttribute("codeSystem", valueCodeSystem.getNodeValue());
+ if (valueCodeSystemName != null) {
+ valueElem.setAttribute("codeSystemName", valueCodeSystemName.getNodeValue());
+ }
+ if (valueDisplayName != null) {
+ displayNameElem.setAttribute(VALUE, valueDisplayName.getNodeValue());
+ }
+ } else {
+ valueElem.setAttribute("valueSet", qdmOidValue);
+ addValueSetVersion(qdmNode, valueElem);
+ displayNameElem.setAttribute(
+ VALUE,
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(qdmName)
+ + " "
+ + qdmTaxonomy
+ + " Value Set");
+ }
+ if (displayNameElem.hasAttribute(VALUE)) {
+ valueElem.appendChild(displayNameElem);
+ }
+
+ dataCriteriaElem.appendChild(valueElem);
+ }
+ if (templateNode.getAttributes().getNamedItem("includeSubTemplate") != null) {
+ appendSubTemplateNode(
+ templateNode,
+ dataCriteriaXMLProcessor,
+ templateXMLProcessor,
+ dataCriteriaElem,
+ qdmNode,
+ attributeQDMNode);
+ }
+
+ appendEntryElem = true;
+ }
+ if (appendEntryElem) {
+ if (attributeQDMNode != null) {
+ createDataCriteriaForAttributes(
+ qdmNode,
+ dataCriteriaElem,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ attributeQDMNode,
+ false);
+ }
+ dataCriteriaSectionElem.appendChild(entryElem);
+ }
+ }
+
+ /**
+ * Method to add valueSetVersion attribute in value element tag.
+ *
+ * @param qdmNode the qdm node
+ * @param valueElem the value elem
+ */
+ protected void addValueSetVersion(Node qdmNode, Element valueElem) {
+ String valueSetVersion = qdmNode.getAttributes().getNamedItem("version").getNodeValue();
+ boolean addVersionToValueTag = false;
+ if ("1.0".equals(valueSetVersion)
+ || "1".equals(valueSetVersion)
+ || StringUtils.isBlank(valueSetVersion)) {
+ if (qdmNode.getAttributes().getNamedItem("expansionIdentifier") != null) {
+ valueSetVersion =
+ "mat.vsac:profile:"
+ + qdmNode.getAttributes().getNamedItem("expansionIdentifier").getNodeValue();
+ addVersionToValueTag = true;
+ } else {
+ addVersionToValueTag = false;
+ }
+ } else {
+ valueSetVersion =
+ "mat.vsac:version:" + qdmNode.getAttributes().getNamedItem("version").getNodeValue();
+ addVersionToValueTag = true;
+ }
+ if (addVersionToValueTag) {
+ valueElem.setAttribute("valueSetVersion", valueSetVersion);
+ }
+ }
+
+ /**
+ * Generate outbound for occur.
+ *
+ * @param templateNode the template node
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem the data criteria elem
+ * @param occurString the occur string
+ */
+ private void generateOutboundForOccur(
+ Node templateNode,
+ Node qdmNode,
+ Element dataCriteriaElem,
+ String occurString,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor) {
+ Node refNode = occurrenceMap.get(occurString);
+
+ logger.debug("In generateOutboundForOccur()..refNode:" + refNode);
+ logger.debug("----------Occurance map:" + occurrenceMap);
+
+ if (refNode != null) {
+
+ try {
+ Node cloneRefNode = refNode.cloneNode(true);
+ String name = cloneRefNode.getAttributes().getNamedItem("name").getNodeValue();
+ String occName = qdmNode.getAttributes().getNamedItem("instance").getNodeValue();
+ cloneRefNode.getAttributes().getNamedItem("name").setNodeValue(occName + "_" + name);
+
+ if (!occurrenceMap.containsKey(occName + occurString)) {
+ occurrenceMap.remove(occurString);
+ generateQDMEntry(dataCriteriaXMLProcessor, simpleXmlprocessor, cloneRefNode, true);
+ occurrenceMap.put(occurString, refNode);
+ occurrenceMap.put(occName + occurString, cloneRefNode);
+ }
+
+ String refRootValue = cloneRefNode.getAttributes().getNamedItem(ID).getNodeValue();
+
+ String refDatatype = cloneRefNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String refQdmName = cloneRefNode.getAttributes().getNamedItem("name").getNodeValue();
+ String reExt = StringUtils.deleteWhitespace(refQdmName + "_" + refDatatype);
+
+ Element outboundRelElem =
+ dataCriteriaElem.getOwnerDocument().createElement("outboundRelationship");
+ outboundRelElem.setAttribute("typeCode", "OCCR");
+
+ Element criteriaRefElem =
+ dataCriteriaElem.getOwnerDocument().createElement("criteriaReference");
+ String refClassCodeValue = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
+ String refMoodValue = templateNode.getAttributes().getNamedItem(MOOD).getNodeValue();
+ criteriaRefElem.setAttribute(CLASS_CODE, refClassCodeValue);
+ criteriaRefElem.setAttribute(MOOD_CODE, refMoodValue);
+
+ Element idRelElem = dataCriteriaElem.getOwnerDocument().createElement(ID);
+ idRelElem.setAttribute(ROOT, refRootValue);
+ idRelElem.setAttribute("extension", reExt);
+
+ criteriaRefElem.appendChild(idRelElem);
+ outboundRelElem.appendChild(criteriaRefElem);
+ dataCriteriaElem.appendChild(outboundRelElem);
+ Node templateIdNode = dataCriteriaElem.getElementsByTagName("templateId").item(0);
+ dataCriteriaElem.removeChild(templateIdNode);
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Add Code Element To data Criteria Element based on condition.
+ *
+ * @param templateNode - Node
+ * @param dataCriteriaXMLProcessor - XmlProcessor
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem - Element
+ */
+ private void addCodeElementToDataCriteriaElement(
+ Node templateNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ Node qdmNode,
+ Element dataCriteriaElem) {
+ String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String qdmOidValue = qdmNode.getAttributes().getNamedItem(OID).getNodeValue();
+
+ String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ String qdmTaxonomy = qdmNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
+
+ // Patient Characteristic data type - contains code tag with valueSetId
+ // attribute and no title and value set tag.
+ boolean isPatientChar = templateNode.getAttributes().getNamedItem("valueSetId") != null;
+ boolean isAddValueSetInCodeTrue =
+ templateNode.getAttributes().getNamedItem("addValueSetInCode") != null;
+ boolean isIntervention =
+ ("Intervention, Order".equals(dataType)
+ || "Intervention, Performed".equals(dataType)
+ || "Intervention, Recommended".equals(dataType));
+ if (isAddValueSetInCodeTrue) {
+ Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ Node valueTypeAttr = templateNode.getAttributes().getNamedItem("valueType");
+ if (valueTypeAttr != null) {
+ codeElem.setAttribute(XSI_TYPE, valueTypeAttr.getNodeValue());
+ }
+ codeElem.setAttribute("valueSet", qdmOidValue);
+ addValueSetVersion(qdmNode, codeElem);
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ String displayName = "";
+ displayName =
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(qdmName)
+ + " "
+ + qdmTaxonomy
+ + " Value Set";
+ displayNameElem.setAttribute(VALUE, displayName);
+ codeElem.appendChild(displayNameElem);
+ dataCriteriaElem.appendChild(codeElem);
+
+ } else if (isPatientChar) {
+ Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ codeElem.setAttribute(
+ templateNode.getAttributes().getNamedItem("valueSetId").getNodeValue(), qdmOidValue);
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ displayNameElem.setAttribute(
+ VALUE,
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(qdmName)
+ + " "
+ + qdmTaxonomy
+ + " Value Set");
+ codeElem.appendChild(displayNameElem);
+ dataCriteriaElem.appendChild(codeElem);
+ } else if (isIntervention) {
+ Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ codeElem.setAttribute("valueSet", qdmOidValue);
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ displayNameElem.setAttribute(
+ VALUE,
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(qdmName)
+ + " "
+ + qdmTaxonomy
+ + " Value Set");
+ codeElem.appendChild(displayNameElem);
+ dataCriteriaElem.appendChild(codeElem);
+ } else {
+ Element codeElement = createCodeForDatatype(templateNode, dataCriteriaXMLProcessor);
+ if (codeElement != null) {
+ dataCriteriaElem.appendChild(codeElement);
+ }
+ }
+ }
+
+ /**
+ * This method is called for populating version/expansion Identifier of value set when value set
+ * attribute mode is applied. If version is most recent, 1.0 or 1 is returned.
+ *
+ * @param qdmNode
+ * @return version
+ */
+ private String valueSetVersionStringValue(Node qdmNode) {
+ String version = qdmNode.getAttributes().getNamedItem("version").getNodeValue();
+ if ("1.0".equals(version) || "1".equals(version) || StringUtils.isBlank(version)) {
+ if (qdmNode.getAttributes().getNamedItem("expansionIdentifier") != null) {
+ version =
+ "mat.vsac:profile:"
+ + qdmNode.getAttributes().getNamedItem("expansionIdentifier").getNodeValue();
+ }
+ } else {
+ version =
+ "mat.vsac:version:" + qdmNode.getAttributes().getNamedItem("version").getNodeValue();
+ }
+ return version;
+ }
+
+ /**
+ * Add SubTemplate defined in Template.xml to data criteria Element.
+ *
+ * @param templateNode - Node
+ * @param dataCriteriaXMLProcessor - XmlProcessor for Data Criteria
+ * @param templateXMLProcessor -XmlProcessor for Template Xml.
+ * @param dataCriteriaElem - Element
+ * @param qdmNode the qdm node
+ * @param attributeQDMNode the attribute qdm node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void appendSubTemplateNode(
+ Node templateNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor templateXMLProcessor,
+ Element dataCriteriaElem,
+ Node qdmNode,
+ Node attributeQDMNode)
+ throws XPathExpressionException {
+ String subTemplateName =
+ templateNode.getAttributes().getNamedItem("includeSubTemplate").getNodeValue();
+ Node subTemplateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(), "/templates/subtemplates/" + subTemplateName);
+ NodeList subTemplateNodeChilds =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "/child::node()");
+ String qdmOidValue = qdmNode.getAttributes().getNamedItem(OID).getNodeValue();
+ String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ String qdmNameDataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String qdmTaxonomy = qdmNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
+ if (subTemplateNode.getAttributes().getNamedItem("changeAttribute") != null) {
+ String[] attributeToBeModified =
+ subTemplateNode.getAttributes().getNamedItem("changeAttribute").getNodeValue().split(",");
+ for (String changeAttribute : attributeToBeModified) {
+ NodeList attributedToBeChangedInNode = null;
+ attributedToBeChangedInNode =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "//" + changeAttribute);
+ if (changeAttribute.equalsIgnoreCase(ID)) {
+ String rootId = qdmNode.getAttributes().getNamedItem("uuid").getNodeValue();
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("root")
+ .setNodeValue(rootId);
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("extension")
+ .setNodeValue(UUIDUtilClient.uuid());
+ } else if (changeAttribute.equalsIgnoreCase(CODE)) {
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("valueSet")
+ .setNodeValue(qdmOidValue);
+ String valueSetVersion = valueSetVersionStringValue(qdmNode);
+ if (valueSetVersion.contains("mat/vsacmodel")) {
+ Attr attrNode =
+ attributedToBeChangedInNode
+ .item(0)
+ .getOwnerDocument()
+ .createAttribute("valueSetVersion");
+ attrNode.setNodeValue(valueSetVersion);
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attrNode);
+ } else {
+ if (attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("valueSetVersion")
+ != null) {
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .removeNamedItem("valueSetVersion");
+ }
+ }
+
+ } else if (changeAttribute.equalsIgnoreCase(DISPLAY_NAME)) {
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("value")
+ .setNodeValue(
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(qdmName)
+ + " "
+ + qdmTaxonomy
+ + " value set");
+ } else if (changeAttribute.equalsIgnoreCase(TITLE)) {
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("value")
+ .setNodeValue(qdmNameDataType);
+ } else if (changeAttribute.equalsIgnoreCase(ITEM)) {
+ for (int count = 0; count < attributedToBeChangedInNode.getLength(); count++) {
+ Node itemNode = attributedToBeChangedInNode.item(count);
+ itemNode.getAttributes().getNamedItem("extension").setNodeValue(extensionValue);
+ }
+ }
+ }
+ }
+ for (int i = 0; i < subTemplateNodeChilds.getLength(); i++) {
+ Node childNode = subTemplateNodeChilds.item(i);
+ Node nodeToAttach = dataCriteriaXMLProcessor.getOriginalDoc().importNode(childNode, true);
+ XmlProcessor.clean(nodeToAttach);
+ dataCriteriaElem.appendChild(nodeToAttach);
+ }
+ }
+
+ /**
+ * Method to append Facility Location attribute template to data type. This attribute can only
+ * have value ser and Check If present mode's and these are added to code tag.
+ *
+ * @param templateNode the template node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param templateXMLProcessor the template xml processor
+ * @param dataCriteriaElem the data criteria elem
+ * @param attrNode the attr node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void appendSubTemplateInFacilityAttribute(
+ Node templateNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor templateXMLProcessor,
+ Element dataCriteriaElem,
+ Node attrNode)
+ throws XPathExpressionException {
+ String subTemplateName =
+ templateNode.getAttributes().getNamedItem("includeSubTemplate").getNodeValue();
+ Node subTemplateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(), "/templates/subtemplates/" + subTemplateName);
+ NodeList subTemplateNodeChilds =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "/child::node()");
+ if (subTemplateNode.getAttributes().getNamedItem("changeAttribute") != null) {
+ NodeList attributedToBeChangedInNode = null;
+ String[] tagToBeModified =
+ subTemplateNode.getAttributes().getNamedItem("changeAttribute").getNodeValue().split(",");
+ for (String changeAttribute : tagToBeModified) {
+ attributedToBeChangedInNode =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "//" + changeAttribute);
+ if (changeAttribute.equalsIgnoreCase(ID)) {
+ Node childNodes = attributedToBeChangedInNode.item(0).getFirstChild().getNextSibling();
+ String rootId = (String) attrNode.getUserData(ATTRIBUTE_UUID);
+ childNodes.getAttributes().getNamedItem("root").setNodeValue(rootId);
+ childNodes
+ .getAttributes()
+ .getNamedItem("extension")
+ .setNodeValue(
+ StringUtils.deleteWhitespace((String) attrNode.getUserData(ATTRIBUTE_NAME)));
+ } else if (changeAttribute.equalsIgnoreCase(CODE)) {
+ String attrMode = (String) attrNode.getUserData(ATTRIBUTE_MODE);
+ if (VALUE_SET.equals(attrMode)) {
+ if (attributedToBeChangedInNode.item(0).hasAttributes()) {
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("flavorId");
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("xsi:type");
+ }
+ if (attributedToBeChangedInNode.item(0).hasChildNodes()) {
+ ((Element) attributedToBeChangedInNode.item(0))
+ .removeChild(attributedToBeChangedInNode.item(0).getFirstChild());
+ }
+ checkIfSelectedModeIsValueSet(
+ templateXMLProcessor,
+ attrNode,
+ subTemplateNode,
+ (Element) attributedToBeChangedInNode.item(0));
+ } else if (CHECK_IF_PRESENT.equals(attrMode)) {
+ if (attributedToBeChangedInNode.item(0).hasAttributes()) {
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("valueSet");
+ }
+ if (attributedToBeChangedInNode.item(0).hasChildNodes()) {
+ ((Element) attributedToBeChangedInNode.item(0))
+ .removeChild(attributedToBeChangedInNode.item(0).getFirstChild());
+ }
+ checkIfSelectedModeIsPresent(
+ templateXMLProcessor,
+ attrNode,
+ subTemplateNode,
+ (Element) attributedToBeChangedInNode.item(0));
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("xsi:type");
+ }
+ } else if (changeAttribute.equalsIgnoreCase(ITEM)) {
+ for (int count = 0; count < attributedToBeChangedInNode.getLength(); count++) {
+ Node itemNode = attributedToBeChangedInNode.item(count);
+ itemNode.getAttributes().getNamedItem("extension").setNodeValue(extensionValue);
+ }
+ }
+ }
+ }
+ for (int i = 0; i < subTemplateNodeChilds.getLength(); i++) {
+ Node childNode = subTemplateNodeChilds.item(i);
+ Node nodeToAttach = dataCriteriaXMLProcessor.getOriginalDoc().importNode(childNode, true);
+ XmlProcessor.clean(nodeToAttach);
+ checkIfOutBoundOcc(dataCriteriaElem, nodeToAttach);
+ }
+ }
+
+ /**
+ * Append sub template with order attribute.
+ *
+ * @param templateNode the template node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param templateXMLProcessor the template xml processor
+ * @param dataCriteriaElem the data criteria elem
+ * @param qdmNode the qdm node
+ * @param attrNode the attr node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void appendSubTemplateWithOrderAttribute(
+ Node templateNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor templateXMLProcessor,
+ Element dataCriteriaElem,
+ Node qdmNode,
+ Node attrNode)
+ throws XPathExpressionException {
+ String subTemplateName =
+ templateNode.getAttributes().getNamedItem("includeOtherSubTemplate").getNodeValue();
+ Node subTemplateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(), "/templates/subtemplates/" + subTemplateName);
+ NodeList subTemplateNodeChilds =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "/child::node()");
+ boolean isOrder = templateNode.getAttributes().getNamedItem("typeOrder").getNodeValue() != null;
+ if (subTemplateNode.getAttributes().getNamedItem("changeAttribute") != null) {
+ NodeList attributedToBeChangedInNode = null;
+ String[] tagToBeModified =
+ subTemplateNode.getAttributes().getNamedItem("changeAttribute").getNodeValue().split(",");
+ for (String changeAttribute : tagToBeModified) {
+ attributedToBeChangedInNode =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "//" + changeAttribute);
+ if (changeAttribute.equalsIgnoreCase(ID)) {
+ Node childNodes = attributedToBeChangedInNode.item(0).getFirstChild().getNextSibling();
+ String rootId = (String) attrNode.getUserData(ATTRIBUTE_UUID);
+ childNodes.getAttributes().getNamedItem("root").setNodeValue(rootId);
+ childNodes
+ .getAttributes()
+ .getNamedItem("extension")
+ .setNodeValue(
+ StringUtils.deleteWhitespace((String) attrNode.getUserData(ATTRIBUTE_NAME)));
+ } else if (changeAttribute.equalsIgnoreCase(ITEM)) {
+ for (int count = 0; count < attributedToBeChangedInNode.getLength(); count++) {
+ Node itemNode = attributedToBeChangedInNode.item(count);
+ itemNode.getAttributes().getNamedItem("extension").setNodeValue(extensionValue);
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < subTemplateNodeChilds.getLength(); i++) {
+ Node childNode = subTemplateNodeChilds.item(i);
+ Node nodeToAttach = dataCriteriaXMLProcessor.getOriginalDoc().importNode(childNode, true);
+ XmlProcessor.clean(nodeToAttach);
+ checkIfOutBoundOcc(dataCriteriaElem, nodeToAttach);
+ }
+ Element timeNode = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TIME);
+ generateDateTimeAttributesTag(
+ timeNode, attrNode, dataCriteriaElem, dataCriteriaXMLProcessor, isOrder);
+ }
+
+ /**
+ * Append sub template and add value tag based on mode.
+ *
+ * @param templateNode the template node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param templateXMLProcessor the template xml processor
+ * @param dataCriteriaElem the data criteria elem
+ * @param attrNode the attr node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ protected void appendSubTemplateAndAddValueTagBasedOnMode(
+ Node templateNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor templateXMLProcessor,
+ Element dataCriteriaElem,
+ Node attrNode)
+ throws XPathExpressionException {
+
+ String subTemplateName =
+ templateNode.getAttributes().getNamedItem("includeSubTemplate").getNodeValue();
+ Node subTemplateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(), "/templates/subtemplates/" + subTemplateName);
+
+ if (subTemplateNode.getAttributes().getNamedItem("changeAttribute") != null) {
+ NodeList attributedToBeChangedInNode = null;
+ String[] tagToBeModified =
+ subTemplateNode.getAttributes().getNamedItem("changeAttribute").getNodeValue().split(",");
+ for (String changeAttribute : tagToBeModified) {
+ attributedToBeChangedInNode =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "//" + changeAttribute);
+ if (changeAttribute.equalsIgnoreCase(ID)) {
+ String rootId = (String) attrNode.getUserData(ATTRIBUTE_UUID);
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("root")
+ .setNodeValue(rootId);
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("extension")
+ .setNodeValue(UUIDUtilClient.uuid());
+ } else if (changeAttribute.equalsIgnoreCase(ITEM)) {
+ for (int count = 0; count < attributedToBeChangedInNode.getLength(); count++) {
+ Node itemNode = attributedToBeChangedInNode.item(count);
+ itemNode.getAttributes().getNamedItem("extension").setNodeValue(UUIDUtilClient.uuid());
+ String rootId = (String) attrNode.getUserData(ATTRIBUTE_UUID);
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("root")
+ .setNodeValue(rootId);
+ }
+
+ } else if (changeAttribute.equalsIgnoreCase(VALUE)) {
+ String attrMode = (String) attrNode.getUserData(ATTRIBUTE_MODE);
+ if (CHECK_IF_PRESENT.equals(attrMode)) {
+ if (attributedToBeChangedInNode.item(0).hasAttributes()) {
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("valueSet");
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("flavorId");
+ }
+ String elementName =
+ templateNode.getAttributes().getNamedItem("addTagInValueSet").getNodeValue();
+ NodeList el = attributedToBeChangedInNode.item(0).getChildNodes();
+ Element childElement = null;
+ if (el.getLength() == 0) {
+ childElement =
+ attributedToBeChangedInNode.item(0).getOwnerDocument().createElement(elementName);
+ } else {
+ childElement = (Element) el;
+ if (childElement.hasChildNodes()) {
+ for (int j = childElement.getChildNodes().getLength(); j > 0; j--) {
+ Node ChildNode = childElement.getChildNodes().item(j - 1);
+ childElement.removeChild(ChildNode);
+ }
+ }
+ childElement =
+ attributedToBeChangedInNode.item(0).getOwnerDocument().createElement(elementName);
+ }
+ childElement.setAttribute(FLAVOR_ID, "ANY.NONNULL");
+ attributedToBeChangedInNode.item(0).appendChild(childElement);
+ } else if (attrMode.startsWith(Generator.LESS_THAN)
+ || attrMode.startsWith(Generator.GREATER_THAN)
+ || attrMode.equals(Generator.EQUAL_TO)) {
+
+ String elementName =
+ templateNode.getAttributes().getNamedItem("addTagInValueSet").getNodeValue();
+ NodeList el = attributedToBeChangedInNode.item(0).getChildNodes();
+ Element childElement = null;
+ if (el.getLength() == 0) {
+ childElement =
+ attributedToBeChangedInNode.item(0).getOwnerDocument().createElement(elementName);
+ } else {
+ childElement = (Element) el;
+ if (childElement.hasChildNodes()) {
+ for (int j = childElement.getChildNodes().getLength(); j > 0; j--) {
+ Node ChildNode = childElement.getChildNodes().item(j - 1);
+ childElement.removeChild(ChildNode);
+ }
+ }
+ childElement =
+ attributedToBeChangedInNode.item(0).getOwnerDocument().createElement(elementName);
+ }
+ Node unitAttrib = attrNode.getAttributes().getNamedItem("unit");
+ if (attrMode.equals(Generator.EQUAL_TO)) {
+ childElement.setAttribute(
+ "value", attrNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ if (unitAttrib != null) {
+ childElement.setAttribute("unit", getUnitString(unitAttrib.getNodeValue()));
+ }
+ attributedToBeChangedInNode.item(0).appendChild(childElement);
+ } else if (attrMode.startsWith(Generator.LESS_THAN)) {
+ Element uncertainRangeNode =
+ childElement.getOwnerDocument().createElement("uncertainRange");
+ if (attrMode.equals(Generator.LESS_THAN)) {
+ uncertainRangeNode.setAttribute("highClosed", "false");
+ }
+ Element lowNode = childElement.getOwnerDocument().createElement(LOW);
+ lowNode.setAttribute(XSI_TYPE, "PQ");
+ lowNode.setAttribute("nullFlavor", "NINF");
+
+ Element highNode = childElement.getOwnerDocument().createElement(HIGH);
+ highNode.setAttribute(XSI_TYPE, "PQ");
+ highNode.setAttribute(
+ "value", attrNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ if (unitAttrib != null) {
+ highNode.setAttribute("unit", getUnitString(unitAttrib.getNodeValue()));
+ }
+ uncertainRangeNode.appendChild(lowNode);
+ uncertainRangeNode.appendChild(highNode);
+ childElement.appendChild(uncertainRangeNode);
+ attributedToBeChangedInNode.item(0).appendChild(childElement);
+ } else if (attrMode.startsWith(Generator.GREATER_THAN)) {
+ Element uncertainRangeNode =
+ childElement.getOwnerDocument().createElement("uncertainRange");
+ if (attrMode.equals(Generator.GREATER_THAN)) {
+ uncertainRangeNode.setAttribute("lowClosed", "false");
+ }
+ Element lowNode = childElement.getOwnerDocument().createElement(LOW);
+ lowNode.setAttribute(XSI_TYPE, "PQ");
+ lowNode.setAttribute(
+ "value", attrNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ if (unitAttrib != null) {
+ lowNode.setAttribute("unit", getUnitString(unitAttrib.getNodeValue()));
+ }
+ Element highNode = childElement.getOwnerDocument().createElement(HIGH);
+ highNode.setAttribute(XSI_TYPE, "PQ");
+ highNode.setAttribute("nullFlavor", "PINF");
+ uncertainRangeNode.appendChild(lowNode);
+ uncertainRangeNode.appendChild(highNode);
+ childElement.appendChild(uncertainRangeNode);
+ attributedToBeChangedInNode.item(0).appendChild(childElement);
+ }
+ }
+ } else if (changeAttribute.equalsIgnoreCase(CODE)) {
+ String attrMode = (String) attrNode.getUserData(ATTRIBUTE_MODE);
+ if (CHECK_IF_PRESENT.equals(attrMode)) {
+ if (attributedToBeChangedInNode.item(0).hasAttributes()) {
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("valueSet");
+ }
+ if (attributedToBeChangedInNode.item(0).hasChildNodes()) {
+ attributedToBeChangedInNode
+ .item(0)
+ .removeChild(attributedToBeChangedInNode.item(0).getFirstChild());
+ }
+ Attr attribute =
+ attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("flavorId");
+ attribute.setNodeValue("ANY.NONNULL");
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attribute);
+ } else if (VALUE_SET.equalsIgnoreCase(attrMode)) {
+
+ String valueSetVersion = valueSetVersionStringValue(attrNode);
+ if (valueSetVersion.contains("mat/vsacmodel")) {
+ Attr valuesetVersionAttr =
+ attributedToBeChangedInNode
+ .item(0)
+ .getOwnerDocument()
+ .createAttribute("valueSetVersion");
+ valuesetVersionAttr.setNodeValue(valueSetVersion);
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(valuesetVersionAttr);
+ } else {
+ if (attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("valueSetVersion")
+ != null) {
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .removeNamedItem("valueSetVersion");
+ }
+ }
+ if (attributedToBeChangedInNode.item(0).hasAttributes()) {
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("flavorId");
+ }
+ if (attributedToBeChangedInNode.item(0).hasChildNodes()) {
+ ((Element) attributedToBeChangedInNode.item(0))
+ .removeChild(attributedToBeChangedInNode.item(0).getFirstChild());
+ }
+ String attributeValueSetName =
+ attrNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ String attributeOID = attrNode.getAttributes().getNamedItem(OID).getNodeValue();
+ String attributeTaxonomy =
+ attrNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
+ Attr attribute =
+ attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("valueSet");
+ attribute.setNodeValue(attributeOID);
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attribute);
+ Element valueDisplayNameElem =
+ attributedToBeChangedInNode.item(0).getOwnerDocument().createElement(DISPLAY_NAME);
+ valueDisplayNameElem.setAttribute(
+ VALUE,
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(attributeValueSetName)
+ + " "
+ + attributeTaxonomy
+ + " Value Set");
+ attributedToBeChangedInNode.item(0).appendChild(valueDisplayNameElem);
+ }
+ }
+ }
+ }
+ for (int i = 0; i < subTemplateNode.getChildNodes().getLength(); i++) {
+ Node childNode = subTemplateNode.getChildNodes().item(i);
+ Node nodeToAttach = dataCriteriaXMLProcessor.getOriginalDoc().importNode(childNode, true);
+ XmlProcessor.clean(nodeToAttach);
+ checkIfOutBoundOcc(dataCriteriaElem, nodeToAttach);
+ }
+ }
+
+ /**
+ * This method will look for attributes used in the subTree logic and then generate appropriate
+ * data criteria entries.
+ *
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem the data criteria elem
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param attributeQDMNode the attribute qdm node
+ * @param isFunctionAttributeFlow - boolean function Attribute flow.
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void createDataCriteriaForAttributes(
+ Node qdmNode,
+ Element dataCriteriaElem,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ Node attributeQDMNode,
+ boolean isFunctionAttributeFlow)
+ throws XPathExpressionException {
+ String attributeName = (String) attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ String attributeMode = (String) attributeQDMNode.getUserData(ATTRIBUTE_MODE);
+ boolean checkForMode = false;
+ switch (attributeName.toLowerCase()) {
+ case NEGATION_RATIONALE:
+ if (!isFunctionAttributeFlow) {
+ generateNegationRationalEntries(
+ qdmNode,
+ dataCriteriaElem,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ attributeQDMNode);
+ }
+ break;
+ case START_DATETIME:
+ case STOP_DATETIME:
+ case SIGNED_DATETIME:
+ case RECORDED_DATETIME:
+ case ABATEMENT_DATETIME:
+ generateOrderTypeAttributes(
+ qdmNode,
+ dataCriteriaElem,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ attributeQDMNode);
+ break;
+ case ADMISSION_DATETIME:
+ case DISCHARGE_DATETIME:
+ case REMOVAL_DATETIME:
+ case ACTIVE_DATETIME:
+ case TIME:
+ case DATE:
+ case ONSET_DATETIME:
+ generateDateTimeAttributes(
+ qdmNode,
+ dataCriteriaElem,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ attributeQDMNode);
+ break;
+ case FACILITY_LOCATION_ARRIVAL_DATETIME:
+ case FACILITY_LOCATION_DEPARTURE_DATETIME:
+ generateFacilityLocationTypeAttributes(
+ qdmNode,
+ dataCriteriaElem,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ attributeQDMNode);
+ break;
+ case DOSE:
+ case LENGTH_OF_STAY:
+ generateDoseTypeAttributes(
+ qdmNode,
+ dataCriteriaElem,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ attributeQDMNode);
+ break;
+ case REFILLS:
+ generateRepeatNumber(
+ qdmNode, dataCriteriaXMLProcessor, dataCriteriaElem, attributeQDMNode, REPEAT_NUMBER);
+ break;
+ case DISCHARGE_STATUS:
+ generateDischargeStatus(
+ qdmNode, dataCriteriaXMLProcessor, dataCriteriaElem, attributeQDMNode);
+ break;
+ case INCISION_DATETIME:
+ generateIncisionDateTimeTypeAttributes(
+ qdmNode,
+ dataCriteriaElem,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ attributeQDMNode);
+ break;
+ case PRINCIPAL_DIAGNOSIS:
+ case DIAGNOSIS:
+ generatePrincipalAndDiagnosisAttributes(
+ qdmNode,
+ dataCriteriaElem,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ attributeQDMNode);
+ break;
+ default:
+ checkForMode = true;
+ break;
+ }
+ if (checkForMode) {
+ if (VALUE_SET.equals(attributeMode)
+ || CHECK_IF_PRESENT.equals(attributeMode)
+ || attributeMode.startsWith(LESS_THAN)
+ || attributeMode.startsWith(GREATER_THAN)
+ || EQUAL_TO.equals(attributeMode)) {
+ // handle "Value Set", "Check If Present" and comparison(less than, greater
+ // than, equals) mode
+ generateOtherAttributes(
+ qdmNode,
+ dataCriteriaElem,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ attributeQDMNode);
+ }
+ }
+ }
+
+ /**
+ * Generate dose type attributes.
+ *
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem the data criteria elem
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param attributeQDMNode the attribute qdm node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ protected void generateDoseTypeAttributes(
+ Node qdmNode,
+ Element dataCriteriaElem,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ Node attributeQDMNode)
+ throws XPathExpressionException {
+
+ String attrName = (String) attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ String attrMode = (String) attributeQDMNode.getUserData(ATTRIBUTE_MODE);
+ Node attrOID = attributeQDMNode.getAttributes().getNamedItem(OID);
+ XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(4.3);
+ Node templateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/AttrTemplate[text()='" + attrName.toLowerCase() + "']");
+ Node targetNode = templateNode.getAttributes().getNamedItem("target");
+ Element targetQuantityTag = null;
+ if (targetNode != null) {
+ targetQuantityTag =
+ dataCriteriaElem.getOwnerDocument().createElement(targetNode.getNodeValue());
+ }
+ Node unitAttrib = attributeQDMNode.getAttributes().getNamedItem("unit");
+ if (CHECK_IF_PRESENT.equals(attrMode)) {
+ targetQuantityTag.setAttribute(FLAVOR_ID, "ANY.NONNULL");
+ } else if (VALUE_SET.equals(attrMode)) {
+ targetQuantityTag.setAttribute(NULL_FLAVOR, "UNK");
+ Element translationNode = dataCriteriaElem.getOwnerDocument().createElement(TRANSLATION);
+ translationNode.setAttribute("valueSet", attrOID.getNodeValue());
+
+ String valueSetVersion = valueSetVersionStringValue(attributeQDMNode);
+ if (valueSetVersion.contains("mat/vsacmodel")) {
+ translationNode.setAttribute("valueSetVersion", valueSetVersion);
+ } else {
+ if (translationNode.getAttributes().getNamedItem("valueSetVersion") != null) {
+ translationNode.getAttributes().removeNamedItem("valueSetVersion");
+ }
+ }
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ String newQdmName =
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(
+ attributeQDMNode.getAttributes().getNamedItem(NAME).getNodeValue());
+ displayNameElem.setAttribute(
+ VALUE,
+ newQdmName
+ + " "
+ + attributeQDMNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue()
+ + " Value Set");
+ translationNode.appendChild(displayNameElem);
+ targetQuantityTag.appendChild(translationNode);
+ // }
+ } else if (attrMode.startsWith(Generator.LESS_THAN)
+ || attrMode.startsWith(Generator.GREATER_THAN)
+ || attrMode.equals(Generator.EQUAL_TO)) {
+ if (attrMode.equals(Generator.EQUAL_TO)) {
+ targetQuantityTag.setAttribute(
+ "value",
+ attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ if (unitAttrib != null) {
+ targetQuantityTag.setAttribute("unit", getUnitString(unitAttrib.getNodeValue()));
+ }
+ } else if (attrMode.startsWith(Generator.LESS_THAN)) {
+ Element uncertainRangeNode =
+ dataCriteriaElem.getOwnerDocument().createElement("uncertainRange");
+ if (attrMode.equals(Generator.LESS_THAN)) {
+ uncertainRangeNode.setAttribute("highClosed", "false");
+ }
+ Element lowNode = dataCriteriaElem.getOwnerDocument().createElement(LOW);
+ lowNode.setAttribute("xsi:type", "PQ");
+ lowNode.setAttribute("nullFlavor", "NINF");
+ Element highNode = dataCriteriaElem.getOwnerDocument().createElement(HIGH);
+ highNode.setAttribute("xsi:type", "PQ");
+ highNode.setAttribute(
+ "value",
+ attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ if (unitAttrib != null) {
+ highNode.setAttribute("unit", getUnitString(unitAttrib.getNodeValue()));
+ }
+
+ uncertainRangeNode.appendChild(lowNode);
+ uncertainRangeNode.appendChild(highNode);
+ targetQuantityTag.appendChild(uncertainRangeNode);
+
+ } else if (attrMode.startsWith(Generator.GREATER_THAN)) {
+ Element uncertainRangeNode =
+ dataCriteriaElem.getOwnerDocument().createElement("uncertainRange");
+ if (attrMode.equals(Generator.GREATER_THAN)) {
+ uncertainRangeNode.setAttribute("lowClosed", "false");
+ }
+ Element lowNode = dataCriteriaElem.getOwnerDocument().createElement(LOW);
+ lowNode.setAttribute("xsi:type", "PQ");
+ lowNode.setAttribute(
+ "value",
+ attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ if (unitAttrib != null) {
+ lowNode.setAttribute("unit", getUnitString(unitAttrib.getNodeValue()));
+ }
+ Element highNode = dataCriteriaElem.getOwnerDocument().createElement(HIGH);
+ highNode.setAttribute("xsi:type", "PQ");
+ highNode.setAttribute("nullFlavor", "PINF");
+ uncertainRangeNode.appendChild(lowNode);
+ uncertainRangeNode.appendChild(highNode);
+ targetQuantityTag.appendChild(uncertainRangeNode);
+ }
+ }
+ String insertAfterNodeName =
+ templateNode.getAttributes().getNamedItem("insertAfterNode").getNodeValue();
+ if (insertAfterNodeName != null) {
+ if (dataCriteriaElem.getElementsByTagName(insertAfterNodeName).item(0) != null) {
+ Node outBoundElement =
+ dataCriteriaElem.getElementsByTagName(insertAfterNodeName).item(0).getNextSibling();
+ if (outBoundElement != null) {
+ outBoundElement.getParentNode().insertBefore(targetQuantityTag, outBoundElement);
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, targetQuantityTag);
+ }
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, targetQuantityTag);
+ }
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, targetQuantityTag);
+ }
+ }
+
+ /**
+ * Generate facility location type attributes.
+ *
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem the data criteria elem
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param attributeQDMNode the attribute qdm node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ protected void generateFacilityLocationTypeAttributes(
+ Node qdmNode,
+ Element dataCriteriaElem,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ Node attributeQDMNode)
+ throws XPathExpressionException {
+ String attributeName = (String) attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(4.3);
+ Node templateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/AttrTemplate[text()='" + attributeName.toLowerCase() + "']");
+ if (templateNode == null) {
+ return;
+ }
+ if (templateNode.getAttributes().getNamedItem("includeSubTemplate") != null) {
+ appendSubTemplateInFacilityAttribute(
+ templateNode,
+ dataCriteriaXMLProcessor,
+ templateXMLProcessor,
+ dataCriteriaElem,
+ attributeQDMNode);
+ }
+ generateDateTimeAttributes(
+ qdmNode, dataCriteriaElem, dataCriteriaXMLProcessor, simpleXmlprocessor, attributeQDMNode);
+ }
+
+ /**
+ * Generate incision date time type attributes.
+ *
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem the data criteria elem
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param attributeQDMNode the attribute qdm node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ protected void generateIncisionDateTimeTypeAttributes(
+ Node qdmNode,
+ Element dataCriteriaElem,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ Node attributeQDMNode)
+ throws XPathExpressionException {
+ String attributeName = (String) attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(4.3);
+ Node templateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/AttrTemplate[text()='" + attributeName.toLowerCase() + "']");
+ if (templateNode == null) {
+ return;
+ }
+ if (templateNode.getAttributes().getNamedItem("includeSubTemplate") != null) {
+ appendSubTemplateNode(
+ templateNode,
+ dataCriteriaXMLProcessor,
+ templateXMLProcessor,
+ dataCriteriaElem,
+ qdmNode,
+ attributeQDMNode);
+ }
+ generateDateTimeAttributes(
+ qdmNode, dataCriteriaElem, dataCriteriaXMLProcessor, simpleXmlprocessor, attributeQDMNode);
+ }
+
+ /**
+ * Generate order type attributes.
+ *
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem the data criteria elem
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param attributeQDMNode the attribute qdm node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ protected void generateOrderTypeAttributes(
+ Node qdmNode,
+ Element dataCriteriaElem,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ Node attributeQDMNode)
+ throws XPathExpressionException {
+ String qdmName = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String attrName = (String) attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(4.3);
+ Node templateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/template[text()='" + qdmName.toLowerCase() + "']");
+ if (templateNode == null) {
+ return;
+ }
+ if ((templateNode.getAttributes().getNamedItem("includeOtherSubTemplate") != null)
+ || attrName.equalsIgnoreCase(SIGNED_DATETIME)
+ || attrName.equalsIgnoreCase(RECORDED_DATETIME)) {
+ appendSubTemplateWithOrderAttribute(
+ templateNode,
+ dataCriteriaXMLProcessor,
+ templateXMLProcessor,
+ dataCriteriaElem,
+ qdmNode,
+ attributeQDMNode);
+ } else {
+ generateDateTimeAttributes(
+ qdmNode,
+ dataCriteriaElem,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ attributeQDMNode);
+ }
+ }
+
+ /**
+ * Generate negation rational entries.
+ *
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem the data criteria elem
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param attributeQDMNode the attribute qdm node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void generateNegationRationalEntries(
+ Node qdmNode,
+ Element dataCriteriaElem,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ Node attributeQDMNode)
+ throws XPathExpressionException {
+ if (attributeQDMNode.getAttributes().getLength() > 0) {
+
+ String attrName = (String) attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ String attribUUID = (String) attributeQDMNode.getUserData(ATTRIBUTE_UUID);
+
+ XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(4.3);
+ Node templateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/AttrTemplate[text()='" + attrName + "']");
+ String attributeValueSetName =
+ attributeQDMNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ String attributeOID = attributeQDMNode.getAttributes().getNamedItem(OID).getNodeValue();
+ String attributeTaxonomy =
+ attributeQDMNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
+ dataCriteriaElem.setAttribute("actionNegationInd", "true");
+
+ Element outboundRelationshipElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
+ outboundRelationshipElem.setAttribute(
+ TYPE_CODE, templateNode.getAttributes().getNamedItem(TYPE).getNodeValue());
+
+ Element observationCriteriaElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(OBSERVATION_CRITERIA);
+ observationCriteriaElem.setAttribute(
+ CLASS_CODE, templateNode.getAttributes().getNamedItem(CLASS).getNodeValue());
+ observationCriteriaElem.setAttribute(
+ MOOD_CODE, templateNode.getAttributes().getNamedItem(MOOD).getNodeValue());
+
+ outboundRelationshipElem.appendChild(observationCriteriaElem);
+
+ Element templateId = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
+ observationCriteriaElem.appendChild(templateId);
+
+ Element itemChild = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ITEM);
+ itemChild.setAttribute(ROOT, templateNode.getAttributes().getNamedItem(OID).getNodeValue());
+ itemChild.setAttribute("extension", VERSION_4_1_2_ID);
+ templateId.appendChild(itemChild);
+
+ Element idElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ID);
+ idElem.setAttribute(ROOT, attribUUID);
+ idElem.setAttribute("extension", StringUtils.deleteWhitespace(attributeValueSetName));
+ observationCriteriaElem.appendChild(idElem);
+
+ Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ codeElem.setAttribute(CODE, templateNode.getAttributes().getNamedItem(CODE).getNodeValue());
+ codeElem.setAttribute(
+ CODE_SYSTEM, templateNode.getAttributes().getNamedItem(CODE_SYSTEM).getNodeValue());
+
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ displayNameElem.setAttribute(VALUE, "Reason");
+
+ observationCriteriaElem.appendChild(codeElem);
+ codeElem.appendChild(displayNameElem);
+
+ Element titleElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TITLE);
+ titleElem.setAttribute(VALUE, "Reason");
+ observationCriteriaElem.appendChild(titleElem);
+
+ Element valueElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(VALUE);
+ valueElem.setAttribute(
+ XSI_TYPE, templateNode.getAttributes().getNamedItem("valueType").getNodeValue());
+ valueElem.setAttribute("valueSet", attributeOID);
+ addValueSetVersion(attributeQDMNode, valueElem);
+ Element valueDisplayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ valueDisplayNameElem.setAttribute(
+ VALUE,
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(attributeValueSetName)
+ + " "
+ + attributeTaxonomy
+ + " Value Set");
+
+ valueElem.appendChild(valueDisplayNameElem);
+ observationCriteriaElem.appendChild(valueElem);
+
+ dataCriteriaElem.appendChild(outboundRelationshipElem);
+ }
+ }
+
+ /**
+ * Method is used to generate HQMF logic for Principle Diagnosis and Diagnosis attributes.
+ *
+ * @param qdmNode
+ * @param dataCriteriaElem
+ * @param dataCriteriaXMLProcessor
+ * @param simpleXmlprocessor
+ * @param attributeQDMNode
+ * @throws XPathExpressionException
+ */
+ protected void generatePrincipalAndDiagnosisAttributes(
+ Node qdmNode,
+ Element dataCriteriaElem,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ Node attributeQDMNode)
+ throws XPathExpressionException {
+ String attrName = (String) attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ String attrMode = (String) attributeQDMNode.getUserData(ATTRIBUTE_MODE);
+
+ XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(4.3);
+ Node templateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/AttrTemplate[text()='" + attrName.toLowerCase() + "']");
+ if (templateNode == null) {
+ return;
+ } else {
+ Element outboundRelationshipElem = null;
+ Element actCriteriaElem = null;
+ outboundRelationshipElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
+ outboundRelationshipElem.setAttribute(
+ TYPE_CODE, templateNode.getAttributes().getNamedItem(TYPE).getNodeValue());
+ actCriteriaElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement("actCriteria");
+ actCriteriaElem.setAttribute(
+ CLASS_CODE, templateNode.getAttributes().getNamedItem(CLASS).getNodeValue());
+ actCriteriaElem.setAttribute(
+ MOOD_CODE, templateNode.getAttributes().getNamedItem(MOOD).getNodeValue());
+ Element idElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ID);
+ idElem.setAttribute(ROOT, UUIDUtilClient.uuid());
+ idElem.setAttribute("extension", UUIDUtilClient.uuid());
+ actCriteriaElem.appendChild(idElem);
+ Element codeElem = createCodeForDatatype(templateNode, dataCriteriaXMLProcessor);
+ actCriteriaElem.appendChild(codeElem);
+ Element titleElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TITLE);
+ titleElem.setAttribute(VALUE, "Encounter " + attrName);
+ actCriteriaElem.appendChild(titleElem);
+
+ outboundRelationshipElem.appendChild(actCriteriaElem);
+
+ String subTemplateName =
+ templateNode.getAttributes().getNamedItem("includeSubTemplate").getNodeValue();
+ Node subTemplateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(), "/templates/subtemplates/" + subTemplateName);
+ NodeList subTemplateNodeChilds =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "/child::node()");
+
+ if (subTemplateNode.getAttributes().getNamedItem("changeAttribute") != null) {
+ String[] attributeToBeModified =
+ subTemplateNode
+ .getAttributes()
+ .getNamedItem("changeAttribute")
+ .getNodeValue()
+ .split(",");
+ for (String changeAttribute : attributeToBeModified) {
+ NodeList attributedToBeChangedInNode = null;
+ attributedToBeChangedInNode =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "//" + changeAttribute);
+ if (changeAttribute.equalsIgnoreCase(ID)) {
+ String rootId = qdmNode.getAttributes().getNamedItem("uuid").getNodeValue();
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("root")
+ .setNodeValue(rootId);
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("extension")
+ .setNodeValue(UUIDUtilClient.uuid());
+ } else if (changeAttribute.equalsIgnoreCase(VALUE)) {
+ if (CHECK_IF_PRESENT.equals(attrMode)) {
+ if (attributedToBeChangedInNode.item(0).hasAttributes()) {
+ if (attributedToBeChangedInNode.item(0).hasAttributes()) {
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("valueSet");
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("flavorId");
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("xsi:type");
+ }
+ }
+ if (attributedToBeChangedInNode.item(0).hasChildNodes()) {
+ attributedToBeChangedInNode
+ .item(0)
+ .removeChild(attributedToBeChangedInNode.item(0).getFirstChild());
+ }
+ Attr attribute =
+ attributedToBeChangedInNode
+ .item(0)
+ .getOwnerDocument()
+ .createAttribute("flavorId");
+ attribute.setNodeValue("ANY.NONNULL");
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attribute);
+
+ Attr attributeXSIType =
+ attributedToBeChangedInNode
+ .item(0)
+ .getOwnerDocument()
+ .createAttribute("xsi:type");
+ attributeXSIType.setNodeValue("ANY");
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attributeXSIType);
+ } else if (VALUE_SET.equalsIgnoreCase(attrMode)) {
+
+ String valueSetVersion = valueSetVersionStringValue(attributeQDMNode);
+ if (valueSetVersion.contains("mat/vsacmodel")) {
+ Attr valuesetVersionAttr =
+ attributedToBeChangedInNode
+ .item(0)
+ .getOwnerDocument()
+ .createAttribute("valueSetVersion");
+ valuesetVersionAttr.setNodeValue(valueSetVersion);
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .setNamedItem(valuesetVersionAttr);
+ } else {
+ if (attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("valueSetVersion")
+ != null) {
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .removeNamedItem("valueSetVersion");
+ }
+ }
+ if (attributedToBeChangedInNode.item(0).hasAttributes()) {
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("valueSet");
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("flavorId");
+ ((Element) attributedToBeChangedInNode.item(0)).removeAttribute("xsi:type");
+ }
+ if (attributedToBeChangedInNode.item(0).hasChildNodes()) {
+ ((Element) attributedToBeChangedInNode.item(0))
+ .removeChild(attributedToBeChangedInNode.item(0).getFirstChild());
+ }
+ String attributeValueSetName =
+ attributeQDMNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ String attributeOID =
+ attributeQDMNode.getAttributes().getNamedItem(OID).getNodeValue();
+ String attributeTaxonomy =
+ attributeQDMNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
+ Attr attribute =
+ attributedToBeChangedInNode
+ .item(0)
+ .getOwnerDocument()
+ .createAttribute("valueSet");
+ attribute.setNodeValue(attributeOID);
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attribute);
+ Attr attributeXSIType =
+ attributedToBeChangedInNode
+ .item(0)
+ .getOwnerDocument()
+ .createAttribute("xsi:type");
+ attributeXSIType.setNodeValue("CD");
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attributeXSIType);
+ Element valueDisplayNameElem =
+ attributedToBeChangedInNode
+ .item(0)
+ .getOwnerDocument()
+ .createElement(DISPLAY_NAME);
+ valueDisplayNameElem.setAttribute(
+ VALUE,
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(attributeValueSetName)
+ + " "
+ + attributeTaxonomy
+ + " Value Set");
+ attributedToBeChangedInNode.item(0).appendChild(valueDisplayNameElem);
+ }
+ }
+ }
+ }
+ for (int i = 0; i < subTemplateNodeChilds.getLength(); i++) {
+ Node childNode = subTemplateNodeChilds.item(i);
+ Node nodeToAttach = dataCriteriaXMLProcessor.getOriginalDoc().importNode(childNode, true);
+ XmlProcessor.clean(nodeToAttach);
+ actCriteriaElem.appendChild(nodeToAttach);
+ }
+
+ dataCriteriaElem.appendChild(outboundRelationshipElem);
+ }
+ }
+
+ /**
+ * Generate other attribute entries.
+ *
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem the data criteria elem
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param attributeQDMNode the attribute qdm node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ protected void generateOtherAttributes(
+ Node qdmNode,
+ Element dataCriteriaElem,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ Node attributeQDMNode)
+ throws XPathExpressionException {
+
+ String attrName = (String) attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ String attrMode = (String) attributeQDMNode.getUserData(ATTRIBUTE_MODE);
+ String attribUUID = (String) attributeQDMNode.getUserData(ATTRIBUTE_UUID);
+ String qdmName = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ boolean isResult = "result".equalsIgnoreCase(attrName);
+
+ boolean isResultNotOutBound =
+ isResult
+ && ("Diagnostic Study, Performed".equalsIgnoreCase(qdmName)
+ || "Laboratory Test, Performed".equalsIgnoreCase(qdmName)
+ || "Functional Status, Performed".equalsIgnoreCase(qdmName)
+ || "Risk Category Assessment".equalsIgnoreCase(qdmName));
+
+ XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(4.3);
+ Node templateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/AttrTemplate[text()='" + attrName.toLowerCase() + "']");
+ boolean isRadiation = false;
+ if (templateNode == null) {
+ templateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/AttrTemplate[text()='"
+ + attrName.toLowerCase()
+ + "-"
+ + attrMode.toLowerCase()
+ + "']");
+ if (templateNode == null) {
+ return;
+ } else {
+ if (ANATOMICAL_LOCATION_SITE.equalsIgnoreCase(attrName)
+ || ORDINALITY.equalsIgnoreCase(attrName)
+ || ROUTE.equalsIgnoreCase(attrName)
+ || "method".equalsIgnoreCase(attrName)
+ || ANATOMICAL_APPROACH_SITE.equalsIgnoreCase(attrName)) {
+ addTargetSiteOrPriorityCodeOrRouteCodeElement(
+ dataCriteriaElem, dataCriteriaXMLProcessor, attributeQDMNode, templateNode);
+ } else if (LATERALITY.equalsIgnoreCase(attrName)) {
+ appendSubTemplateNode(
+ templateNode,
+ dataCriteriaXMLProcessor,
+ templateXMLProcessor,
+ dataCriteriaElem,
+ qdmNode,
+ attributeQDMNode);
+ }
+ return;
+ }
+ }
+ // flag to add statusCode for Radiation Dosage and Radiation Duration attributes
+ if (templateNode.getAttributes().getNamedItem("isRadiation") != null) {
+ isRadiation = templateNode.getAttributes().getNamedItem("isRadiation").getNodeValue() != null;
+ }
+ if (attrName.equalsIgnoreCase(FACILITY_LOCATION)) {
+ if (templateNode.getAttributes().getNamedItem("includeSubTemplate") != null) {
+ appendSubTemplateInFacilityAttribute(
+ templateNode,
+ dataCriteriaXMLProcessor,
+ templateXMLProcessor,
+ dataCriteriaElem,
+ attributeQDMNode);
+ }
+ return;
+ } else if (attrName.contains(REFERENCE) || attrName.equalsIgnoreCase(RELATIONSHIP)) {
+ if (templateNode.getAttributes().getNamedItem("includeSubTemplate") != null) {
+ appendSubTemplateAndAddValueTagBasedOnMode(
+ templateNode,
+ dataCriteriaXMLProcessor,
+ templateXMLProcessor,
+ dataCriteriaElem,
+ attributeQDMNode);
+ }
+ return;
+ }
+ Element outboundRelationshipElem = null;
+ Element observationCriteriaElem = null;
+ if (!isResultNotOutBound) { // result attribute with specific Datatypes does'nt add
+ // OutBoundRelationShip
+ outboundRelationshipElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
+ outboundRelationshipElem.setAttribute(
+ TYPE_CODE, templateNode.getAttributes().getNamedItem(TYPE).getNodeValue());
+
+ Node invAttribNode = templateNode.getAttributes().getNamedItem("inv");
+ if (invAttribNode != null) {
+ outboundRelationshipElem.setAttribute("inversionInd", invAttribNode.getNodeValue());
+ }
+
+ observationCriteriaElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(OBSERVATION_CRITERIA);
+ observationCriteriaElem.setAttribute(
+ CLASS_CODE, templateNode.getAttributes().getNamedItem(CLASS).getNodeValue());
+ observationCriteriaElem.setAttribute(
+ MOOD_CODE, templateNode.getAttributes().getNamedItem(MOOD).getNodeValue());
+
+ outboundRelationshipElem.appendChild(observationCriteriaElem);
+
+ if ((templateNode.getAttributes().getNamedItem(OID) != null)
+ && !attrName.equalsIgnoreCase(ONSET_AGE)) {
+ Element templateId = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
+ observationCriteriaElem.appendChild(templateId);
+
+ Element itemChild = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ITEM);
+ itemChild.setAttribute(ROOT, templateNode.getAttributes().getNamedItem(OID).getNodeValue());
+ if (templateNode.getAttributes().getNamedItem("addExtensionInTemplate") == null) {
+ itemChild.setAttribute("extension", VERSION_4_1_2_ID);
+ }
+ templateId.appendChild(itemChild);
+ }
+
+ Element idElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ID);
+ idElem.setAttribute(ROOT, attribUUID);
+ idElem.setAttribute("extension", StringUtils.deleteWhitespace(attrName));
+ observationCriteriaElem.appendChild(idElem);
+ Element codeElem = createCodeForDatatype(templateNode, dataCriteriaXMLProcessor);
+ if ((isRadiation || isResult) && (codeElem != null)) {
+ observationCriteriaElem.appendChild(codeElem);
+ } else {
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ if (templateNode.getAttributes().getNamedItem("displayNameValue") != null) {
+ displayNameElem.setAttribute(
+ VALUE, templateNode.getAttributes().getNamedItem("displayNameValue").getNodeValue());
+ } else {
+ displayNameElem.setAttribute(VALUE, attrName);
+ }
+ if (codeElem != null) {
+ observationCriteriaElem.appendChild(codeElem);
+ codeElem.appendChild(displayNameElem);
+ }
+ }
+ if (!isRadiation) {
+ if (!attrName.equalsIgnoreCase(ONSET_AGE)) {
+ Element titleElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TITLE);
+ titleElem.setAttribute(VALUE, attrName);
+ observationCriteriaElem.appendChild(titleElem);
+ } else {
+ Element titleElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TITLE);
+ titleElem.setAttribute(VALUE, "Age");
+ observationCriteriaElem.appendChild(titleElem);
+ }
+ }
+ if (isRadiation) { // statusCode is added for Radiation Duration and Dosage
+ Element statusCodeElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(STATUS_CODE);
+ if (templateNode.getAttributes().getNamedItem("status") != null) {
+ statusCodeElem.setAttribute(
+ CODE, templateNode.getAttributes().getNamedItem("status").getNodeValue());
+ }
+ observationCriteriaElem.appendChild(statusCodeElem);
+ }
+ }
+ if (attrName.equalsIgnoreCase(ONSET_AGE)) {
+ generateRepeatNumber(
+ templateNode, dataCriteriaXMLProcessor, observationCriteriaElem, attributeQDMNode, VALUE);
+ dataCriteriaElem.appendChild(outboundRelationshipElem);
+ } else {
+ Element valueElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(VALUE);
+ if (VALUE_SET.equals(attrMode)) {
+ checkIfSelectedModeIsValueSet(
+ dataCriteriaXMLProcessor, attributeQDMNode, templateNode, valueElem);
+ } else if (CHECK_IF_PRESENT.equalsIgnoreCase(attrMode)) {
+ checkIfSelectedModeIsPresent(
+ dataCriteriaXMLProcessor, attributeQDMNode, templateNode, valueElem);
+ } else if (EQUAL_TO.equals(attrMode)
+ || attrMode.startsWith(LESS_THAN)
+ || attrMode.startsWith(GREATER_THAN)) {
+ checkIfSelectedModeIsArthimaticExpr(
+ dataCriteriaXMLProcessor, attributeQDMNode, templateNode, valueElem);
+ }
+ if ((outboundRelationshipElem != null) && (observationCriteriaElem != null)) {
+ observationCriteriaElem.appendChild(valueElem);
+ dataCriteriaElem.appendChild(outboundRelationshipElem);
+ } else {
+ NodeList outboundRelationshipList =
+ dataCriteriaElem.getElementsByTagName("outboundRelationship");
+ if ((outboundRelationshipList != null) && (outboundRelationshipList.getLength() > 0)) {
+ Node outboundRelationshipNode = outboundRelationshipList.item(0);
+ dataCriteriaElem.insertBefore(valueElem, outboundRelationshipNode);
+ } else {
+ dataCriteriaElem.appendChild(valueElem);
+ }
+ }
+ }
+ }
+
+ /**
+ * Refills Attribute tags.
+ *
+ * @param templateNode the template node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param dataCriteriaElem the data criteria elem
+ * @param attributeQDMNode the attribute qdm node
+ */
+ protected void generateRepeatNumber(
+ Node templateNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ Element dataCriteriaElem,
+ Node attributeQDMNode,
+ String elementNameToCreate) {
+ String attrMode = (String) attributeQDMNode.getUserData(ATTRIBUTE_MODE);
+ Element repeatNumberElement =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(elementNameToCreate);
+ Node unitAttrib = attributeQDMNode.getAttributes().getNamedItem("unit");
+
+ if (CHECK_IF_PRESENT.equalsIgnoreCase(attrMode)) {
+ if (elementNameToCreate.equalsIgnoreCase(VALUE)) {
+ repeatNumberElement.setAttribute("xsi:type", "ANY");
+ }
+ repeatNumberElement.setAttribute(FLAVOR_ID, "ANY.NONNULL");
+ } else if (EQUAL_TO.equals(attrMode)
+ || attrMode.startsWith(LESS_THAN)
+ || attrMode.startsWith(GREATER_THAN)) {
+ if (elementNameToCreate.equalsIgnoreCase(VALUE)) {
+ repeatNumberElement.setAttribute("xsi:type", "IVL_PQ");
+ }
+ if (EQUAL_TO.equals(attrMode)) {
+ Element lowElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(LOW);
+ lowElem.setAttribute(
+ VALUE, attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ Element highElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(HIGH);
+ highElem.setAttribute(
+ VALUE, attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ if (unitAttrib != null) {
+ lowElem.setAttribute("unit", getUnitString(unitAttrib.getNodeValue()));
+ highElem.setAttribute("unit", getUnitString(unitAttrib.getNodeValue()));
+ }
+ repeatNumberElement.appendChild(lowElem);
+ repeatNumberElement.appendChild(highElem);
+ } else if (attrMode.startsWith(GREATER_THAN)) {
+ if (attrMode.equals(GREATER_THAN)) {
+ repeatNumberElement.setAttribute("lowClosed", "false");
+ }
+ Element lowElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(LOW);
+ lowElem.setAttribute(
+ VALUE, attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ repeatNumberElement.appendChild(lowElem);
+ Element highElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(HIGH);
+ highElem.setAttribute(NULL_FLAVOR, "PINF");
+ if (unitAttrib != null) {
+ lowElem.setAttribute("unit", getUnitString(unitAttrib.getNodeValue()));
+ }
+
+ repeatNumberElement.appendChild(highElem);
+ } else if (attrMode.startsWith(LESS_THAN)) {
+ if (attrMode.equals(LESS_THAN)) {
+ repeatNumberElement.setAttribute("highClosed", "false");
+ }
+ Element lowElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(LOW);
+ lowElem.setAttribute(NULL_FLAVOR, "NINF");
+ repeatNumberElement.appendChild(lowElem);
+ Element highElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(HIGH);
+ highElem.setAttribute(
+ VALUE, attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ if (unitAttrib != null) {
+ highElem.setAttribute("unit", getUnitString(unitAttrib.getNodeValue()));
+ }
+ repeatNumberElement.appendChild(highElem);
+ }
+ }
+
+ if ((dataCriteriaElem.getElementsByTagName("statusCode").item(0) != null)) {
+ Node outBoundElement = dataCriteriaElem.getElementsByTagName("statusCode").item(0);
+ if (outBoundElement != null) {
+ outBoundElement.getParentNode().insertBefore(repeatNumberElement, outBoundElement);
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, repeatNumberElement);
+ }
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, repeatNumberElement);
+ }
+ }
+
+ /**
+ * Discharge Status Attribute tags.
+ *
+ * @param templateNode the template node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param dataCriteriaElem the data criteria elem
+ * @param attributeQDMNode the attribute qdm node
+ */
+ protected void generateDischargeStatus(
+ Node templateNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ Element dataCriteriaElem,
+ Node attributeQDMNode) {
+ String attrMode = (String) attributeQDMNode.getUserData(ATTRIBUTE_MODE);
+ Element dischargeDispositionElement =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement("dischargeDispositionCode");
+ if (CHECK_IF_PRESENT.equalsIgnoreCase(attrMode)) {
+ dischargeDispositionElement.setAttribute(FLAVOR_ID, "ANY.NONNULL");
+ checkIfOutBoundOcc(dataCriteriaElem, dischargeDispositionElement);
+ } else if (VALUE_SET.equalsIgnoreCase(attrMode)) {
+ String attributeValueSetName =
+ attributeQDMNode.getAttributes().getNamedItem(NAME).getNodeValue();
+
+ String attributeOID = attributeQDMNode.getAttributes().getNamedItem(OID).getNodeValue();
+ String attributeTaxonomy =
+ attributeQDMNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
+ dischargeDispositionElement.setAttribute("valueSet", attributeOID);
+ addValueSetVersion(attributeQDMNode, dischargeDispositionElement);
+ Element valueDisplayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ valueDisplayNameElem.setAttribute(
+ VALUE,
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(attributeValueSetName)
+ + " "
+ + attributeTaxonomy
+ + " Value Set");
+ dischargeDispositionElement.appendChild(valueDisplayNameElem);
+ checkIfOutBoundOcc(dataCriteriaElem, dischargeDispositionElement);
+ }
+ }
+
+ /**
+ * Check if selected mode is value set.
+ *
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param attributeQDMNode the attribute qdm node
+ * @param templateNode the template node
+ * @param valueElem the value elem
+ * @return the element
+ */
+ protected Element checkIfSelectedModeIsValueSet(
+ XmlProcessor dataCriteriaXMLProcessor,
+ Node attributeQDMNode,
+ Node templateNode,
+ Element valueElem) {
+ String attributeValueSetName =
+ attributeQDMNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ String attributeOID = attributeQDMNode.getAttributes().getNamedItem(OID).getNodeValue();
+ String attributeTaxonomy =
+ attributeQDMNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
+ if (templateNode.getAttributes().getNamedItem("valueType") != null) {
+ valueElem.setAttribute(
+ XSI_TYPE, templateNode.getAttributes().getNamedItem("valueType").getNodeValue());
+ }
+
+ valueElem.setAttribute("valueSet", attributeOID);
+ addValueSetVersion(attributeQDMNode, valueElem);
+ Element valueDisplayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ valueDisplayNameElem.setAttribute(
+ VALUE,
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(attributeValueSetName)
+ + " "
+ + attributeTaxonomy
+ + " Value Set");
+ valueElem.appendChild(valueDisplayNameElem);
+
+ return valueElem;
+ }
+
+ /**
+ * Check if selected mode is present.
+ *
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param attributeQDMNode the attribute qdm node
+ * @param templateNode the template node
+ * @param valueElem the value elem
+ * @return the element
+ */
+ protected Element checkIfSelectedModeIsPresent(
+ XmlProcessor dataCriteriaXMLProcessor,
+ Node attributeQDMNode,
+ Node templateNode,
+ Element valueElem) {
+ valueElem.setAttribute(XSI_TYPE, "ANY");
+ valueElem.setAttribute(FLAVOR_ID, "ANY.NONNULL");
+ return valueElem;
+ }
+
+ /**
+ * Check if selected mode is arthimatic expr.
+ *
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param attributeQDMNode the attribute qdm node
+ * @param templateNode the template node
+ * @param valueElem the value elem
+ * @return the element
+ */
+ private Element checkIfSelectedModeIsArthimaticExpr(
+ XmlProcessor dataCriteriaXMLProcessor,
+ Node attributeQDMNode,
+ Node templateNode,
+ Element valueElem) {
+ String attrMode = (String) attributeQDMNode.getUserData(ATTRIBUTE_MODE);
+ String attrName = (String) attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ String nodeName = attributeQDMNode.getNodeName();
+ boolean isRadiation = false;
+ boolean isTargetOutCome = false;
+ boolean isCumMedicationDuration = CUMULATIVE_MEDICATION_DURATION.equalsIgnoreCase(attrName);
+ boolean isFrequency = FREQUENCY.equalsIgnoreCase(attrName);
+ boolean isResult = "result".equalsIgnoreCase(attrName);
+ if (templateNode.getAttributes().getNamedItem("isRadiation") != null) {
+ isRadiation = templateNode.getAttributes().getNamedItem("isRadiation").getNodeValue() != null;
+ }
+ if (templateNode.getAttributes().getNamedItem("isTargetOutcome") != null) {
+ isTargetOutCome =
+ templateNode.getAttributes().getNamedItem("isTargetOutcome").getNodeValue() != null;
+ }
+ if (nodeName.equals("attribute")) {
+ valueElem.setAttribute(XSI_TYPE, "IVL_PQ");
+ Node unitAttrib = attributeQDMNode.getAttributes().getNamedItem("unit");
+ if (EQUAL_TO.equals(attrMode)) {
+ if (isRadiation) { // for radiation dosage and radiation duration
+ valueElem.getAttributes().getNamedItem(XSI_TYPE).setNodeValue("PQ");
+ valueElem.setAttribute(
+ VALUE,
+ attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ if (unitAttrib != null) {
+ String unitString = getUnitString(unitAttrib.getNodeValue());
+ valueElem.setAttribute("unit", unitString);
+ }
+ } else { // for attributes other than radiation duration and radiation dosage
+ Element lowElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(LOW);
+ lowElem.setAttribute(
+ VALUE,
+ attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+
+ Element highElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(HIGH);
+ highElem.setAttribute(
+ VALUE,
+ attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+
+ if (unitAttrib != null) {
+ String unitString = getUnitString(unitAttrib.getNodeValue());
+ lowElem.setAttribute("unit", unitString);
+ highElem.setAttribute("unit", unitString);
+ }
+ if (isResult) {
+ lowElem.setAttribute(XSI_TYPE, "PQ");
+ highElem.setAttribute(XSI_TYPE, "PQ");
+ }
+ valueElem.appendChild(lowElem);
+ valueElem.appendChild(highElem);
+ }
+
+ } else if (attrMode.startsWith(GREATER_THAN)) {
+ if (attrMode.equals(GREATER_THAN)) {
+ valueElem.setAttribute("lowClosed", "false");
+ }
+ Element lowElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(LOW);
+ if (isResult) {
+ lowElem.setAttribute(XSI_TYPE, "PQ");
+ }
+ lowElem.setAttribute(
+ VALUE, attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ if (unitAttrib != null) {
+ String unitString = getUnitString(unitAttrib.getNodeValue());
+ lowElem.setAttribute("unit", unitString);
+ }
+ valueElem.appendChild(lowElem);
+ if (isRadiation || isResult || isTargetOutCome || isCumMedicationDuration || isFrequency) {
+ Element highElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(HIGH);
+ highElem.setAttribute(NULL_FLAVOR, "PINF");
+ valueElem.appendChild(highElem);
+ }
+ } else if (attrMode.startsWith(LESS_THAN)) {
+ if (attrMode.equals(LESS_THAN)) {
+ valueElem.setAttribute("highClosed", "false");
+ }
+ if (isRadiation || isResult || isTargetOutCome || isCumMedicationDuration || isFrequency) {
+ Element highElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(LOW);
+ highElem.setAttribute(NULL_FLAVOR, "NINF");
+ valueElem.appendChild(highElem);
+ }
+ Element highElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(HIGH);
+ if (isResult) {
+ highElem.setAttribute(XSI_TYPE, "PQ");
+ }
+ highElem.setAttribute(
+ VALUE, attributeQDMNode.getAttributes().getNamedItem("comparisonValue").getNodeValue());
+ if (unitAttrib != null) {
+ String unitString = getUnitString(unitAttrib.getNodeValue());
+ highElem.setAttribute("unit", unitString);
+ }
+ valueElem.appendChild(highElem);
+ }
+ }
+
+ return valueElem;
+ }
+
+ /**
+ * Adds the target site or priority code or route code element.
+ *
+ * @param dataCriteriaElem the data criteria elem
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param attributeQDMNode the attribute qdm node
+ * @param templateNode the template node
+ */
+ private void addTargetSiteOrPriorityCodeOrRouteCodeElement(
+ Element dataCriteriaElem,
+ XmlProcessor dataCriteriaXMLProcessor,
+ Node attributeQDMNode,
+ Node templateNode) {
+ String targetElementName = templateNode.getAttributes().getNamedItem("target").getNodeValue();
+ Element targetSiteCodeElement =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(targetElementName);
+ String insertBeforeNodeName = null;
+ String insertAfterNodeName = null;
+ if (templateNode.getAttributes().getNamedItem("insertBeforeNode") != null) {
+ insertBeforeNodeName =
+ templateNode.getAttributes().getNamedItem("insertBeforeNode").getNodeValue();
+ } else if (templateNode.getAttributes().getNamedItem("insertAfterNode") != null) {
+ insertAfterNodeName =
+ templateNode.getAttributes().getNamedItem("insertAfterNode").getNodeValue();
+ }
+ if (templateNode.getAttributes().getNamedItem("childTarget") != null) {
+ String qdmOidValue = attributeQDMNode.getAttributes().getNamedItem(OID).getNodeValue();
+ // .getNodeValue();
+ Element valueElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ITEM);
+ valueElem.setAttribute("valueSet", qdmOidValue);
+ addValueSetVersion(attributeQDMNode, valueElem);
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ String newQdmName =
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(
+ attributeQDMNode.getAttributes().getNamedItem(NAME).getNodeValue());
+ displayNameElem.setAttribute(
+ VALUE,
+ newQdmName
+ + " "
+ + attributeQDMNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue()
+ + " Value Set");
+ valueElem.appendChild(displayNameElem);
+ targetSiteCodeElement.appendChild(valueElem);
+ if ((insertBeforeNodeName != null)
+ && (dataCriteriaElem.getElementsByTagName(insertBeforeNodeName).item(0) != null)) {
+ Node outBoundElement = dataCriteriaElem.getElementsByTagName(insertBeforeNodeName).item(0);
+ if (outBoundElement != null) {
+ outBoundElement.getParentNode().insertBefore(targetSiteCodeElement, outBoundElement);
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, targetSiteCodeElement);
+ }
+ } else if ((insertAfterNodeName != null)
+ && (dataCriteriaElem.getElementsByTagName(insertAfterNodeName).item(0) != null)) {
+ Node outBoundElement =
+ dataCriteriaElem.getElementsByTagName(insertAfterNodeName).item(0).getNextSibling();
+ if (outBoundElement != null) {
+ outBoundElement.getParentNode().insertBefore(targetSiteCodeElement, outBoundElement);
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, targetSiteCodeElement);
+ }
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, targetSiteCodeElement);
+ }
+ } else if (templateNode.getAttributes().getNamedItem(FLAVOR_ID) != null) {
+ String flavorIdValue = templateNode.getAttributes().getNamedItem(FLAVOR_ID).getNodeValue();
+ targetSiteCodeElement.setAttribute(FLAVOR_ID, flavorIdValue);
+ if ((insertBeforeNodeName != null)
+ && (dataCriteriaElem.getElementsByTagName(insertBeforeNodeName).item(0) != null)) {
+ Node outBoundElement = dataCriteriaElem.getElementsByTagName(insertBeforeNodeName).item(0);
+ if (outBoundElement != null) {
+ outBoundElement.getParentNode().insertBefore(targetSiteCodeElement, outBoundElement);
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, targetSiteCodeElement);
+ }
+ } else if ((insertAfterNodeName != null)
+ && (dataCriteriaElem.getElementsByTagName(insertAfterNodeName).item(0) != null)) {
+ Node outBoundElement =
+ dataCriteriaElem.getElementsByTagName(insertAfterNodeName).item(0).getNextSibling();
+ if (outBoundElement != null) {
+ outBoundElement.getParentNode().insertBefore(targetSiteCodeElement, outBoundElement);
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, targetSiteCodeElement);
+ }
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, targetSiteCodeElement);
+ }
+ } else if (templateNode.getAttributes().getNamedItem("addValueSet") != null) {
+ String qdmOidValue = attributeQDMNode.getAttributes().getNamedItem(OID).getNodeValue();
+ targetSiteCodeElement.setAttribute("valueSet", qdmOidValue);
+ addValueSetVersion(attributeQDMNode, targetSiteCodeElement);
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ String newQdmName =
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(
+ attributeQDMNode.getAttributes().getNamedItem(NAME).getNodeValue());
+ displayNameElem.setAttribute(
+ VALUE,
+ newQdmName
+ + " "
+ + attributeQDMNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue()
+ + " Value Set");
+ targetSiteCodeElement.appendChild(displayNameElem);
+ if ((insertBeforeNodeName != null)
+ && (dataCriteriaElem.getElementsByTagName(insertBeforeNodeName).item(0) != null)) {
+ Node outBoundElement = dataCriteriaElem.getElementsByTagName(insertBeforeNodeName).item(0);
+ if (outBoundElement != null) {
+ outBoundElement.getParentNode().insertBefore(targetSiteCodeElement, outBoundElement);
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, targetSiteCodeElement);
+ }
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, targetSiteCodeElement);
+ }
+ }
+ }
+
+ /**
+ * Method to generate HQMF XML for date time attributes.
+ *
+ * @param childNode the child node
+ * @param dataCriteriaElem the data criteria elem
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param attributeQDMNode the attribute qdm node
+ */
+ protected void generateDateTimeAttributes(
+ Node childNode,
+ Element dataCriteriaElem,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ Node attributeQDMNode) {
+
+ Element effectiveTimeNode =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(EFFECTIVE_TIME);
+ effectiveTimeNode.setAttribute(XSI_TYPE, "IVL_TS");
+ generateDateTimeAttributesTag(
+ effectiveTimeNode, attributeQDMNode, dataCriteriaElem, dataCriteriaXMLProcessor, false);
+ }
+
+ /**
+ * Generate date time attributes tag.
+ *
+ * @param dateTimeNode the effective time node
+ * @param attributeQDMNode the attribute qdm node
+ * @param dataCriteriaElem the data criteria elem
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param isOrder the is order
+ */
+ protected void generateDateTimeAttributesTag(
+ Node dateTimeNode,
+ Node attributeQDMNode,
+ Element dataCriteriaElem,
+ XmlProcessor dataCriteriaXMLProcessor,
+ boolean isOrder) {
+
+ String attrName = (String) attributeQDMNode.getUserData(ATTRIBUTE_NAME);
+ String attrMode = (String) attributeQDMNode.getUserData(ATTRIBUTE_MODE);
+ String attrDate = (String) attributeQDMNode.getUserData(ATTRIBUTE_DATE);
+
+ String timeTagName = "";
+ switch (attrName.toLowerCase()) {
+ case START_DATETIME:
+ case FACILITY_LOCATION_ARRIVAL_DATETIME:
+ case ADMISSION_DATETIME:
+ case ACTIVE_DATETIME:
+ case DATE:
+ case TIME:
+ case INCISION_DATETIME:
+ case ONSET_DATETIME:
+ timeTagName = LOW;
+ break;
+ case STOP_DATETIME:
+ case FACILITY_LOCATION_DEPARTURE_DATETIME:
+ case DISCHARGE_DATETIME:
+ case REMOVAL_DATETIME:
+ case SIGNED_DATETIME:
+ case RECORDED_DATETIME:
+ case ABATEMENT_DATETIME:
+ timeTagName = HIGH;
+ break;
+ default:
+ timeTagName = "";
+ break;
+ }
+
+ if (CHECK_IF_PRESENT.equals(attrMode)) {
+
+ if (timeTagName.length() > 0) {
+ Element timeTagNode = dataCriteriaElem.getOwnerDocument().createElement(timeTagName);
+ timeTagNode.setAttribute(FLAVOR_ID, "ANY.NONNULL");
+ dateTimeNode.appendChild(timeTagNode);
+ }
+ } else {
+ if (attrMode.equals(Generator.EQUAL_TO)) {
+ if (timeTagName.length() > 0) {
+ Element timeTagNode = dataCriteriaElem.getOwnerDocument().createElement(timeTagName);
+ timeTagNode.setAttribute(VALUE, attrDate);
+ dateTimeNode.appendChild(timeTagNode);
+ }
+ } else if (attrMode.startsWith(Generator.GREATER_THAN)) {
+ if (timeTagName.length() > 0) {
+ Element timeTagNode = dataCriteriaElem.getOwnerDocument().createElement(timeTagName);
+ Element uncertainRangeNode =
+ dataCriteriaElem.getOwnerDocument().createElement("uncertainRange");
+ if (attrMode.equals(Generator.GREATER_THAN)) {
+ uncertainRangeNode.setAttribute("lowClosed", "false");
+ }
+ Element lowNode = dataCriteriaElem.getOwnerDocument().createElement(LOW);
+ lowNode.setAttribute(XSI_TYPE, "TS");
+ lowNode.setAttribute(VALUE, attrDate);
+
+ Element highNode = dataCriteriaElem.getOwnerDocument().createElement(HIGH);
+ highNode.setAttribute(XSI_TYPE, "TS");
+ highNode.setAttribute("nullFlavor", "PINF");
+
+ uncertainRangeNode.appendChild(lowNode);
+ uncertainRangeNode.appendChild(highNode);
+ timeTagNode.appendChild(uncertainRangeNode);
+ dateTimeNode.appendChild(timeTagNode);
+ }
+ } else if (attrMode.startsWith(Generator.LESS_THAN)) {
+ if (timeTagName.length() > 0) {
+ Element timeTagNode = dataCriteriaElem.getOwnerDocument().createElement(timeTagName);
+ Element uncertainRangeNode =
+ dataCriteriaElem.getOwnerDocument().createElement("uncertainRange");
+ if (attrMode.equals(Generator.LESS_THAN)) {
+ uncertainRangeNode.setAttribute("highClosed", "false");
+ }
+ Element lowNode = dataCriteriaElem.getOwnerDocument().createElement(LOW);
+ lowNode.setAttribute(XSI_TYPE, "TS");
+ lowNode.setAttribute("nullFlavor", "NINF");
+
+ Element highNode = dataCriteriaElem.getOwnerDocument().createElement(HIGH);
+ highNode.setAttribute(XSI_TYPE, "TS");
+ highNode.setAttribute(VALUE, attrDate);
+
+ uncertainRangeNode.appendChild(lowNode);
+ uncertainRangeNode.appendChild(highNode);
+ timeTagNode.appendChild(uncertainRangeNode);
+ dateTimeNode.appendChild(timeTagNode);
+ }
+ }
+ }
+
+ /** If effectiveTimeNode has any child nodes then add it to the main dataCriteriaNode. */
+ if (dateTimeNode.hasChildNodes()) {
+
+ if (attrName.equalsIgnoreCase(START_DATETIME)
+ || attrName.equalsIgnoreCase(STOP_DATETIME)
+ || attrName.equalsIgnoreCase(SIGNED_DATETIME)
+ || attrName.equalsIgnoreCase(RECORDED_DATETIME)) {
+ NodeList nodeList = dataCriteriaElem.getElementsByTagName("participation");
+ if ((nodeList != null) && (nodeList.getLength() > 0) && isOrder) {
+ if (nodeList.getLength() > 1) {
+ nodeList
+ .item(1)
+ .insertBefore(dateTimeNode, dataCriteriaElem.getElementsByTagName("role").item(1));
+ } else {
+ nodeList
+ .item(0)
+ .insertBefore(dateTimeNode, dataCriteriaElem.getElementsByTagName("role").item(0));
+ }
+ } else {
+ NodeList valueNodeList = dataCriteriaElem.getElementsByTagName("value");
+ if ((valueNodeList != null) && (valueNodeList.getLength() > 0)) {
+ dataCriteriaElem.insertBefore(dateTimeNode, valueNodeList.item(0));
+ } else {
+ NodeList statusCodeNodeList = dataCriteriaElem.getElementsByTagName("statusCode");
+ if ((statusCodeNodeList != null) && (statusCodeNodeList.getLength() > 0)) {
+ dataCriteriaElem.insertBefore(
+ dateTimeNode, statusCodeNodeList.item(0).getNextSibling());
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, dateTimeNode);
+ }
+ }
+ }
+ } else {
+ NodeList nodeList = dataCriteriaElem.getElementsByTagName("value");
+ if ((nodeList != null) && (nodeList.getLength() > 0)) {
+ dataCriteriaElem.insertBefore(dateTimeNode, nodeList.item(0));
+ } else {
+
+ if (attrName.contains("facility")) {
+ NodeList nodeListParticipation = dataCriteriaElem.getElementsByTagName("role");
+ if ((nodeListParticipation != null) && (nodeListParticipation.getLength() > 0)) {
+ nodeListParticipation
+ .item(0)
+ .getFirstChild()
+ .getParentNode()
+ .appendChild(dateTimeNode);
+ }
+ } else if (attrName.equalsIgnoreCase(
+ INCISION_DATETIME)) { // for Incision Datetime Attribute
+ // effective Time is Added inside
+ NodeList nodeListProcedureCriteria =
+ dataCriteriaElem.getElementsByTagName("procedureCriteria");
+ if ((nodeListProcedureCriteria != null)
+ && (nodeListProcedureCriteria.getLength() > 0)) {
+ nodeListProcedureCriteria
+ .item(0)
+ .getFirstChild()
+ .getParentNode()
+ .appendChild(dateTimeNode);
+ }
+ } else {
+ NodeList nodeListParticipation = dataCriteriaElem.getElementsByTagName("participation");
+ if ((nodeListParticipation != null) && (nodeListParticipation.getLength() > 0)) {
+ dataCriteriaElem.insertBefore(dateTimeNode, nodeListParticipation.item(0));
+ } else {
+ checkIfOutBoundOcc(dataCriteriaElem, dateTimeNode);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds the data criteria comment.
+ *
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ */
+ private void addDataCriteriaComment(XmlProcessor dataCriteriaXMLProcessor) {
+ Element element = dataCriteriaXMLProcessor.getOriginalDoc().getDocumentElement();
+ Comment comment =
+ dataCriteriaXMLProcessor.getOriginalDoc().createComment("Data Criteria Section");
+ element.getParentNode().insertBefore(comment, element);
+ }
+
+ /**
+ * Creates the code for datatype.
+ *
+ * @param templateNode the template node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @return the element
+ */
+ protected Element createCodeForDatatype(
+ Node templateNode, XmlProcessor dataCriteriaXMLProcessor) {
+ Node codeAttr = templateNode.getAttributes().getNamedItem(CODE);
+ Node codeSystemAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM);
+ Node codeSystemNameAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM_NAME);
+ Node codeDisplayNameAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM_DISPLAY_NAME);
+ Element codeElement = null;
+ if ((codeAttr != null)
+ || (codeSystemAttr != null)
+ || (codeSystemNameAttr != null)
+ || (codeDisplayNameAttr != null)) {
+ codeElement = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ if (codeAttr != null) {
+ codeElement.setAttribute(CODE, codeAttr.getNodeValue());
+ }
+ if (codeSystemAttr != null) {
+ codeElement.setAttribute(CODE_SYSTEM, codeSystemAttr.getNodeValue());
+ }
+ if (codeSystemNameAttr != null) {
+ codeElement.setAttribute(CODE_SYSTEM_NAME, codeSystemNameAttr.getNodeValue());
+ }
+ if (codeDisplayNameAttr != null) {
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ displayNameElem.setAttribute(VALUE, codeDisplayNameAttr.getNodeValue());
+ codeElement.appendChild(displayNameElem);
+ }
+ }
+ return codeElement;
+ }
+
+ /**
+ * This method is called before we start generating HQMF code for various data criteria elements.
+ * It will perform the task of prepping the Simple XML for the clause generation process. It will
+ * do the following,
+ *
+ * 1) Call prepForAGE_AT(MeasureExport me) which will, Look for and replace it with The first child of this new
+ * relationalOp will be the elementRef for Birthdate QDM element. The 2nd child will be the first
+ * child of the original .
+ */
+ private void prepHQMF(MeasureExport me) {
+ logger.debug("Prepping for HQMF Clause generation..............");
+ prepForUUID(me);
+ prepForAGE_AT(me);
+ prepForSatisfiesAll_Any(me);
+ logger.debug("Done prepping for HQMF Clause generation.");
+ }
+
+ private void prepForUUID(MeasureExport me) {
+
+ String xPathForFunctionalOp = "/measure/subTreeLookUp//functionalOp";
+ String xPathForRelationalOp = "/measure/subTreeLookUp//relationalOp";
+ String xPathForSetOp = "/measure/subTreeLookUp//setOp";
+
+ try {
+ NodeList nodeList =
+ me.getSimpleXmlProcessor()
+ .findNodeList(me.getSimpleXmlProcessor().getOriginalDoc(), xPathForFunctionalOp);
+ addUUIDToNodes(nodeList);
+
+ nodeList =
+ me.getSimpleXmlProcessor()
+ .findNodeList(me.getSimpleXmlProcessor().getOriginalDoc(), xPathForRelationalOp);
+ addUUIDToNodes(nodeList);
+
+ nodeList =
+ me.getSimpleXmlProcessor()
+ .findNodeList(me.getSimpleXmlProcessor().getOriginalDoc(), xPathForSetOp);
+ addUUIDToNodes(nodeList);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void addUUIDToNodes(NodeList nodeList) {
+ if ((nodeList != null) && (nodeList.getLength() > 0)) {
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node node = nodeList.item(i);
+ ((Element) node).setAttribute("uuid", UUIDUtilClient.uuid());
+ }
+ }
+ }
+
+ /**
+ * This method will be called by prepHQMF(MeasureExport me) method to prep functionalOp for AGE AT
+ * functions. This methiod will do the following,
+ *
+ *
Look for and replace it with The first child of this new relationalOp will be the elementRef for Birthdate QDM
+ * element. The 2nd child will be the first child of the original .
+ *
+ * @param me
+ */
+ private void prepForAGE_AT(MeasureExport me) {
+ XmlProcessor xmlProcessor = me.getSimpleXmlProcessor();
+ logger.debug("Prepping for HQMF Clause generation for AGE AT functionalOps.");
+
+ try {
+
+ // find for Birthdate QDM element in elementLookUp
+ String xPathForBirthdate =
+ "/measure/elementLookUp/qdm[@name='Birthdate'][@datatype='Patient Characteristic Birthdate']";
+ Node birthDateQDM = xmlProcessor.findNode(xmlProcessor.getOriginalDoc(), xPathForBirthdate);
+ if (birthDateQDM == null) {
+ logger.debug(
+ "********** Could not find QDM for Birthdate. No changes done for AGE AT. ***************");
+ return;
+ }
+
+ String xPathForAGE_AT = "/measure/subTreeLookUp//functionalOp[@type='AGE AT']";
+ Node ageAtFuncNode = xmlProcessor.findNode(xmlProcessor.getOriginalDoc(), xPathForAGE_AT);
+
+ logger.debug(".......found AGE AT functionalOps");
+
+ while (ageAtFuncNode != null) {
+ logger.debug("Changing " + ageAtFuncNode.toString() + " to relational SBS node.");
+ Node cloneAgeAtRelNode = ageAtFuncNode.cloneNode(true);
+
+ // hold on to the first child of Age At
+ Node firstChild = cloneAgeAtRelNode.getFirstChild();
+ NamedNodeMap attribMap = ageAtFuncNode.getAttributes();
+ Element newRelationalOp = xmlProcessor.getOriginalDoc().createElement("relationalOp");
+
+ for (int j = 0; j < attribMap.getLength(); j++) {
+ Node attrib = attribMap.item(j);
+ newRelationalOp.setAttribute(attrib.getNodeName(), attrib.getNodeValue());
+ }
+
+ // set the type attribute to SBS
+ newRelationalOp.getAttributes().getNamedItem("type").setNodeValue("SBS");
+
+ // create a new This method will look for all functionalOp's with names, SATISFIES ALL/SATISFIES ANY renames
+ * the tag with tag.
+ *
+ * @param me
+ */
+ private void prepForSatisfiesAll_Any(MeasureExport me) {
+ XmlProcessor xmlProcessor = me.getSimpleXmlProcessor();
+ logger.debug(
+ "Prepping for HQMF Clause generation for Satisfies All/Satisfies Any functionalOps.");
+ String xPathForSatisfiesAllAny =
+ "/measure/subTreeLookUp//functionalOp[@type='SATISFIES ALL' or @type='SATISFIES ANY']";
+ try {
+ Node satisfiesFuncNode =
+ xmlProcessor.findNode(xmlProcessor.getOriginalDoc(), xPathForSatisfiesAllAny);
+ logger.debug(".......found Satisfies All/Satisfies Any functionalOps");
+ while (satisfiesFuncNode != null) {
+ logger.debug(
+ "Changing functionaOp "
+ + satisfiesFuncNode.getAttributes().getNamedItem("displayName").getNodeValue()
+ + " to relationalOp node.");
+
+ NamedNodeMap attribMap = satisfiesFuncNode.getAttributes();
+ Element newSetOp = xmlProcessor.getOriginalDoc().createElement("setOp");
+
+ for (int j = 0; j < attribMap.getLength(); j++) {
+ Node attrib = attribMap.item(j);
+ newSetOp.setAttribute(attrib.getNodeName(), attrib.getNodeValue());
+ }
+
+ NodeList childNodeList = satisfiesFuncNode.getChildNodes();
+ /** Ignore the first element of SATISFIES ALL/ANY. i.e. Start counter at 1 isntead of 0. */
+ for (int j = 1; j < childNodeList.getLength(); j++) {
+ Node childNode = childNodeList.item(j).cloneNode(true);
+ newSetOp.appendChild(childNode);
+ }
+
+ Node parentNode = satisfiesFuncNode.getParentNode();
+ parentNode.insertBefore(newSetOp, satisfiesFuncNode);
+ parentNode.removeChild(satisfiesFuncNode);
+ logger.debug("Change done.");
+ satisfiesFuncNode =
+ xmlProcessor.findNode(xmlProcessor.getOriginalDoc(), xPathForSatisfiesAllAny);
+ }
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Gets the unit string.
+ *
+ * @param unitString the unit string
+ * @return the unit string
+ */
+ protected String getUnitString(String unitString) {
+ String returnString = unitString;
+
+ if (unitString.equals("years") || unitString.equals("year")) {
+ returnString = "a";
+ } else if (unitString.equals("month") || unitString.equals("months")) {
+ returnString = "mo";
+ } else if (unitString.equals("day") || unitString.equals("days")) {
+ returnString = "d";
+ } else if (unitString.equals("hours") || unitString.equals("hour")) {
+ returnString = "h";
+ } else if (unitString.equals("week") || unitString.equals("weeks")) {
+ returnString = "wk";
+ } else if (unitString.equals("minutes") || unitString.equals("minute")) {
+ returnString = "min";
+ } else if (unitString.equals("quarter") || unitString.equals("quarters")) {
+ returnString = "[qtr]";
+ } else if (unitString.equals("second") || unitString.equals("seconds")) {
+ returnString = "s";
+ } else if (unitString.equals("bpm")) {
+ returnString = "{H.B.}/min";
+ } else if (unitString.equals("mmHg")) {
+ returnString = "mm[Hg]";
+ } else if (unitString.equals("mEq")) {
+ returnString = "meq";
+ } else if (unitString.equals("celsius")) {
+ returnString = "Cel";
+ } else if (unitString.equals("WBC/mm3")) {
+ returnString = "{WBC}/mm3";
+ } else if (unitString.equals("WBC/hpf")) {
+ returnString = "{WBC}/[HPF]";
+ } else if (unitString.equals("CFU/mL")) {
+ returnString = "[CFU]/mL";
+ } else if (unitString.equals("per mm3")) {
+ returnString = "/mm3";
+ } else if (unitString.equals("copies/mL")) {
+ returnString = "{copies}/mL";
+ } else if (unitString.equals("IU")) {
+ returnString = "[iU]";
+ } else if (unitString.equals("IU/L")) {
+ returnString = "[iU]/L";
+ } else if (unitString.equals("AU")) {
+ returnString = "[AU]";
+ } else if (unitString.equals("BAU")) {
+ returnString = "[BAU]";
+ }
+
+ return returnString;
+ }
+
+ /**
+ * Check if out bound is occurrence and append the Attribute entry before Temporal and
+ * outBoundRelationShip Tag.
+ *
+ * @param dataCriteriaElem the data criteria elem
+ * @param dateTimeNode the date time node
+ */
+ private void checkIfOutBoundOcc(Element dataCriteriaElem, Node dateTimeNode) {
+ Node outBoundOccNode = dataCriteriaElem.getElementsByTagName("outboundRelationship").item(0);
+ if ((outBoundOccNode != null)
+ && outBoundOccNode
+ .getAttributes()
+ .getNamedItem("typeCode")
+ .getNodeValue()
+ .equalsIgnoreCase("OCCR")) {
+ dataCriteriaElem.insertBefore(dateTimeNode, outBoundOccNode);
+ } else {
+ dataCriteriaElem.appendChild(dateTimeNode);
+ }
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/HQMFFinalCleanUp.java b/src/main/java/gov/cms/madie/hqmf/HQMFFinalCleanUp.java
index 7502e12..4cd9bff 100644
--- a/src/main/java/gov/cms/madie/hqmf/HQMFFinalCleanUp.java
+++ b/src/main/java/gov/cms/madie/hqmf/HQMFFinalCleanUp.java
@@ -10,182 +10,189 @@
import javax.xml.xpath.XPathExpressionException;
public class HQMFFinalCleanUp {
-
- /** The Constant logger. */
- private static final Logger logger = LoggerFactory
- .getLogger(HQMFFinalCleanUp.class);
-
- /** The Constant reverseEntryCheckFile. */
- private static final String reverseEntryCheckFile = "xsl/final_hqmf_entry_deletion_check.xsl";
-
- /** The Constant deleteUnUsedEntryFile. */
- private static final String deleteUnUsedEntryFile = "xsl/hqmf_delete_Unused_entry.xsl";
-
- /**
- * Clean.
- *
- * @param me the me
- */
- public static void clean(MeasureExport me) {
-
- XmlProcessor hqmfProcessor = me.getHqmfXmlProcessor();
- XmlProcessor simpleProcessor = me.getSimpleXmlProcessor();
-
- if(hqmfProcessor == null){
- logger.debug("HQMF document is null. Aborting clean up.");
- return;
- }
-
- if(simpleProcessor == null){
- logger.debug("SimpleXML document is null. Aborting clean up.");
- return;
- }
-
- cleanExtensions(me);
- cleanLocalVariableNames(me);
- //deleteUnusedEntry(me);
-
- }
-
- public static void cleanAndDeleteUnused(MeasureExport me) {
- clean(me);
- deleteUnusedEntry(me);
- }
-
-
- /**
- * Clean extensions.
- *
- * @param me the me
- */
- private static void cleanExtensions(MeasureExport me) {
-
- String xPathForExtensions = "//*/@extension";
- try {
- NodeList extensionsList = me.getHqmfXmlProcessor().findNodeList(me.getHqmfXmlProcessor().getOriginalDoc(), xPathForExtensions);
- for(int i=0;i=") > -1){
- extValue = StringUtils.replace(extValue, ">=", "grtr_thn_eql_");
-
- }
- if(extValue.indexOf(">") > -1){
- extValue = StringUtils.replace(extValue, ">", "grtr_thn_");
-
- }
- if(extValue.indexOf("<=") > -1){
- extValue = StringUtils.replace(extValue, "<=", "less_thn_eql_");
- }
- if(extValue.indexOf("<") > -1){
- extValue = StringUtils.replace(extValue, "<", "less_thn_");
- }
- if(extValue.indexOf("=") > -1){
- extValue = StringUtils.replace(extValue, "=", "eql_");
- }
- if(extValue.contains(",")) {
- extValue = StringUtils.remove(extValue, ',');
- }
- if(extValue.contains("'")) {
- extValue = StringUtils.remove(extValue, "'");
- }
- return extValue;
- }
-
-
- /**
- * Delete unused entry.
- * This method is to check and delete Unused QDM Entries
- * in HQMF
- *
- * @param me the me
- */
- private static void deleteUnusedEntry(MeasureExport me) {
- String delDupEntryResults = XMLUtility.getInstance().applyXSL(me.getHqmfXmlProcessor().transform(me.getHqmfXmlProcessor().getOriginalDoc()),
- XMLUtility.getInstance().getXMLResource(deleteUnUsedEntryFile));
-
- me.setHqmfXmlProcessor(new XmlProcessor(delDupEntryResults));
-
- reverseEntryCheck(delDupEntryResults);
- }
+ /** The Constant logger. */
+ private static final Logger logger = LoggerFactory.getLogger(HQMFFinalCleanUp.class);
+
+ /** The Constant reverseEntryCheckFile. */
+ private static final String reverseEntryCheckFile = "xsl/final_hqmf_entry_deletion_check.xsl";
+
+ /** The Constant deleteUnUsedEntryFile. */
+ private static final String deleteUnUsedEntryFile = "xsl/hqmf_delete_Unused_entry.xsl";
+
+ /**
+ * Clean.
+ *
+ * @param me the me
+ */
+ public static void clean(MeasureExport me) {
+
+ XmlProcessor hqmfProcessor = me.getHqmfXmlProcessor();
+ XmlProcessor simpleProcessor = me.getSimpleXmlProcessor();
+
+ if (hqmfProcessor == null) {
+ logger.debug("HQMF document is null. Aborting clean up.");
+ return;
+ }
+
+ if (simpleProcessor == null) {
+ logger.debug("SimpleXML document is null. Aborting clean up.");
+ return;
+ }
+
+ cleanExtensions(me);
+ cleanLocalVariableNames(me);
+ // deleteUnusedEntry(me);
+
+ }
+
+ public static void cleanAndDeleteUnused(MeasureExport me) {
+ clean(me);
+ deleteUnusedEntry(me);
+ }
+
+ /**
+ * Clean extensions.
+ *
+ * @param me the me
+ */
+ private static void cleanExtensions(MeasureExport me) {
+
+ String xPathForExtensions = "//*/@extension";
+ try {
+ NodeList extensionsList =
+ me.getHqmfXmlProcessor()
+ .findNodeList(me.getHqmfXmlProcessor().getOriginalDoc(), xPathForExtensions);
+ for (int i = 0; i < extensionsList.getLength(); i++) {
+ Node extNode = extensionsList.item(i);
+ String extValue = extNode.getNodeValue();
+
+ extValue = getReplaceString(extValue);
+ extNode.setNodeValue(extValue);
+ }
+
+ } catch (XPathExpressionException e) {
+ logger.error("Exception in HQMFFinalCleanUp.cleanExtensions:" + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Clean local variable names.
+ *
+ * @param me the me
+ */
+ private static void cleanLocalVariableNames(MeasureExport me) {
+
+ String xPathForLocalVars = "//localVariableName/@value";
+ String xPathForMeasureObValueExpression = "//measureObservationDefinition//value/expression";
+ String xPathForMeasureObPreconditionVal = "//measureObservationDefinition//precondition//value";
+
+ try {
+ NodeList localVarValuesList =
+ me.getHqmfXmlProcessor()
+ .findNodeList(me.getHqmfXmlProcessor().getOriginalDoc(), xPathForLocalVars);
+ NodeList measureObValueExpList =
+ me.getHqmfXmlProcessor()
+ .findNodeList(
+ me.getHqmfXmlProcessor().getOriginalDoc(), xPathForMeasureObValueExpression);
+ NodeList measureObPreConditionValList =
+ me.getHqmfXmlProcessor()
+ .findNodeList(
+ me.getHqmfXmlProcessor().getOriginalDoc(), xPathForMeasureObPreconditionVal);
+ for (int i = 0; i < localVarValuesList.getLength(); i++) {
+ Node extNode = localVarValuesList.item(i);
+ String extValue = extNode.getNodeValue();
+ extValue = getReplaceString(extValue);
+ extNode.setNodeValue(extValue);
+ }
+
+ for (int i = 0; i < measureObValueExpList.getLength(); i++) {
+ Node expressionNode = measureObValueExpList.item(i);
+ String value = expressionNode.getAttributes().getNamedItem("value").getNodeValue();
+ value = getReplaceString(value);
+ expressionNode.getAttributes().getNamedItem("value").setNodeValue(value);
+ }
+
+ for (int i = 0; i < measureObPreConditionValList.getLength(); i++) {
+ Node valueNode = measureObPreConditionValList.item(i);
+ String value = valueNode.getAttributes().getNamedItem("value").getNodeValue();
+ String[] preConditionExpArray = value.split("==");
+ String preCondExpValue = null;
+ for (String valueToEval : preConditionExpArray) {
+ if (preCondExpValue == null) {
+ preCondExpValue = getReplaceString(valueToEval);
+ } else {
+ preCondExpValue = preCondExpValue + "==" + getReplaceString(valueToEval);
+ }
+ }
+ value = getReplaceString(value);
+ valueNode.getAttributes().getNamedItem("value").setNodeValue(preCondExpValue);
+ }
+
+ } catch (XPathExpressionException e) {
+ logger.error("Exception in HQMFFinalCleanUp.cleanExtensions:" + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Reverse entry check.
+ *
+ * @param me the me
+ */
+ private static void reverseEntryCheck(String hqmfXML) {
+ String reverseEntryCheckResults =
+ XMLUtility.getInstance()
+ .applyXSL(hqmfXML, XMLUtility.getInstance().getXMLResource(reverseEntryCheckFile));
+ logger.debug("Reverse Entry Check results: " + reverseEntryCheckResults);
+ }
+
+ /**
+ * Gets the replace string.
+ *
+ * @param extValue the ext value
+ * @return the replace string
+ */
+ private static String getReplaceString(String extValue) {
+ if (extValue.indexOf(">=") > -1) {
+ extValue = StringUtils.replace(extValue, ">=", "grtr_thn_eql_");
+ }
+ if (extValue.indexOf(">") > -1) {
+ extValue = StringUtils.replace(extValue, ">", "grtr_thn_");
+ }
+ if (extValue.indexOf("<=") > -1) {
+ extValue = StringUtils.replace(extValue, "<=", "less_thn_eql_");
+ }
+ if (extValue.indexOf("<") > -1) {
+ extValue = StringUtils.replace(extValue, "<", "less_thn_");
+ }
+ if (extValue.indexOf("=") > -1) {
+ extValue = StringUtils.replace(extValue, "=", "eql_");
+ }
+ if (extValue.contains(",")) {
+ extValue = StringUtils.remove(extValue, ',');
+ }
+ if (extValue.contains("'")) {
+ extValue = StringUtils.remove(extValue, "'");
+ }
+ return extValue;
+ }
+
+ /**
+ * Delete unused entry. This method is to check and delete Unused QDM Entries in HQMF
+ *
+ * @param me the me
+ */
+ private static void deleteUnusedEntry(MeasureExport me) {
+ String delDupEntryResults =
+ XMLUtility.getInstance()
+ .applyXSL(
+ me.getHqmfXmlProcessor().transform(me.getHqmfXmlProcessor().getOriginalDoc()),
+ XMLUtility.getInstance().getXMLResource(deleteUnUsedEntryFile));
+
+ me.setHqmfXmlProcessor(new XmlProcessor(delDupEntryResults));
+
+ reverseEntryCheck(delDupEntryResults);
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/HQMFGeneratorFactory.java b/src/main/java/gov/cms/madie/hqmf/HQMFGeneratorFactory.java
index 568f241..cef6555 100644
--- a/src/main/java/gov/cms/madie/hqmf/HQMFGeneratorFactory.java
+++ b/src/main/java/gov/cms/madie/hqmf/HQMFGeneratorFactory.java
@@ -2,23 +2,20 @@
import gov.cms.madie.hqmf.qdm_5_6.HQMFGenerator;
import lombok.AllArgsConstructor;
-import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
-/**
- * Factory class to select the proper HQMF generator based on QDM model version.
- */
+/** Factory class to select the proper HQMF generator based on QDM model version. */
@Slf4j
@Component
@AllArgsConstructor
-@NoArgsConstructor
public class HQMFGeneratorFactory {
- private HQMFGenerator qdm_5_6_generator;
+ private HQMFGenerator qdm_5_6_generator;
- public Generator getHQMFGenerator() {
- // Keeping generator around in case we need to support additional versions or implementations in the future
- return qdm_5_6_generator;
- }
+ public Generator getHQMFGenerator() {
+ // Keeping generator around in case we need to support additional versions or implementations in
+ // the future
+ return qdm_5_6_generator;
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/MatConstants.java b/src/main/java/gov/cms/madie/hqmf/MatConstants.java
index ebd5885..85905f7 100644
--- a/src/main/java/gov/cms/madie/hqmf/MatConstants.java
+++ b/src/main/java/gov/cms/madie/hqmf/MatConstants.java
@@ -1,97 +1,94 @@
-/**
- *
- */
+/** */
package gov.cms.madie.hqmf;
/**
- * This holds constants used across MAT.
- * These constants are available on client as well as server side.
+ * This holds constants used across MAT. These constants are available on client as well as server
+ * side.
*/
-
public interface MatConstants {
- String NUMERATOR_EXCLUSIONS = "numeratorExclusions";
- String DENOMINATOR_EXCEPTIONS = "denominatorExceptions";
- String DENOMINATOR_EXCLUSIONS = "denominatorExclusions";
- String STRATUM = "stratum";
- String MEASURE_POPULATION_EXCLUSIONS = "measurePopulationExclusions";
- String INITIAL_POPULATION = "initialPopulation";
- String MEASURE_OBSERVATION_POPULATION = "measureObservation";
- String TAXONOMY = "taxonomy";
- String DATATYPE = "datatype";
- String DATETIMEDIFF = "Datetimediff";
- String FIRST = "First";
- String SECOND = "Second";
- String THIRD = "Third";
- String FOURTH = "Fourth";
- String FIFTH = "Fifth";
- String MOST_RECENT = "Most Recent";
- String TIMEDIFF = "TIMEDIFF";
- String SUM = "Sum";
- String MEDIAN = "Median";
- String MIN = "Min";
- String MAX = "Max";
- String DATEDIFF = "DATEDIFF";
- String COUNT = "Count";
- String AVG = "Avg";
- String AGE_AT = "Age At";
- String DATE = "date";
- String MODE = "mode";
- String NAME = "name";
- String NEGATION_RATIONALE = "negation rationale";
- String ATTRIBUTE = "attribute";
- String OCCURRENCE = "Occurrence";
- String UNIT = "unit";
- String UUID = "uuid";
- String ASSOCIATED_POPULATION_UUID = "associatedPopulationUUID";
- String NONE = "None";
- String CONTINUOUS_VARIABLE = "continuous Variable";
- String COHORT = "cohort";
- String PROPORTION = "proportion";
- String SATISFIES = "SATISFIES";
- String STRATIFICATION = "Stratification";
- String TRUE = "true";
- String AND = "AND";
- String MEASURE_OBSERVATION = "Measure Observation";
- String MEASURE_DETAILS = "measureDetails";
- String RATIO = "ratio";
- String MEASURE_POPULATION = "measurePopulation";
- String NUMERATOR = "numerator";
- String DENOMINATOR = "denominator";
- String TYPE = "type";
- String FALSE = "false";
- String QDM_VARIABLE = "qdmVariable";
- String ID = "id";
- String INSTANCE_OF = "instanceOf";
- String INSTANCE = "instance";
- String ELEMENT_LOOK_UP = "elementLookUp";
- String FUNCTIONAL_OP = "functionalOp";
- String DISPLAY_NAME = "displayName";
- String ELEMENT_REF = "elementRef";
- String RELATIONAL_OP = "relationalOp";
- String HTML_LI = "li";
- String HTML_UL = "ul";
- String SET_OP = "setOp";
- String SUB_TREE = "subTree";
- String COMMENT = "comment";
- String LOGICAL_OP = "logicalOp";
- String ATTR_UUID = "attrUUID";
- String SUB_TREE_REF = "subTreeRef";
- String EXTENSION = "extension";
- String FULFILLS = "FULFILLS";
- String QUANTITY = "quantity";
- String ATTR_DATE = "attrDate";
- String COMPARISON_VALUE = "comparisonValue";
- String OPERATOR_TYPE = "operatorType";
- String SATISFIES_ANY = "Satisfies Any";
- String SATISFIES_ALL = "Satisfies All";
- String STARTS_CONCURRENT_WITH = "Starts Concurrent With";
- String STARTS_CONCURRENT_WITH_END_OF = "Starts Concurrent With End Of";
- String STARTS_DURING = "Starts During";
- String ENDS_CONCURRENT_WITH = "Ends Concurrent With";
- String ENDS_CONCURRENT_WITH_START_OF = "Ends Concurrent With Start Of";
- String ENDS_DURING = "Ends During";
- String CONCURRENT_WITH = "Concurrent With";
- String DURING = "During";
- String OVERLAPS = "Overlaps";
- String NOT_APPLICABLE = "Not Applicable";
+ String NUMERATOR_EXCLUSIONS = "numeratorExclusions";
+ String DENOMINATOR_EXCEPTIONS = "denominatorExceptions";
+ String DENOMINATOR_EXCLUSIONS = "denominatorExclusions";
+ String STRATUM = "stratum";
+ String MEASURE_POPULATION_EXCLUSIONS = "measurePopulationExclusions";
+ String INITIAL_POPULATION = "initialPopulation";
+ String MEASURE_OBSERVATION_POPULATION = "measureObservation";
+ String TAXONOMY = "taxonomy";
+ String DATATYPE = "datatype";
+ String DATETIMEDIFF = "Datetimediff";
+ String FIRST = "First";
+ String SECOND = "Second";
+ String THIRD = "Third";
+ String FOURTH = "Fourth";
+ String FIFTH = "Fifth";
+ String MOST_RECENT = "Most Recent";
+ String TIMEDIFF = "TIMEDIFF";
+ String SUM = "Sum";
+ String MEDIAN = "Median";
+ String MIN = "Min";
+ String MAX = "Max";
+ String DATEDIFF = "DATEDIFF";
+ String COUNT = "Count";
+ String AVG = "Avg";
+ String AGE_AT = "Age At";
+ String DATE = "date";
+ String MODE = "mode";
+ String NAME = "name";
+ String NEGATION_RATIONALE = "negation rationale";
+ String ATTRIBUTE = "attribute";
+ String OCCURRENCE = "Occurrence";
+ String UNIT = "unit";
+ String UUID = "uuid";
+ String ASSOCIATED_POPULATION_UUID = "associatedPopulationUUID";
+ String NONE = "None";
+ String CONTINUOUS_VARIABLE = "continuous Variable";
+ String COHORT = "cohort";
+ String PROPORTION = "proportion";
+ String SATISFIES = "SATISFIES";
+ String STRATIFICATION = "Stratification";
+ String TRUE = "true";
+ String AND = "AND";
+ String MEASURE_OBSERVATION = "Measure Observation";
+ String MEASURE_DETAILS = "measureDetails";
+ String RATIO = "ratio";
+ String MEASURE_POPULATION = "measurePopulation";
+ String NUMERATOR = "numerator";
+ String DENOMINATOR = "denominator";
+ String TYPE = "type";
+ String FALSE = "false";
+ String QDM_VARIABLE = "qdmVariable";
+ String ID = "id";
+ String INSTANCE_OF = "instanceOf";
+ String INSTANCE = "instance";
+ String ELEMENT_LOOK_UP = "elementLookUp";
+ String FUNCTIONAL_OP = "functionalOp";
+ String DISPLAY_NAME = "displayName";
+ String ELEMENT_REF = "elementRef";
+ String RELATIONAL_OP = "relationalOp";
+ String HTML_LI = "li";
+ String HTML_UL = "ul";
+ String SET_OP = "setOp";
+ String SUB_TREE = "subTree";
+ String COMMENT = "comment";
+ String LOGICAL_OP = "logicalOp";
+ String ATTR_UUID = "attrUUID";
+ String SUB_TREE_REF = "subTreeRef";
+ String EXTENSION = "extension";
+ String FULFILLS = "FULFILLS";
+ String QUANTITY = "quantity";
+ String ATTR_DATE = "attrDate";
+ String COMPARISON_VALUE = "comparisonValue";
+ String OPERATOR_TYPE = "operatorType";
+ String SATISFIES_ANY = "Satisfies Any";
+ String SATISFIES_ALL = "Satisfies All";
+ String STARTS_CONCURRENT_WITH = "Starts Concurrent With";
+ String STARTS_CONCURRENT_WITH_END_OF = "Starts Concurrent With End Of";
+ String STARTS_DURING = "Starts During";
+ String ENDS_CONCURRENT_WITH = "Ends Concurrent With";
+ String ENDS_CONCURRENT_WITH_START_OF = "Ends Concurrent With Start Of";
+ String ENDS_DURING = "Ends During";
+ String CONCURRENT_WITH = "Concurrent With";
+ String DURING = "During";
+ String OVERLAPS = "Overlaps";
+ String NOT_APPLICABLE = "Not Applicable";
}
diff --git a/src/main/java/gov/cms/madie/hqmf/QDMTemplateProcessorFactory.java b/src/main/java/gov/cms/madie/hqmf/QDMTemplateProcessorFactory.java
index d7fb6e6..2e33a2f 100644
--- a/src/main/java/gov/cms/madie/hqmf/QDMTemplateProcessorFactory.java
+++ b/src/main/java/gov/cms/madie/hqmf/QDMTemplateProcessorFactory.java
@@ -7,35 +7,23 @@
/**
* DO NOT DELETE OLDER GENERATORS.
*
- * On Export, MAT will serve up the latest pre-existing instance in the MEASURE_EXPORT table. If no HQMF exists,
- * then MAT will generate the HQMF during the Export operation and save it to the table. Older versions of the Generators
- * are kept to ensure the HQMF can be generated on-demand.
+ * On Export, MAT will serve up the latest pre-existing instance in the MEASURE_EXPORT table. If
+ * no HQMF exists, then MAT will generate the HQMF during the Export operation and save it to the
+ * table. Older versions of the Generators are kept to ensure the HQMF can be generated on-demand.
*/
public class QDMTemplateProcessorFactory {
-
- public static XmlProcessor getTemplateProcessor(double qdmVersion) {
- String fileName;
-// if(qdmVersion == 5.3) {
-// fileName = "templates/hqmf/qdm_v5_3_datatype_templates.xml";
-// } else if(qdmVersion == 5.4) {
-// fileName = "templates/hqmf/qdm_v5_4_datatype_templates.xml";
-// } else if(qdmVersion == 5.5) {
-// fileName = "templates/hqmf/qdm_v5_5_datatype_templates.xml";
-// } else if(qdmVersion == 5.6) {
- fileName = "templates/hqmf/qdm_v5_6_datatype_templates.xml";
-// } else {
-// fileName = "templates/hqmf/qdm_v4_x_datatype_templates.xml";
-// }
+ public static XmlProcessor getTemplateProcessor(double qdmVersion) {
+ String fileName = "templates/hqmf/qdm_v5_6_datatype_templates.xml";
- URL templateFileUrl = QDMTemplateProcessorFactory.class.getClassLoader().getResource(fileName);
- File templateFile = null;
- try {
- templateFile = new File(templateFileUrl.toURI());
- } catch (URISyntaxException e) {
- e.printStackTrace();
- }
-
- return new XmlProcessor(templateFile);
- }
+ URL templateFileUrl = QDMTemplateProcessorFactory.class.getClassLoader().getResource(fileName);
+ File templateFile = null;
+ try {
+ templateFile = new File(templateFileUrl.toURI());
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+
+ return new XmlProcessor(templateFile);
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/UUIDUtilClient.java b/src/main/java/gov/cms/madie/hqmf/UUIDUtilClient.java
index 1b3caba..9b524db 100644
--- a/src/main/java/gov/cms/madie/hqmf/UUIDUtilClient.java
+++ b/src/main/java/gov/cms/madie/hqmf/UUIDUtilClient.java
@@ -1,75 +1,68 @@
package gov.cms.madie.hqmf;
-/**
- * The Class UUIDUtilClient.
- */
+/** The Class UUIDUtilClient. */
public class UUIDUtilClient {
- /** The Constant CHARS. */
- private static final char[] CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
-
- /**
- * Generate a random uuid of the specified length. Example: uuid(15)
- * returns "VcydxgltxrVZSTV"
- *
- * @param len
- * the desired number of characters
- * @return the string
- */
- public static String uuid(int len) {
- return uuid(len, CHARS.length);
- }
-
- /**
- * Generate a random uuid of the specified length, and radix. Examples:
- *
- * - uuid(8, 2) returns "01001010" (8 character ID, base=2)
- *
- uuid(8, 10) returns "47473046" (8 character ID, base=10)
- *
- uuid(8, 16) returns "098F4D35" (8 character ID, base=16)
- *
- *
- * @param len
- * the desired number of characters
- * @param radix
- * the number of allowable values for each character (must be
- * <= 62)
- * @return the string
- */
- public static String uuid(int len, int radix) {
- if (radix > CHARS.length) {
- throw new IllegalArgumentException();
- }
- char[] uuid = new char[len];
- // Compact form
- for (int i = 0; i < len; i++) {
- uuid[i] = CHARS[(int)(Math.random()*radix)];
- }
- return new String(uuid);
- }
-
- /**
- * Generate a RFC4122, version 4 ID. Example:
- * "92329D39-6F5C-4520-ABFC-AAB64544E172"
- *
- * @return the string
- */
- public static String uuid() {
- char[] uuid = new char[36];
- int r;
+ /** The Constant CHARS. */
+ private static final char[] CHARS =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
- // rfc4122 requires these characters
- uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
- uuid[14] = '4';
+ /**
+ * Generate a random uuid of the specified length. Example: uuid(15) returns "VcydxgltxrVZSTV"
+ *
+ * @param len the desired number of characters
+ * @return the string
+ */
+ public static String uuid(int len) {
+ return uuid(len, CHARS.length);
+ }
- // Fill in random data. At i==19 set the high bits of clock sequence as
- // per rfc4122, sec. 4.1.5
- for (int i = 0; i < 36; i++) {
- if (uuid[i] == 0) {
- r = (int) (Math.random()*16);
- uuid[i] = CHARS[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];
- }
- }
- return new String(uuid);
- }
+ /**
+ * Generate a random uuid of the specified length, and radix. Examples:
+ *
+ *
+ * - uuid(8, 2) returns "01001010" (8 character ID, base=2)
+ *
- uuid(8, 10) returns "47473046" (8 character ID, base=10)
+ *
- uuid(8, 16) returns "098F4D35" (8 character ID, base=16)
+ *
+ *
+ * @param len the desired number of characters
+ * @param radix the number of allowable values for each character (must be <= 62)
+ * @return the string
+ */
+ public static String uuid(int len, int radix) {
+ if (radix > CHARS.length) {
+ throw new IllegalArgumentException();
+ }
+ char[] uuid = new char[len];
+ // Compact form
+ for (int i = 0; i < len; i++) {
+ uuid[i] = CHARS[(int) (Math.random() * radix)];
+ }
+ return new String(uuid);
+ }
+ /**
+ * Generate a RFC4122, version 4 ID. Example: "92329D39-6F5C-4520-ABFC-AAB64544E172"
+ *
+ * @return the string
+ */
+ public static String uuid() {
+ char[] uuid = new char[36];
+ int r;
+
+ // rfc4122 requires these characters
+ uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
+ uuid[14] = '4';
+
+ // Fill in random data. At i==19 set the high bits of clock sequence as
+ // per rfc4122, sec. 4.1.5
+ for (int i = 0; i < 36; i++) {
+ if (uuid[i] == 0) {
+ r = (int) (Math.random() * 16);
+ uuid[i] = CHARS[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];
+ }
+ }
+ return new String(uuid);
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/XMLUtility.java b/src/main/java/gov/cms/madie/hqmf/XMLUtility.java
index 290ca28..00c64d1 100644
--- a/src/main/java/gov/cms/madie/hqmf/XMLUtility.java
+++ b/src/main/java/gov/cms/madie/hqmf/XMLUtility.java
@@ -26,121 +26,124 @@
@Slf4j
public class XMLUtility {
- private static final String HTTP_WWW_W3_ORG_2001_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
- private static XMLUtility instance;
- private static final String DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
- private static final String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
- private static final String EXTERNAL_GENERAL_ENTITIES = "http://xml.org/sax/features/external-general-entities";
- private static final String EXTERNAL_PARAMETER_ENTITIES = "http://xml.org/sax/features/external-parameter-entities";
-
- public static XMLUtility getInstance() {
- if(instance == null) {
- instance = new XMLUtility();
- }
- return instance;
- }
- private XMLUtility() {}
+ private static final String HTTP_WWW_W3_ORG_2001_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
+ private static XMLUtility instance;
+ private static final String DISALLOW_DOCTYPE_DECL =
+ "http://apache.org/xml/features/disallow-doctype-decl";
+ private static final String LOAD_EXTERNAL_DTD =
+ "http://apache.org/xml/features/nonvalidating/load-external-dtd";
+ private static final String EXTERNAL_GENERAL_ENTITIES =
+ "http://xml.org/sax/features/external-general-entities";
+ private static final String EXTERNAL_PARAMETER_ENTITIES =
+ "http://xml.org/sax/features/external-parameter-entities";
- /**
- * Apply xsl.
- *
- * @param input
- * the input
- * @param xslt
- * the xslt
- * @return the string
- */
- public String applyXSL(String input, String xslt)
- {
- //This system property sets the TransformFactory to use the Saxon TransformerFactoryImpl method
- //This line is needed to prevent issues with XSLT transform.
- System.setProperty("javax.xml.transform.TransformerFactory","net.sf.saxon.TransformerFactoryImpl");
- String result;
- ByteArrayOutputStream outStream;
- outStream = new ByteArrayOutputStream();
- TransformerFactory tFactory = buildTransformerFactory();
- Transformer transformer;
- try {
- transformer = tFactory.newTransformer(new StreamSource(xslt));
- transformer.transform(new StreamSource(new StringReader(input)), new StreamResult(outStream));
- } catch (TransformerConfigurationException e) {
- log.error("An error occurred in transformer", e);
- throw new RuntimeException("Error Configuring XML Transformer:", e.getCause());
- } catch (TransformerException e) {
- log.error("An error occurred in transformer", e);
- throw new RuntimeException("Error Transforming XML:", e.getCause());
- }catch(Exception e){
- log.error("An error occurred in transformer", e);
- }
- result = outStream.toString();
- return result;
- }
-
- /**
- * Gets the xML resource.
- *
- * @param name
- * the name
- * @return the xML resource
- */
- public String getXMLResource(String name) {
- try {
- return new ClassPathResource(name).getURL().toExternalForm();
- } catch (IOException e) {
- log.error("An error occurred loading the resource [{}]: ", name, e);
- }
- return null;
- }
-
- public TransformerFactory buildTransformerFactory() {
- TransformerFactory transformerFactory = SAXTransformerFactory.newInstance();
+ public static XMLUtility getInstance() {
+ if (instance == null) {
+ instance = new XMLUtility();
+ }
+ return instance;
+ }
- try {
- transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
- transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
- } catch(IllegalArgumentException | TransformerConfigurationException e) {
- /* see JDK-8015487, some parsers do not handle these attributes */
- }
+ private XMLUtility() {}
+ /**
+ * Apply xsl.
+ *
+ * @param input the input
+ * @param xslt the xslt
+ * @return the string
+ */
+ public String applyXSL(String input, String xslt) {
+ // This system property sets the TransformFactory to use the Saxon TransformerFactoryImpl method
+ // This line is needed to prevent issues with XSLT transform.
+ System.setProperty(
+ "javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
+ String result;
+ ByteArrayOutputStream outStream;
+ outStream = new ByteArrayOutputStream();
+ TransformerFactory tFactory = buildTransformerFactory();
+ Transformer transformer;
+ try {
+ transformer = tFactory.newTransformer(new StreamSource(xslt));
+ transformer.transform(new StreamSource(new StringReader(input)), new StreamResult(outStream));
+ } catch (TransformerConfigurationException e) {
+ log.error("An error occurred in transformer", e);
+ throw new RuntimeException("Error Configuring XML Transformer:", e.getCause());
+ } catch (TransformerException e) {
+ log.error("An error occurred in transformer", e);
+ throw new RuntimeException("Error Transforming XML:", e.getCause());
+ } catch (Exception e) {
+ log.error("An error occurred in transformer", e);
+ }
+ result = outStream.toString();
+ return result;
+ }
- return transformerFactory;
- }
-
- public DocumentBuilderFactory buildDocumentBuilderFactory() throws ParserConfigurationException {
- DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
- documentBuilderFactory.setFeature(DISALLOW_DOCTYPE_DECL, true);
- documentBuilderFactory.setFeature(EXTERNAL_GENERAL_ENTITIES, false);
- documentBuilderFactory.setFeature(EXTERNAL_PARAMETER_ENTITIES, false);
- documentBuilderFactory.setFeature(LOAD_EXTERNAL_DTD, false);
- documentBuilderFactory.setXIncludeAware(false);
- documentBuilderFactory.setExpandEntityReferences(false);
- return documentBuilderFactory;
- }
-
- public SAXParserFactory buildSaxParserFactory() throws SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException {
- SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
- saxParserFactory.setFeature(DISALLOW_DOCTYPE_DECL, true);
- saxParserFactory.setFeature(EXTERNAL_GENERAL_ENTITIES, false);
- saxParserFactory.setFeature(EXTERNAL_PARAMETER_ENTITIES, false);
- saxParserFactory.setFeature(LOAD_EXTERNAL_DTD, false);
- saxParserFactory.setXIncludeAware(false);
- return saxParserFactory;
- }
-
- public SchemaFactory buildSchemaFactory() throws SAXNotRecognizedException, SAXNotSupportedException {
- SchemaFactory schemaFactory = SchemaFactory.newInstance(HTTP_WWW_W3_ORG_2001_XML_SCHEMA);
- schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
- schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
- return schemaFactory;
- }
-
- public XMLReader getXMLReader(SAXParser parser) throws SAXException {
- XMLReader reader = parser.getXMLReader();
- reader.setFeature(DISALLOW_DOCTYPE_DECL, true);
- reader.setFeature(LOAD_EXTERNAL_DTD, false);
- reader.setFeature(EXTERNAL_GENERAL_ENTITIES, false);
- reader.setFeature(EXTERNAL_PARAMETER_ENTITIES, false);
- return reader;
- }
+ /**
+ * Gets the xML resource.
+ *
+ * @param name the name
+ * @return the xML resource
+ */
+ public String getXMLResource(String name) {
+ try {
+ return new ClassPathResource(name).getURL().toExternalForm();
+ } catch (IOException e) {
+ log.error("An error occurred loading the resource [{}]: ", name, e);
+ }
+ return null;
+ }
+
+ public TransformerFactory buildTransformerFactory() {
+ TransformerFactory transformerFactory = SAXTransformerFactory.newInstance();
+
+ try {
+ transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
+ transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+ } catch (IllegalArgumentException | TransformerConfigurationException e) {
+ /* see JDK-8015487, some parsers do not handle these attributes */
+ }
+
+ return transformerFactory;
+ }
+
+ public DocumentBuilderFactory buildDocumentBuilderFactory() throws ParserConfigurationException {
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setFeature(DISALLOW_DOCTYPE_DECL, true);
+ documentBuilderFactory.setFeature(EXTERNAL_GENERAL_ENTITIES, false);
+ documentBuilderFactory.setFeature(EXTERNAL_PARAMETER_ENTITIES, false);
+ documentBuilderFactory.setFeature(LOAD_EXTERNAL_DTD, false);
+ documentBuilderFactory.setXIncludeAware(false);
+ documentBuilderFactory.setExpandEntityReferences(false);
+ return documentBuilderFactory;
+ }
+
+ public SAXParserFactory buildSaxParserFactory()
+ throws SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException {
+ SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+ saxParserFactory.setFeature(DISALLOW_DOCTYPE_DECL, true);
+ saxParserFactory.setFeature(EXTERNAL_GENERAL_ENTITIES, false);
+ saxParserFactory.setFeature(EXTERNAL_PARAMETER_ENTITIES, false);
+ saxParserFactory.setFeature(LOAD_EXTERNAL_DTD, false);
+ saxParserFactory.setXIncludeAware(false);
+ return saxParserFactory;
+ }
+
+ public SchemaFactory buildSchemaFactory()
+ throws SAXNotRecognizedException, SAXNotSupportedException {
+ SchemaFactory schemaFactory = SchemaFactory.newInstance(HTTP_WWW_W3_ORG_2001_XML_SCHEMA);
+ schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+ schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
+ return schemaFactory;
+ }
+
+ public XMLReader getXMLReader(SAXParser parser) throws SAXException {
+ XMLReader reader = parser.getXMLReader();
+ reader.setFeature(DISALLOW_DOCTYPE_DECL, true);
+ reader.setFeature(LOAD_EXTERNAL_DTD, false);
+ reader.setFeature(EXTERNAL_GENERAL_ENTITIES, false);
+ reader.setFeature(EXTERNAL_PARAMETER_ENTITIES, false);
+ return reader;
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/XmlProcessor.java b/src/main/java/gov/cms/madie/hqmf/XmlProcessor.java
index fcecbf0..ef1a29d 100644
--- a/src/main/java/gov/cms/madie/hqmf/XmlProcessor.java
+++ b/src/main/java/gov/cms/madie/hqmf/XmlProcessor.java
@@ -1,6 +1,5 @@
package gov.cms.madie.hqmf;
-
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
@@ -38,1143 +37,1154 @@
@Slf4j
public class XmlProcessor {
- private static final String COHORT = "COHORT";
- private static final String XPATH_POPULATIONS = "/measure/populations";
- private static final String XPATH_NUMERATORS = "/measure/populations/numerators";
- private static final String XPATH_DENOMINATOR = "/measure/populations/denominators";
- private static final String XPATH_NUMERATOR_EXCLUSIONS = "/measure/populations/numeratorExclusions";
- private static final String XPATH_MEASURE_OBSERVATIONS = "/measure/measureObservations";
- private static final String XPATH_MEASURE_STRATIFICATIONS = "/measure/strata";
- private static final String XPATH_MEASURE_SD_ELEMENTS = "/measure/supplementalDataElements";
- private static final String XPATH_MEASURE_RAV_ELEMENTS = "/measure/riskAdjustmentVariables";
- private static final String XPATH_MEASURE_ELEMENT_LOOKUP = "/measure/elementLookUp";
- private static final String XPATH_MEASURE_SUBTREE_LOOKUP = "/measure/subTreeLookUp";
- private static final String XPATH_MEASURE_POPULATIONS = "/measure/populations/measurePopulations";
- private static final String XPATH_MEASURE_POPULATION_EXCLUSIONS = "/measure/populations/measurePopulationExclusions";
- private static final String XPATH_DENOMINATOR_EXCEPTIONS = "/measure/populations/denominatorExceptions";
- private static final String XPATH_DENOMINATOR_EXCLUSIONS = "/measure/populations/denominatorExclusions";
- private static final String RATIO = "RATIO";
- private static final String PROPORTION = "PROPORTION";
- private static final String CONTINUOUS_VARIABLE = "CONTINUOUS VARIABLE";
- private static final String NUMERATOR_EXCLUSIONS = "numeratorExclusions";
- private static final String DENOMINATOR_EXCEPTIONS = "denominatorExceptions";
- private static final String DENOMINATOR_EXCLUSIONS = "denominatorExclusions";
- private static final String DENOMINATORS = "denominators";
- private static final String NUMERATORS = "numerators";
- private static final String MEASURE_POPULATIONS = "measurePopulations";
- private static final String MEASURE_POPULATION_EXCLUSIONS = "measurePopulationExclusions";
- private static final String INITIAL_POPULATIONS = "initialPopulations";
- public static final String XPATH_MEASURE_CLAUSE = "/measure/populations/*/clause | /measure/*/clause | /measure/strata/stratification | /measure/strata/Stratification";
- public static final String XPATH_MEASURE_GROUPING = "/measure/measureGrouping";
- public static final String XPATH_MEASURE_GROUPING_GROUP = "/measure/measureGrouping/group";
- public static final String XPATH_GROUP_SEQ_START = "/measure/measureGrouping/group[@sequence = '";
- public static final String XPATH_GROUP_SEQ_END = "' ] ";
- public static final String XPATH_FIND_GROUP_CLAUSE = "/measure/measureGrouping/group[packageClause[";
- public static final String XPATH_OLD_ALL_RELATIONALOP_SBOD = "/measure//*/relationalOp[@type='SBOD']";
- public static final String XPATH_OLD_ALL_RELATIONALOP_EBOD = "/measure//*/relationalOp[@type='EBOD']";
- public static final String STRATIFICATION = "stratification";
- private static final String STRATIFICATION_DISPLAYNAME = "Stratification 1";
- private static final String MEASURE_OBSERVATION = "measureObservations";
- private static final String AND = "and";
- private static final String OR_STRING = "or";
- private static final String UUID_STRING = "uuid";
- private static final String DISPLAY_NAME = "displayName";
- private static final String TYPE = "type";
- private static final String PATIENT = " Patient ";
- private static Map constantsMap = new HashMap();
- private static Map topNodeOperatorMap = new HashMap();
- private String originalXml;
- private DocumentBuilder docBuilder;
- private Document originalDoc;
- private static final String PARAMETER_MEASUREMENT_PERIOD = "Measurement Period";
- private static final String XPATH_FOR_CODES = "//cqlLookUp/codes/code";
- private static final String XPATH_FOR_VALUESETS = "//cqlLookUp/valuesets/valueset";
- private static final String ATTRIBUTE_CODE_OID = "codeOID";
- private static final String ATTRIBUTE_CODE_NAME = "codeName";
- private static final String ATTRIBUTE_READ_ONLY = "readOnly";
- private static final String ATTRIBUTE_CODE_SYSTEM_OID = "codeSystemOID";
- private static final String[] POPULATIONS = {
- INITIAL_POPULATIONS, NUMERATORS, NUMERATOR_EXCLUSIONS, DENOMINATORS,
- DENOMINATOR_EXCLUSIONS, DENOMINATOR_EXCEPTIONS, MEASURE_POPULATIONS,
- MEASURE_POPULATION_EXCLUSIONS};
-
- static {
- constantsMap.put("populations", "Populations");
- constantsMap.put(MEASURE_OBSERVATION, "Measure Observations");
- constantsMap.put("strata", "Stratification");
- constantsMap.put("initialPopulations", "Initial Populations");
- constantsMap.put("numerators", "Numerators");
- constantsMap.put("denominators", "Denominators");
- constantsMap.put("denominatorExclusions", "Denominator Exclusions");
- constantsMap.put("denominatorExceptions", "Denominator Exceptions");
- constantsMap.put("measurePopulations", "Measure Populations");
- constantsMap.put("measurePopulationExclusions", "Measure Population Exclusions");
- constantsMap.put("numeratorExclusions", "Numerator Exclusions");
- constantsMap.put("Measure Observations", "Measure Observation");
- constantsMap.put("Stratum", "Stratum");
- constantsMap.put("Initial Populations", "Initial Population");
- constantsMap.put("Numerators", "Numerator");
- constantsMap.put("Denominators", "Denominator");
- constantsMap.put("Denominator Exclusions", "Denominator Exclusions");
- constantsMap.put("Denominator Exceptions", "Denominator Exceptions");
- constantsMap.put("Measure Populations", "Measure Population");
- constantsMap.put("Measure Population Exclusions", "Measure Population Exclusions");
- constantsMap.put("Numerator Exclusions", "Numerator Exclusions");
- topNodeOperatorMap.put("initialPopulations", AND);
- topNodeOperatorMap.put("numerators", AND);
- topNodeOperatorMap.put("denominators", AND);
- topNodeOperatorMap.put("measurePopulations", AND);
- topNodeOperatorMap.put("denominatorExclusions", OR_STRING);
- topNodeOperatorMap.put("numeratorExclusions", OR_STRING);
- topNodeOperatorMap.put("denominatorExceptions", OR_STRING);
- topNodeOperatorMap.put("measurePopulationExclusions", OR_STRING);
+ private static final String COHORT = "COHORT";
+ private static final String XPATH_POPULATIONS = "/measure/populations";
+ private static final String XPATH_NUMERATORS = "/measure/populations/numerators";
+ private static final String XPATH_DENOMINATOR = "/measure/populations/denominators";
+ private static final String XPATH_NUMERATOR_EXCLUSIONS =
+ "/measure/populations/numeratorExclusions";
+ private static final String XPATH_MEASURE_OBSERVATIONS = "/measure/measureObservations";
+ private static final String XPATH_MEASURE_STRATIFICATIONS = "/measure/strata";
+ private static final String XPATH_MEASURE_SD_ELEMENTS = "/measure/supplementalDataElements";
+ private static final String XPATH_MEASURE_RAV_ELEMENTS = "/measure/riskAdjustmentVariables";
+ private static final String XPATH_MEASURE_ELEMENT_LOOKUP = "/measure/elementLookUp";
+ private static final String XPATH_MEASURE_SUBTREE_LOOKUP = "/measure/subTreeLookUp";
+ private static final String XPATH_MEASURE_POPULATIONS = "/measure/populations/measurePopulations";
+ private static final String XPATH_MEASURE_POPULATION_EXCLUSIONS =
+ "/measure/populations/measurePopulationExclusions";
+ private static final String XPATH_DENOMINATOR_EXCEPTIONS =
+ "/measure/populations/denominatorExceptions";
+ private static final String XPATH_DENOMINATOR_EXCLUSIONS =
+ "/measure/populations/denominatorExclusions";
+ private static final String RATIO = "RATIO";
+ private static final String PROPORTION = "PROPORTION";
+ private static final String CONTINUOUS_VARIABLE = "CONTINUOUS VARIABLE";
+ private static final String NUMERATOR_EXCLUSIONS = "numeratorExclusions";
+ private static final String DENOMINATOR_EXCEPTIONS = "denominatorExceptions";
+ private static final String DENOMINATOR_EXCLUSIONS = "denominatorExclusions";
+ private static final String DENOMINATORS = "denominators";
+ private static final String NUMERATORS = "numerators";
+ private static final String MEASURE_POPULATIONS = "measurePopulations";
+ private static final String MEASURE_POPULATION_EXCLUSIONS = "measurePopulationExclusions";
+ private static final String INITIAL_POPULATIONS = "initialPopulations";
+ public static final String XPATH_MEASURE_CLAUSE =
+ "/measure/populations/*/clause | /measure/*/clause | /measure/strata/stratification | /measure/strata/Stratification";
+ public static final String XPATH_MEASURE_GROUPING = "/measure/measureGrouping";
+ public static final String XPATH_MEASURE_GROUPING_GROUP = "/measure/measureGrouping/group";
+ public static final String XPATH_GROUP_SEQ_START = "/measure/measureGrouping/group[@sequence = '";
+ public static final String XPATH_GROUP_SEQ_END = "' ] ";
+ public static final String XPATH_FIND_GROUP_CLAUSE =
+ "/measure/measureGrouping/group[packageClause[";
+ public static final String XPATH_OLD_ALL_RELATIONALOP_SBOD =
+ "/measure//*/relationalOp[@type='SBOD']";
+ public static final String XPATH_OLD_ALL_RELATIONALOP_EBOD =
+ "/measure//*/relationalOp[@type='EBOD']";
+ public static final String STRATIFICATION = "stratification";
+ private static final String STRATIFICATION_DISPLAYNAME = "Stratification 1";
+ private static final String MEASURE_OBSERVATION = "measureObservations";
+ private static final String AND = "and";
+ private static final String OR_STRING = "or";
+ private static final String UUID_STRING = "uuid";
+ private static final String DISPLAY_NAME = "displayName";
+ private static final String TYPE = "type";
+ private static final String PATIENT = " Patient ";
+ private static Map constantsMap = new HashMap();
+ private static Map topNodeOperatorMap = new HashMap();
+ private String originalXml;
+ private DocumentBuilder docBuilder;
+ private Document originalDoc;
+ private static final String PARAMETER_MEASUREMENT_PERIOD = "Measurement Period";
+ private static final String XPATH_FOR_CODES = "//cqlLookUp/codes/code";
+ private static final String XPATH_FOR_VALUESETS = "//cqlLookUp/valuesets/valueset";
+ private static final String ATTRIBUTE_CODE_OID = "codeOID";
+ private static final String ATTRIBUTE_CODE_NAME = "codeName";
+ private static final String ATTRIBUTE_READ_ONLY = "readOnly";
+ private static final String ATTRIBUTE_CODE_SYSTEM_OID = "codeSystemOID";
+ private static final String[] POPULATIONS = {
+ INITIAL_POPULATIONS,
+ NUMERATORS,
+ NUMERATOR_EXCLUSIONS,
+ DENOMINATORS,
+ DENOMINATOR_EXCLUSIONS,
+ DENOMINATOR_EXCEPTIONS,
+ MEASURE_POPULATIONS,
+ MEASURE_POPULATION_EXCLUSIONS
+ };
+
+ static {
+ constantsMap.put("populations", "Populations");
+ constantsMap.put(MEASURE_OBSERVATION, "Measure Observations");
+ constantsMap.put("strata", "Stratification");
+ constantsMap.put("initialPopulations", "Initial Populations");
+ constantsMap.put("numerators", "Numerators");
+ constantsMap.put("denominators", "Denominators");
+ constantsMap.put("denominatorExclusions", "Denominator Exclusions");
+ constantsMap.put("denominatorExceptions", "Denominator Exceptions");
+ constantsMap.put("measurePopulations", "Measure Populations");
+ constantsMap.put("measurePopulationExclusions", "Measure Population Exclusions");
+ constantsMap.put("numeratorExclusions", "Numerator Exclusions");
+ constantsMap.put("Measure Observations", "Measure Observation");
+ constantsMap.put("Stratum", "Stratum");
+ constantsMap.put("Initial Populations", "Initial Population");
+ constantsMap.put("Numerators", "Numerator");
+ constantsMap.put("Denominators", "Denominator");
+ constantsMap.put("Denominator Exclusions", "Denominator Exclusions");
+ constantsMap.put("Denominator Exceptions", "Denominator Exceptions");
+ constantsMap.put("Measure Populations", "Measure Population");
+ constantsMap.put("Measure Population Exclusions", "Measure Population Exclusions");
+ constantsMap.put("Numerator Exclusions", "Numerator Exclusions");
+ topNodeOperatorMap.put("initialPopulations", AND);
+ topNodeOperatorMap.put("numerators", AND);
+ topNodeOperatorMap.put("denominators", AND);
+ topNodeOperatorMap.put("measurePopulations", AND);
+ topNodeOperatorMap.put("denominatorExclusions", OR_STRING);
+ topNodeOperatorMap.put("numeratorExclusions", OR_STRING);
+ topNodeOperatorMap.put("denominatorExceptions", OR_STRING);
+ topNodeOperatorMap.put("measurePopulationExclusions", OR_STRING);
+ }
+
+ /**
+ * Instantiates a new xml processor.
+ *
+ * @param originalXml the original xml
+ */
+ public XmlProcessor(String originalXml) {
+ log.debug("In XmlProcessor() constructor");
+ this.originalXml = originalXml;
+ try {
+ DocumentBuilderFactory documentBuilderFactory =
+ XMLUtility.getInstance().buildDocumentBuilderFactory();
+ docBuilder = documentBuilderFactory.newDocumentBuilder();
+ InputSource oldXmlstream = new InputSource(new StringReader(originalXml));
+ originalDoc = docBuilder.parse(oldXmlstream);
+ log.debug("Document Object created successfully for the XML String");
+ } catch (Exception e) {
+ log.error("Exception thrown on XmlProcessor() constructor", e);
+ caughtExceptions(e);
}
-
- /**
- * Instantiates a new xml processor.
- *
- * @param originalXml the original xml
- */
- public XmlProcessor(String originalXml) {
- log.debug("In XmlProcessor() constructor");
- this.originalXml = originalXml;
- try {
- DocumentBuilderFactory documentBuilderFactory = XMLUtility.getInstance().buildDocumentBuilderFactory();
- docBuilder = documentBuilderFactory.newDocumentBuilder();
- InputSource oldXmlstream = new InputSource(new StringReader(originalXml));
- originalDoc = docBuilder.parse(oldXmlstream);
- log.debug("Document Object created successfully for the XML String");
- } catch (Exception e) {
- log.error("Exception thrown on XmlProcessor() constructor",e);
- caughtExceptions(e);
- }
-
+ }
+
+ /**
+ * Instantiates a new xml processor for HQMFMeasureXml.
+ *
+ * @param file the file
+ */
+ public XmlProcessor(File file) {
+ try {
+ DocumentBuilderFactory documentBuilderFactory =
+ XMLUtility.getInstance().buildDocumentBuilderFactory();
+ docBuilder = documentBuilderFactory.newDocumentBuilder();
+ originalDoc = docBuilder.parse(file);
+ log.debug("Document Object created successfully for the XML String");
+ } catch (ParserConfigurationException e) {
+ log.error("Exception thrown on XmlProcessor() constructor", e);
+ } catch (SAXException e) {
+ log.error("Exception thrown on XmlProcessor() constructor", e);
+ } catch (IOException e) {
+ log.debug("Exception thrown on XmlProcessor() constructor", e);
+ caughtExceptions(e);
}
-
- /**
- * Instantiates a new xml processor for HQMFMeasureXml.
- *
- * @param file the file
- */
- public XmlProcessor(File file) {
- try {
- DocumentBuilderFactory documentBuilderFactory = XMLUtility.getInstance().buildDocumentBuilderFactory();
- docBuilder = documentBuilderFactory.newDocumentBuilder();
- originalDoc = docBuilder.parse(file);
- log.debug("Document Object created successfully for the XML String");
- } catch (ParserConfigurationException e) {
- log.error("Exception thrown on XmlProcessor() constructor", e);
- } catch (SAXException e) {
- log.error("Exception thrown on XmlProcessor() constructor", e);
- } catch (IOException e) {
- log.debug("Exception thrown on XmlProcessor() constructor", e);
- caughtExceptions(e);
+ }
+
+ /**
+ * Method to insert new Node under existing parent Node.
+ *
+ * @param newElement the new element
+ * @param nodeName the node name
+ * @param parentNode the parent node
+ * @return the string
+ * @throws SAXException the sAX exception
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ public String appendNode(String newElement, String nodeName, String parentNode)
+ throws SAXException, IOException {
+ log.debug("In appendNode method with newElement ::: ");
+ if ((originalDoc == null) || (newElement == null)) {
+ return "";
+ }
+ try {
+ Node parentTypeNode = findNode(originalDoc, parentNode);
+ if (parentTypeNode != null) {
+ InputSource newXmlstream = new InputSource(new StringReader(newElement));
+ // Parse the NewXml which should be replaced.
+ Document newDoc = docBuilder.parse(newXmlstream);
+ NodeList newNodeList = newDoc.getElementsByTagName(nodeName);
+ for (int i = 0; i < newNodeList.getLength(); i++) {
+ Node newNode = newNodeList.item(i);
+ parentTypeNode.appendChild(originalDoc.importNode(newNode, true));
}
+ log.debug("Document Object created successfully for the XML String.");
+ } else {
+ log.debug(
+ "parentNode:" + parentNode + " not found. method appendNode exiting prematurely.");
+ }
+ } catch (XPathExpressionException e) {
+ log.debug("Exception thrown on appendNode method");
+ caughtExceptions(e);
}
-
- /**
- * Method to insert new Node under existing parent Node.
- *
- * @param newElement the new element
- * @param nodeName the node name
- * @param parentNode the parent node
- * @return the string
- * @throws SAXException the sAX exception
- * @throws IOException Signals that an I/O exception has occurred.
- */
- public String appendNode(String newElement, String nodeName,
- String parentNode) throws SAXException, IOException {
- log.debug("In appendNode method with newElement ::: ");
- if ((originalDoc == null) || (newElement == null)) {
- return "";
- }
- try {
- Node parentTypeNode = findNode(originalDoc, parentNode);
- if (parentTypeNode != null) {
- InputSource newXmlstream = new InputSource(new StringReader(
- newElement));
- // Parse the NewXml which should be replaced.
- Document newDoc = docBuilder.parse(newXmlstream);
- NodeList newNodeList = newDoc.getElementsByTagName(nodeName);
- for (int i = 0; i < newNodeList.getLength(); i++) {
- Node newNode = newNodeList.item(i);
- parentTypeNode.appendChild(originalDoc.importNode(newNode,
- true));
- }
-
- log.debug("Document Object created successfully for the XML String.");
- } else {
- log.debug("parentNode:" + parentNode
- + " not found. method appendNode exiting prematurely.");
+ return transform(originalDoc);
+ }
+
+ /**
+ * Method with Replace/Insert Node into the Original Xml ------- REPLACE ----- Example NewXml -
+ * new text OldXml - old Text Result - new
+ * text ------- INSERT ------ Example NewXml - new text OldXml -
+ * first Result - firstnew text.
+ *
+ * @param newXml the new xml
+ * @param nodeName the node name
+ * @param parentName // this is optional, can be null or empty. if parentName not null, the
+ * oldNode to be replaced will be retrieved based on the parent Node, this is done to make
+ * sure we are replacing the correct node.
+ * @return the string
+ */
+ public String replaceNode(String newXml, String nodeName, String parentName) {
+ try {
+ log.debug("In replaceNode() method");
+ InputSource newXmlstream = new InputSource(new StringReader(newXml));
+ Document newDoc = docBuilder.parse(newXmlstream); // Parse the NewXml
+ // which should
+ // be replaced
+ Node newNode = null;
+ Node oldNode = null;
+ NodeList newNodeList = newDoc.getElementsByTagName(nodeName);
+ NodeList oldNodeList = originalDoc.getElementsByTagName(nodeName);
+ if (oldNodeList.getLength() > 0) {
+ if (StringUtils.isBlank(parentName)) {
+ oldNode = oldNodeList.item(0);
+ } else {
+ for (int i = 0; i < oldNodeList.getLength(); i++) {
+ if (parentName.equals(
+ oldNodeList.item(i).getParentNode().getNodeName())) { // get the old
+ // node with
+ // the
+ // matching
+ // Parent
+ // Node.
+ oldNode = oldNodeList.item(i);
+ break;
}
- } catch (XPathExpressionException e) {
- log.debug("Exception thrown on appendNode method");
- caughtExceptions(e);
+ }
+ }
+ }
+ if (newNodeList.getLength() > 0) {
+ newNode = newNodeList.item(0);
+ for (int i = 0; i < newNodeList.getLength(); i++) {
+ if (parentName.equals(
+ newNodeList.item(i).getParentNode().getNodeName())) { // get the new node used to
+ // replace.
+ newNode = newNodeList.item(i);
+ break;
+ }
+ }
+ if (oldNode != null) { // check if the OriginalXml has the Node
+ // that should be replaced
+ Node nextSibling = oldNode.getNextSibling();
+ Node parentNode = oldNode.getParentNode();
+ parentNode.removeChild(oldNode); // Removing the old child
+ // node
+ if (nextSibling != null) {
+ // to maintain the order insert before the next sibling if exists
+ parentNode.insertBefore(originalDoc.importNode(newNode, true), nextSibling);
+ } else {
+ parentNode.appendChild(
+ originalDoc.importNode(newNode, true)); // insert the new child node to the old
+ // child's Parent node,.
+ }
+ log.debug("Replaced old Child Node with new Child Node " + nodeName);
+ } else { // if the Original Document doesnt have the Node, then
+ // insert the new Node under the first child
+ Node importNode = originalDoc.importNode(newNode, true);
+ originalDoc.getFirstChild().appendChild(importNode);
+ log.debug("Inserted new Child Node" + nodeName);
}
return transform(originalDoc);
- }
+ }
- /**
- * Method with Replace/Insert Node into the Original Xml ------- REPLACE
- * ----- Example NewXml - new text OldXml - old
- * Text Result - new text ------- INSERT
- * ------ Example NewXml - new text OldXml -
- * first Result - firstnew
- * text.
- *
- * @param newXml the new xml
- * @param nodeName the node name
- * @param parentName // this is optional, can be null or empty. if parentName not
- * null, the oldNode to be replaced will be retrieved based on
- * the parent Node, this is done to make sure we are replacing
- * the correct node.
- * @return the string
- */
- public String replaceNode(String newXml, String nodeName, String parentName) {
- try {
- log.debug("In replaceNode() method");
- InputSource newXmlstream = new InputSource(new StringReader(newXml));
- Document newDoc = docBuilder.parse(newXmlstream); // Parse the NewXml
- // which should
- // be replaced
- Node newNode = null;
- Node oldNode = null;
- NodeList newNodeList = newDoc.getElementsByTagName(nodeName);
- NodeList oldNodeList = originalDoc.getElementsByTagName(nodeName);
- if (oldNodeList.getLength() > 0) {
- if (StringUtils.isBlank(parentName)) {
- oldNode = oldNodeList.item(0);
- } else {
- for (int i = 0; i < oldNodeList.getLength(); i++) {
- if (parentName.equals(oldNodeList.item(i)
- .getParentNode().getNodeName())) { // get the old
- // node with
- // the
- // matching
- // Parent
- // Node.
- oldNode = oldNodeList.item(i);
- break;
- }
- }
- }
- }
- if (newNodeList.getLength() > 0) {
- newNode = newNodeList.item(0);
- for (int i = 0; i < newNodeList.getLength(); i++) {
- if (parentName.equals(newNodeList.item(i).getParentNode()
- .getNodeName())) { // get the new node used to
- // replace.
- newNode = newNodeList.item(i);
- break;
- }
- }
- if (oldNode != null) { // check if the OriginalXml has the Node
- // that should be replaced
- Node nextSibling = oldNode.getNextSibling();
- Node parentNode = oldNode.getParentNode();
- parentNode.removeChild(oldNode); // Removing the old child
- // node
- if (nextSibling != null) {
- // to maintain the order insert before the next sibling if exists
- parentNode.insertBefore(
- originalDoc.importNode(newNode, true),
- nextSibling);
- } else {
- parentNode.appendChild(originalDoc.importNode(newNode,
- true)); // insert the new child node to the old
- // child's Parent node,.
- }
- log.debug("Replaced old Child Node with new Child Node "
- + nodeName);
- } else { // if the Original Document doesnt have the Node, then
- // insert the new Node under the first child
- Node importNode = originalDoc.importNode(newNode, true);
- originalDoc.getFirstChild().appendChild(importNode);
- log.debug("Inserted new Child Node" + nodeName);
- }
- return transform(originalDoc);
- }
-
- } catch (Exception e) {
- log.debug("Exception thrown on replaceNode() method", e);
- caughtExceptions(e);
- }
- return originalXml; // not replaced returnig the original Xml;
+ } catch (Exception e) {
+ log.debug("Exception thrown on replaceNode() method", e);
+ caughtExceptions(e);
}
-
- /**
- * Update node text.
- *
- * @param nodeName the node name
- * @param nodeValue the node value
- * @return the string
- */
- public String updateNodeText(String nodeName, String nodeValue) {
- try {
- log.debug("In updateNodeText() method");
- InputSource xmlStream = new InputSource(new StringReader(
- originalXml));
- Document doc = docBuilder.parse(xmlStream);
- doc.getElementsByTagName(nodeName).item(0).setTextContent(nodeValue);
- log.debug("update NoedText");
- return transform(doc);
- } catch (Exception e) {
- log.error("Exception thrown on updateNodeText() method", e);
- caughtExceptions(e);
- }
- return null;
+ return originalXml; // not replaced returnig the original Xml;
+ }
+
+ /**
+ * Update node text.
+ *
+ * @param nodeName the node name
+ * @param nodeValue the node value
+ * @return the string
+ */
+ public String updateNodeText(String nodeName, String nodeValue) {
+ try {
+ log.debug("In updateNodeText() method");
+ InputSource xmlStream = new InputSource(new StringReader(originalXml));
+ Document doc = docBuilder.parse(xmlStream);
+ doc.getElementsByTagName(nodeName).item(0).setTextContent(nodeValue);
+ log.debug("update NoedText");
+ return transform(doc);
+ } catch (Exception e) {
+ log.error("Exception thrown on updateNodeText() method", e);
+ caughtExceptions(e);
}
-
- /**
- * Gets the original xml.
- *
- * @return the original xml
- */
- public String getOriginalXml() {
- return originalXml;
+ return null;
+ }
+
+ /**
+ * Gets the original xml.
+ *
+ * @return the original xml
+ */
+ public String getOriginalXml() {
+ return originalXml;
+ }
+
+ /**
+ * Sets the original xml.
+ *
+ * @param originalXml the new original xml
+ */
+ public void setOriginalXml(String originalXml) {
+ this.originalXml = originalXml;
+ }
+
+ /**
+ * Gets the xml by tag name.
+ *
+ * @param tagName the tag name
+ * @return the xml by tag name
+ */
+ public String getXmlByTagName(String tagName) {
+ String returnVar = null;
+ Node node =
+ originalDoc.getElementsByTagName(tagName).getLength() > 0
+ ? originalDoc.getElementsByTagName(tagName).item(0)
+ : null;
+ if (null != node) {
+ returnVar = transform(node);
}
-
- /**
- * Sets the original xml.
- *
- * @param originalXml the new original xml
- */
- public void setOriginalXml(String originalXml) {
- this.originalXml = originalXml;
+ return returnVar;
+ }
+
+ /**
+ * Adds the parent node.
+ *
+ * @param parentTagName the parent tag name
+ */
+ public void addParentNode(String parentTagName) {
+ if (originalDoc.hasChildNodes()) {
+ Document newDoc = docBuilder.newDocument();
+ Node parentNode = newDoc.appendChild(newDoc.createElement(parentTagName));
+ Node importedNode = newDoc.importNode(originalDoc.getFirstChild(), true);
+ parentNode.appendChild(importedNode);
+ originalDoc = newDoc;
}
-
- /**
- * Gets the xml by tag name.
- *
- * @param tagName the tag name
- * @return the xml by tag name
- */
- public String getXmlByTagName(String tagName) {
- String returnVar = null;
- Node node = originalDoc.getElementsByTagName(tagName).getLength() > 0 ? originalDoc
- .getElementsByTagName(tagName).item(0) : null;
- if (null != node) {
- returnVar = transform(node);
- }
- return returnVar;
+ }
+
+ /**
+ * Caught exceptions.
+ *
+ * @param excp the exception that was caught
+ */
+ private void caughtExceptions(Exception excp) {
+ if (excp instanceof ParserConfigurationException) {
+ log.error("Document Builder Object creation failed:" + excp.getMessage(), excp);
+ } else if (excp instanceof SAXException) {
+ log.error("Xml parsing failed:" + excp.getMessage(), excp);
+ } else if (excp instanceof IOException) {
+ log.error("Conversion of String XML to InputSource failed" + excp.getMessage(), excp);
+ } else {
+ log.error("Generic Exception: " + excp.getMessage(), excp);
}
-
- /**
- * Adds the parent node.
- *
- * @param parentTagName the parent tag name
- */
- public void addParentNode(String parentTagName) {
- if (originalDoc.hasChildNodes()) {
- Document newDoc = docBuilder.newDocument();
- Node parentNode = newDoc.appendChild(newDoc
- .createElement(parentTagName));
- Node importedNode = newDoc.importNode(originalDoc.getFirstChild(),
- true);
- parentNode.appendChild(importedNode);
- originalDoc = newDoc;
- }
+ }
+
+ /**
+ * Check for scoring type.
+ *
+ * @return the string
+ */
+ public String checkForScoringType(String scoringType) {
+ if (originalDoc == null) {
+ return "";
}
-
- /**
- * Caught exceptions.
- *
- * @param excp the exception that was caught
- */
- private void caughtExceptions(Exception excp) {
- if (excp instanceof ParserConfigurationException) {
- log.error("Document Builder Object creation failed:" + excp.getMessage(), excp);
- } else if (excp instanceof SAXException) {
- log.error("Xml parsing failed:" + excp.getMessage(), excp);
- } else if (excp instanceof IOException) {
- log.error("Conversion of String XML to InputSource failed" + excp.getMessage(), excp);
- } else {
- log.error("Generic Exception: " + excp.getMessage(), excp);
- }
+ try {
+ removeNodesBasedOnScoring(scoringType);
+ createNewNodesBasedOnScoring(scoringType);
+ } catch (XPathExpressionException e) {
+ log.error(e.getMessage(), e);
}
-
- /**
- * Check for scoring type.
- *
- * @return the string
- */
- public String checkForScoringType(String scoringType) {
- if (originalDoc == null) {
- return "";
- }
- try {
- removeNodesBasedOnScoring(scoringType);
- createNewNodesBasedOnScoring(scoringType);
- } catch (XPathExpressionException e) {
- log.error(e.getMessage(), e);
- }
- return transform(originalDoc);
+ return transform(originalDoc);
+ }
+
+ /**
+ * This method looks at the Scoring Type for a measure and removes nodes based on the value of
+ * Scoring Type.
+ *
+ * @param scoringType the scoring type
+ * @throws XPathExpressionException the x path expression exception
+ */
+ public void removeNodesBasedOnScoring(String scoringType) throws XPathExpressionException {
+ List xPathList = new ArrayList();
+
+ if (RATIO.equalsIgnoreCase(scoringType)) {
+ // Denominator Exceptions, Measure Populations
+ xPathList.add(XPATH_DENOMINATOR_EXCEPTIONS);
+ xPathList.add(XPATH_MEASURE_POPULATIONS);
+ xPathList.add(XPATH_MEASURE_POPULATION_EXCLUSIONS);
+ } else if (PROPORTION.equalsIgnoreCase(scoringType)) {
+ // Measure Population Exlusions, Measure Populations
+ xPathList.add(XPATH_MEASURE_POPULATIONS);
+ xPathList.add(XPATH_MEASURE_POPULATION_EXCLUSIONS);
+ xPathList.add(XPATH_MEASURE_OBSERVATIONS);
+ } else if (CONTINUOUS_VARIABLE.equalsIgnoreCase(scoringType)) {
+ // Numerators,Numerator Exclusions, Denominators, Denominator
+ // Exceptions, Denominator Exclusions
+ xPathList.add(XPATH_NUMERATORS);
+ xPathList.add(XPATH_NUMERATOR_EXCLUSIONS);
+ xPathList.add(XPATH_DENOMINATOR);
+ xPathList.add(XPATH_DENOMINATOR_EXCEPTIONS);
+ xPathList.add(XPATH_DENOMINATOR_EXCLUSIONS);
+ } else if (COHORT.equalsIgnoreCase(scoringType)) {
+ xPathList.add(XPATH_NUMERATORS);
+ xPathList.add(XPATH_NUMERATOR_EXCLUSIONS);
+ xPathList.add(XPATH_DENOMINATOR);
+ xPathList.add(XPATH_DENOMINATOR_EXCEPTIONS);
+ xPathList.add(XPATH_DENOMINATOR_EXCLUSIONS);
+ xPathList.add(XPATH_MEASURE_POPULATIONS);
+ xPathList.add(XPATH_MEASURE_POPULATION_EXCLUSIONS);
+ xPathList.add(XPATH_MEASURE_OBSERVATIONS);
}
-
- /**
- * This method looks at the Scoring Type for a measure and removes nodes
- * based on the value of Scoring Type.
- *
- * @param scoringType the scoring type
- * @throws XPathExpressionException the x path expression exception
- */
- public void removeNodesBasedOnScoring(String scoringType) throws XPathExpressionException {
- List xPathList = new ArrayList();
-
- if (RATIO.equalsIgnoreCase(scoringType)) {
- // Denominator Exceptions, Measure Populations
- xPathList.add(XPATH_DENOMINATOR_EXCEPTIONS);
- xPathList.add(XPATH_MEASURE_POPULATIONS);
- xPathList.add(XPATH_MEASURE_POPULATION_EXCLUSIONS);
- } else if (PROPORTION.equalsIgnoreCase(scoringType)) {
- // Measure Population Exlusions, Measure Populations
- xPathList.add(XPATH_MEASURE_POPULATIONS);
- xPathList.add(XPATH_MEASURE_POPULATION_EXCLUSIONS);
- xPathList.add(XPATH_MEASURE_OBSERVATIONS);
- } else if (CONTINUOUS_VARIABLE.equalsIgnoreCase(scoringType)) {
- // Numerators,Numerator Exclusions, Denominators, Denominator
- // Exceptions, Denominator Exclusions
- xPathList.add(XPATH_NUMERATORS);
- xPathList.add(XPATH_NUMERATOR_EXCLUSIONS);
- xPathList.add(XPATH_DENOMINATOR);
- xPathList.add(XPATH_DENOMINATOR_EXCEPTIONS);
- xPathList.add(XPATH_DENOMINATOR_EXCLUSIONS);
- } else if (COHORT.equalsIgnoreCase(scoringType)) {
- xPathList.add(XPATH_NUMERATORS);
- xPathList.add(XPATH_NUMERATOR_EXCLUSIONS);
- xPathList.add(XPATH_DENOMINATOR);
- xPathList.add(XPATH_DENOMINATOR_EXCEPTIONS);
- xPathList.add(XPATH_DENOMINATOR_EXCLUSIONS);
- xPathList.add(XPATH_MEASURE_POPULATIONS);
- xPathList.add(XPATH_MEASURE_POPULATION_EXCLUSIONS);
- xPathList.add(XPATH_MEASURE_OBSERVATIONS);
- }
- for (String xPathString : xPathList) {
- Node node = findNode(originalDoc, xPathString);
- removeFromParent(node);
- }
+ for (String xPathString : xPathList) {
+ Node node = findNode(originalDoc, xPathString);
+ removeFromParent(node);
}
-
- /**
- * Rename ip p_ to_ ip.
- *
- * @param document the document
- * @throws XPathExpressionException the x path expression exception
- */
- public void renameIPPToIP(Document document) throws XPathExpressionException {
- String clause = "clause";
- String initialPopulation = "initialPopulation";
- String initialPatientPopulation = "initialPatientPopulation";
- String xpathOldInitPatientPop = "/measure/populations/initialPatientPopulations";
- String xpathOldGroupingPackageClause = "/measure/measureGrouping/*/packageClause";
-
- if (document == null) {
- return;
- }
-
- //Find and Replace IPP to IP in measureGrouping/group/packageClause.
- javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
- NodeList nodesPackageClauses = (NodeList) xPath.evaluate(xpathOldGroupingPackageClause,
- originalDoc.getDocumentElement(), XPathConstants.NODESET);
-
- for (int i = 0; i < nodesPackageClauses.getLength(); i++) {
- Node childNode = nodesPackageClauses.item(i);
- String packageClauseType = childNode.getAttributes().getNamedItem(TYPE).getNodeValue();
- String packageClauseName = childNode.getAttributes().getNamedItem("name").getNodeValue();
- if (packageClauseType.equalsIgnoreCase(initialPatientPopulation)) {
- childNode.getAttributes().getNamedItem(TYPE).setNodeValue(initialPopulation);
- if (packageClauseName.indexOf(PATIENT) > 0) {
- packageClauseName = packageClauseName.replaceAll(PATIENT, " ");
- }
- childNode.getAttributes().getNamedItem("name").setNodeValue(packageClauseName);
- }
- }
-
- //find initialPatientPopulations tag
- Node initialPopulationsNode = findNode(document, xpathOldInitPatientPop);
- if (initialPopulationsNode == null) {
- return;
- }
-
- //Also change the value of the 'displayName' attribute
- initialPopulationsNode.getAttributes().getNamedItem(DISPLAY_NAME).setNodeValue("Initial Populations");
-
- //within 'initialPopulations' tag, for all 'clause' tags, rename the 'displayName' attribute
- //from 'Initial Patient Population 1' to 'Initial Population 1'.
- //Also change 'type' attribute to 'initialPopulation'
- NodeList childNodes = initialPopulationsNode.getChildNodes();
- for (int i = 0; i < childNodes.getLength(); i++) {
- Node childNode = childNodes.item(i);
- if (clause.equals(childNode.getNodeName())) {
- childNode.getAttributes().getNamedItem(TYPE).setNodeValue(initialPopulation);
-
- String clauseDisplayName = childNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- if (clauseDisplayName.indexOf(PATIENT) > 0) {
- clauseDisplayName = clauseDisplayName.replaceAll(PATIENT, " ");
- }
- childNode.getAttributes().getNamedItem(DISPLAY_NAME).setNodeValue(clauseDisplayName);
- }
- }
-
- //rename 'initialPatientPopulations' to 'initialPopulations'.
- document.renameNode(initialPopulationsNode, "", INITIAL_POPULATIONS);
+ }
+
+ /**
+ * Rename ip p_ to_ ip.
+ *
+ * @param document the document
+ * @throws XPathExpressionException the x path expression exception
+ */
+ public void renameIPPToIP(Document document) throws XPathExpressionException {
+ String clause = "clause";
+ String initialPopulation = "initialPopulation";
+ String initialPatientPopulation = "initialPatientPopulation";
+ String xpathOldInitPatientPop = "/measure/populations/initialPatientPopulations";
+ String xpathOldGroupingPackageClause = "/measure/measureGrouping/*/packageClause";
+
+ if (document == null) {
+ return;
}
- /**
- * Rename timing conventions.
- *
- * @param document the document
- * @throws XPathExpressionException the x path expression exception
- */
- public void renameTimingConventions(Document document) throws XPathExpressionException {
- String startsBeforeOrDuring = "Starts Before Or During";
- String endsBeforeOrDuring = "Ends Before Or During";
- String startBeforeEnd = "Starts Before End";
- String endsBeforeEnd = "Ends Before End";
- String sBE = "SBE";
- String eBE = "EBE";
- javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
- //replace relationalOp attribute values for displayName and type from SBOD to SBE
- NodeList nodesRelationalOpsSBOD = (NodeList) xPath.evaluate(XPATH_OLD_ALL_RELATIONALOP_SBOD,
- originalDoc.getDocumentElement(), XPathConstants.NODESET);
- for (int i = 0; i < nodesRelationalOpsSBOD.getLength(); i++) {
- Node childNode = nodesRelationalOpsSBOD.item(i);
- String relationalOpDisplayName = childNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- relationalOpDisplayName = relationalOpDisplayName.replace(startsBeforeOrDuring, startBeforeEnd);
- childNode.getAttributes().getNamedItem(DISPLAY_NAME).setNodeValue(relationalOpDisplayName);
- childNode.getAttributes().getNamedItem(TYPE).setNodeValue(sBE);
- }
- //replace relationalOp attribute values for displayName and type from EBOD to EBE
- NodeList nodesRelationalOpsEBOD = (NodeList) xPath.evaluate(XPATH_OLD_ALL_RELATIONALOP_EBOD,
- originalDoc.getDocumentElement(), XPathConstants.NODESET);
- for (int i = 0; i < nodesRelationalOpsEBOD.getLength(); i++) {
- Node childNode = nodesRelationalOpsEBOD.item(i);
- String relationalOpDisplayName = childNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- relationalOpDisplayName = relationalOpDisplayName.replace(endsBeforeOrDuring, endsBeforeEnd);
- childNode.getAttributes().getNamedItem(DISPLAY_NAME).setNodeValue(relationalOpDisplayName);
- childNode.getAttributes().getNamedItem(TYPE).setNodeValue(eBE);
+ // Find and Replace IPP to IP in measureGrouping/group/packageClause.
+ javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
+ NodeList nodesPackageClauses =
+ (NodeList)
+ xPath.evaluate(
+ xpathOldGroupingPackageClause,
+ originalDoc.getDocumentElement(),
+ XPathConstants.NODESET);
+
+ for (int i = 0; i < nodesPackageClauses.getLength(); i++) {
+ Node childNode = nodesPackageClauses.item(i);
+ String packageClauseType = childNode.getAttributes().getNamedItem(TYPE).getNodeValue();
+ String packageClauseName = childNode.getAttributes().getNamedItem("name").getNodeValue();
+ if (packageClauseType.equalsIgnoreCase(initialPatientPopulation)) {
+ childNode.getAttributes().getNamedItem(TYPE).setNodeValue(initialPopulation);
+ if (packageClauseName.indexOf(PATIENT) > 0) {
+ packageClauseName = packageClauseName.replaceAll(PATIENT, " ");
}
+ childNode.getAttributes().getNamedItem("name").setNodeValue(packageClauseName);
+ }
}
-
- /**
- * This method looks at the Scoring Type for a measure and adds nodes based
- * on the value of Scoring Type.
- *
- * @param scoringType the scoring type
- * @throws XPathExpressionException the x path expression exception
- */
- public void createNewNodesBasedOnScoring(String scoringType)
- throws XPathExpressionException {
- List scoreBasedNodes = retrieveScoreBasedNodes(scoringType);
- Node populationsNode = findNode(originalDoc, XPATH_POPULATIONS);
-
- if (populationsNode == null) {
- populationsNode = addPopulationsNode();
- }
- boolean childAppended = calculateChildAppend(scoreBasedNodes,
- populationsNode);
- /**
- * Add Measure Observations node after Populations node if not present
- * and scoring type is Continuous Variable.
- */
- Node measureObservationsNode = findNode(originalDoc, XPATH_MEASURE_OBSERVATIONS);
- if ((CONTINUOUS_VARIABLE.equalsIgnoreCase(scoringType) || RATIO.equalsIgnoreCase(scoringType))
- && (measureObservationsNode == null)) {
- // Create a new measureObservations element.
- String nodeName = MEASURE_OBSERVATION;
- String displayName = constantsMap.get(nodeName);
- Element mainChildElem = createTemplateNode(nodeName,
- displayName);
- measureObservationsNode = mainChildElem;
- // insert measureObservations element after populations element
- Node measureNode = populationsNode.getParentNode();
- Element measureElement = (Element) measureNode;
- measureElement.insertBefore(mainChildElem,
- populationsNode.getNextSibling());
- }
- // Create stratifications node
- Node measureStratificationsNode = findNode(originalDoc,
- XPATH_MEASURE_STRATIFICATIONS);
- if (measureStratificationsNode == null && !RATIO.equalsIgnoreCase(scoringType)) {
- String stratificationsNodeName = "strata";
- String clauseDisplayName = "Stratum";
- Element stratificationElement = createTemplateNode(
- stratificationsNodeName, clauseDisplayName);
-
- NodeList childs = stratificationElement.getChildNodes();
- Element stratificationEle = originalDoc
- .createElement(STRATIFICATION);
- stratificationEle.setAttribute(DISPLAY_NAME, STRATIFICATION_DISPLAYNAME);
- stratificationEle.setAttribute(UUID_STRING, UUID.randomUUID().toString());
- stratificationEle.setAttribute(TYPE, STRATIFICATION);
- List nCList = new ArrayList();
- for (int i = 0; i < childs.getLength(); i++) {
- nCList.add(childs.item(i));
- stratificationElement.removeChild(childs.item(i));
- }
- for (Node cNode : nCList) {
- stratificationEle.appendChild(cNode);
- }
- stratificationElement.appendChild(stratificationEle);
-
- measureStratificationsNode = stratificationElement;
- // insert measureObservations element after populations element
- Node measureNode = populationsNode.getParentNode();
- Element measureElement = (Element) measureNode;
- if (measureObservationsNode != null) {
- measureElement.insertBefore(stratificationElement,
- measureObservationsNode.getNextSibling());
- } else {
- measureElement.insertBefore(stratificationElement,
- populationsNode.getNextSibling());
- }
- } else if (measureStratificationsNode != null && RATIO.equalsIgnoreCase(scoringType)) {
- Node measureNode = measureStratificationsNode.getParentNode();
- Element measureElement = (Element) measureNode;
-
- measureElement.removeChild(measureStratificationsNode);
- }
- // Create supplementalDataElements node
- createSupplementalDataElementNode(measureStratificationsNode);
- /*
- * All the adding and removing can put the children of 'populations' in
- * a random order. Arrange the population nodes in correct order.*/
- // If no children have been appended, dont go through the process of
- // re-arranging the
- // populations node children.
- if (!childAppended) {
- return;
- }
- // remove all the child nodes of populations node first
- NodeList childNodes = populationsNode.getChildNodes();
- List childNodesList = new ArrayList();
- for (int c = 0; c < childNodes.getLength(); c++) {
- childNodesList.add(childNodes.item(c));
- }
- for (int i = 0; i < childNodesList.size(); i++) {
- populationsNode
- .removeChild(populationsNode.getChildNodes().item(0));
- }
- arrangeChildNodeList(populationsNode, childNodesList);
-
+ // find initialPatientPopulations tag
+ Node initialPopulationsNode = findNode(document, xpathOldInitPatientPop);
+ if (initialPopulationsNode == null) {
+ return;
}
- /**
- * Take the child nodeList & re-arrange it according to this order
- * "Initial Patient Populations", "Numerators", "Numerator Exclusions",
- * "Denominators", "Denominator Exclusions",
- * "Denominator Exceptions", "Measure Populations", "Measure Population Exclusions".
- *
- * @param populationsNode the population node
- * @param childNodesList array list of nodes to be ordered
- */
- private void arrangeChildNodeList(Node populationsNode,
- List childNodesList) {
- // Take the child nodeList & re-arrange it according to this order
- // "Initial Patient Populations", "Numerators", "Numerator Exclusions",
- // "Denominators", "Denominator Exclusions",
- // "Denominator Exceptions", "Measure Populations", "Measure Population Exclusions"
- for (String populationsChild : XmlProcessor.POPULATIONS) {
- Node populationsChildNode = null;
- for (int j = 0; j < childNodesList.size(); j++) {
- Node child = childNodesList.get(j);
- if (child.getNodeName().equals(populationsChild)) {
- populationsChildNode = child;
- break;
- }
- }
- if (populationsChildNode != null) {
- populationsNode.appendChild(populationsChildNode);
- }
+ // Also change the value of the 'displayName' attribute
+ initialPopulationsNode
+ .getAttributes()
+ .getNamedItem(DISPLAY_NAME)
+ .setNodeValue("Initial Populations");
+
+ // within 'initialPopulations' tag, for all 'clause' tags, rename the 'displayName' attribute
+ // from 'Initial Patient Population 1' to 'Initial Population 1'.
+ // Also change 'type' attribute to 'initialPopulation'
+ NodeList childNodes = initialPopulationsNode.getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ Node childNode = childNodes.item(i);
+ if (clause.equals(childNode.getNodeName())) {
+ childNode.getAttributes().getNamedItem(TYPE).setNodeValue(initialPopulation);
+
+ String clauseDisplayName =
+ childNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ if (clauseDisplayName.indexOf(PATIENT) > 0) {
+ clauseDisplayName = clauseDisplayName.replaceAll(PATIENT, " ");
}
+ childNode.getAttributes().getNamedItem(DISPLAY_NAME).setNodeValue(clauseDisplayName);
+ }
}
- /**
- * Creates the Supplemental Data Element Node.
- *
- * @param measureStratificationsNode stratifications Node for the measure
- * @throws XPathExpressionException the x path expression exception
- */
- private void createSupplementalDataElementNode(Node measureStratificationsNode) throws XPathExpressionException {
- Node supplementaDataElementsElement = findNode(originalDoc,
- XPATH_MEASURE_SD_ELEMENTS);
- if (supplementaDataElementsElement == null) {
- supplementaDataElementsElement = originalDoc
- .createElement("supplementalDataElements");
- ((Element) measureStratificationsNode.getParentNode())
- .insertBefore(supplementaDataElementsElement,
- measureStratificationsNode.getNextSibling());
- }
- // Create elementLookUp node
- if (findNode(originalDoc, XPATH_MEASURE_ELEMENT_LOOKUP) == null) {
- Element elementLookUpElement = originalDoc
- .createElement("elementLookUp");
- ((Element) supplementaDataElementsElement.getParentNode())
- .insertBefore(elementLookUpElement,
- supplementaDataElementsElement.getNextSibling());
- }
- if (findNode(originalDoc, XPATH_MEASURE_SUBTREE_LOOKUP) == null) {
- Element subTreeLookUpElement = originalDoc
- .createElement("subTreeLookUp");
- ((Element) supplementaDataElementsElement.getParentNode())
- .insertBefore(subTreeLookUpElement,
- supplementaDataElementsElement.getNextSibling());
- }
- // create Measure Grouping node
- if (findNode(originalDoc, XPATH_MEASURE_GROUPING) == null) {
- Element measureGroupingElement = originalDoc
- .createElement("measureGrouping");
- ((Element) supplementaDataElementsElement.getParentNode())
- .insertBefore(measureGroupingElement,
- supplementaDataElementsElement.getNextSibling());
- }
-
- Node riskAdjustmentVariablesElement = findNode(originalDoc,
- XPATH_MEASURE_RAV_ELEMENTS);
- if (riskAdjustmentVariablesElement == null) {
- riskAdjustmentVariablesElement = originalDoc
- .createElement("riskAdjustmentVariables");
- ((Element) supplementaDataElementsElement.getParentNode())
- .insertBefore(riskAdjustmentVariablesElement,
- supplementaDataElementsElement.getNextSibling());
- }
-
- log.debug("Original Doc: " + originalDoc.toString());
+ // rename 'initialPatientPopulations' to 'initialPopulations'.
+ document.renameNode(initialPopulationsNode, "", INITIAL_POPULATIONS);
+ }
+
+ /**
+ * Rename timing conventions.
+ *
+ * @param document the document
+ * @throws XPathExpressionException the x path expression exception
+ */
+ public void renameTimingConventions(Document document) throws XPathExpressionException {
+ String startsBeforeOrDuring = "Starts Before Or During";
+ String endsBeforeOrDuring = "Ends Before Or During";
+ String startBeforeEnd = "Starts Before End";
+ String endsBeforeEnd = "Ends Before End";
+ String sBE = "SBE";
+ String eBE = "EBE";
+ javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
+ // replace relationalOp attribute values for displayName and type from SBOD to SBE
+ NodeList nodesRelationalOpsSBOD =
+ (NodeList)
+ xPath.evaluate(
+ XPATH_OLD_ALL_RELATIONALOP_SBOD,
+ originalDoc.getDocumentElement(),
+ XPathConstants.NODESET);
+ for (int i = 0; i < nodesRelationalOpsSBOD.getLength(); i++) {
+ Node childNode = nodesRelationalOpsSBOD.item(i);
+ String relationalOpDisplayName =
+ childNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ relationalOpDisplayName =
+ relationalOpDisplayName.replace(startsBeforeOrDuring, startBeforeEnd);
+ childNode.getAttributes().getNamedItem(DISPLAY_NAME).setNodeValue(relationalOpDisplayName);
+ childNode.getAttributes().getNamedItem(TYPE).setNodeValue(sBE);
}
-
- /**
- * Calculates whether we appended a child node or not.
- *
- * @param scoreBasedNodes the score Base Node
- * @param populationsNode the node for the measures population
- * @return Boolean
- * true: if we appended a child
- * false: if we didn't append a child
- */
- private boolean calculateChildAppend(List scoreBasedNodes,
- Node populationsNode) {
- boolean childAppended = false;
- for (String nodeName : scoreBasedNodes) {
- boolean isNodePresent = false;
- NodeList childNodes = populationsNode.getChildNodes();
- for (int i = 0; i < childNodes.getLength(); i++) {
- Node childNode = childNodes.item(i);
- String childNodeName = childNode.getNodeName();
- if (childNodeName.equals(nodeName)) {
- isNodePresent = true;
- break;
- }
- }
- if (!isNodePresent) {
- String displayName = constantsMap.get(nodeName);
- Element mainChildElem = createTemplateNode(nodeName,
- displayName);
- populationsNode.appendChild(mainChildElem);
- childAppended = true;
- }
- }
- return childAppended;
+ // replace relationalOp attribute values for displayName and type from EBOD to EBE
+ NodeList nodesRelationalOpsEBOD =
+ (NodeList)
+ xPath.evaluate(
+ XPATH_OLD_ALL_RELATIONALOP_EBOD,
+ originalDoc.getDocumentElement(),
+ XPathConstants.NODESET);
+ for (int i = 0; i < nodesRelationalOpsEBOD.getLength(); i++) {
+ Node childNode = nodesRelationalOpsEBOD.item(i);
+ String relationalOpDisplayName =
+ childNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ relationalOpDisplayName = relationalOpDisplayName.replace(endsBeforeOrDuring, endsBeforeEnd);
+ childNode.getAttributes().getNamedItem(DISPLAY_NAME).setNodeValue(relationalOpDisplayName);
+ childNode.getAttributes().getNamedItem(TYPE).setNodeValue(eBE);
}
-
- /**
- * Retrieves the Score Based nodes.
- *
- * @param scoringType the scoring type
- * @return List
- * the score based Nodes
- */
- private List retrieveScoreBasedNodes(String scoringType) {
- List scoreBasedNodes = new ArrayList();
- if (CONTINUOUS_VARIABLE.equalsIgnoreCase(scoringType)) {
- scoreBasedNodes.add(INITIAL_POPULATIONS);
- scoreBasedNodes.add(MEASURE_POPULATIONS);
- scoreBasedNodes.add(MEASURE_POPULATION_EXCLUSIONS);
- } else if (PROPORTION.equalsIgnoreCase(scoringType)) {
- scoreBasedNodes.add(INITIAL_POPULATIONS);
- scoreBasedNodes.add(NUMERATORS);
- scoreBasedNodes.add(NUMERATOR_EXCLUSIONS);
- scoreBasedNodes.add(DENOMINATORS);
- scoreBasedNodes.add(DENOMINATOR_EXCLUSIONS);
- scoreBasedNodes.add(DENOMINATOR_EXCEPTIONS);
- } else if (RATIO.equalsIgnoreCase(scoringType)) {
- scoreBasedNodes.add(INITIAL_POPULATIONS);
- scoreBasedNodes.add(NUMERATORS);
- scoreBasedNodes.add(NUMERATOR_EXCLUSIONS);
- scoreBasedNodes.add(DENOMINATORS);
- scoreBasedNodes.add(DENOMINATOR_EXCLUSIONS);
- } else if (COHORT.equalsIgnoreCase(scoringType)) {
- scoreBasedNodes.add(INITIAL_POPULATIONS);
- }
- return scoreBasedNodes;
+ }
+
+ /**
+ * This method looks at the Scoring Type for a measure and adds nodes based on the value of
+ * Scoring Type.
+ *
+ * @param scoringType the scoring type
+ * @throws XPathExpressionException the x path expression exception
+ */
+ public void createNewNodesBasedOnScoring(String scoringType) throws XPathExpressionException {
+ List scoreBasedNodes = retrieveScoreBasedNodes(scoringType);
+ Node populationsNode = findNode(originalDoc, XPATH_POPULATIONS);
+
+ if (populationsNode == null) {
+ populationsNode = addPopulationsNode();
}
-
+ boolean childAppended = calculateChildAppend(scoreBasedNodes, populationsNode);
/**
- * This method will add a 'populations' node to the XML. It assumes that the
- * 'measureDetails' node is already present in the XML Document and tries to
- * add the 'populations' node after the 'measureDetails' node.
- *
- * @return the node
- * @throws XPathExpressionException the x path expression exception
+ * Add Measure Observations node after Populations node if not present and scoring type is
+ * Continuous Variable.
*/
- private Node addPopulationsNode() throws XPathExpressionException {
- Element populationsElem = originalDoc.createElement("populations");
- populationsElem.setAttribute(DISPLAY_NAME,
- XmlProcessor.constantsMap.get("populations"));
- Node measureNode = findNode(originalDoc,
- "/measure");
- Element measureElement = (Element) measureNode;
- measureElement.insertBefore(populationsElem,
- measureNode.getFirstChild());
- return populationsElem;
+ Node measureObservationsNode = findNode(originalDoc, XPATH_MEASURE_OBSERVATIONS);
+ if ((CONTINUOUS_VARIABLE.equalsIgnoreCase(scoringType) || RATIO.equalsIgnoreCase(scoringType))
+ && (measureObservationsNode == null)) {
+ // Create a new measureObservations element.
+ String nodeName = MEASURE_OBSERVATION;
+ String displayName = constantsMap.get(nodeName);
+ Element mainChildElem = createTemplateNode(nodeName, displayName);
+ measureObservationsNode = mainChildElem;
+ // insert measureObservations element after populations element
+ Node measureNode = populationsNode.getParentNode();
+ Element measureElement = (Element) measureNode;
+ measureElement.insertBefore(mainChildElem, populationsNode.getNextSibling());
}
-
- /**
- * This method creates blank nodes for Elements like 'child elements of
- * populations node, measureObservations node and stratifications node' The
- * method will return the newly created Element. The called needs to add
- * this Element to the appropriate parent node in the Document.
- *
- * @param nodeName the node name
- * @param clauseDisplayName the clause display name
- * @return the element
- */
- private Element createTemplateNode(String nodeName, String clauseDisplayName) {
- Element mainChildElem = originalDoc.createElement(nodeName);
- mainChildElem.setAttribute(DISPLAY_NAME, constantsMap.get(nodeName));
-
- Element clauseChildElem = originalDoc.createElement("clause");
- String dispName = constantsMap.get(clauseDisplayName);
- clauseChildElem.setAttribute(DISPLAY_NAME, dispName + " 1");
- clauseChildElem.setAttribute(TYPE, toCamelCase(dispName));
- clauseChildElem.setAttribute(UUID_STRING, UUID.randomUUID().toString());
- mainChildElem.appendChild(clauseChildElem);
-
- mainChildElem.appendChild(clauseChildElem);
-
- return mainChildElem;
+ // Create stratifications node
+ Node measureStratificationsNode = findNode(originalDoc, XPATH_MEASURE_STRATIFICATIONS);
+ if (measureStratificationsNode == null && !RATIO.equalsIgnoreCase(scoringType)) {
+ String stratificationsNodeName = "strata";
+ String clauseDisplayName = "Stratum";
+ Element stratificationElement =
+ createTemplateNode(stratificationsNodeName, clauseDisplayName);
+
+ NodeList childs = stratificationElement.getChildNodes();
+ Element stratificationEle = originalDoc.createElement(STRATIFICATION);
+ stratificationEle.setAttribute(DISPLAY_NAME, STRATIFICATION_DISPLAYNAME);
+ stratificationEle.setAttribute(UUID_STRING, UUID.randomUUID().toString());
+ stratificationEle.setAttribute(TYPE, STRATIFICATION);
+ List nCList = new ArrayList();
+ for (int i = 0; i < childs.getLength(); i++) {
+ nCList.add(childs.item(i));
+ stratificationElement.removeChild(childs.item(i));
+ }
+ for (Node cNode : nCList) {
+ stratificationEle.appendChild(cNode);
+ }
+ stratificationElement.appendChild(stratificationEle);
+
+ measureStratificationsNode = stratificationElement;
+ // insert measureObservations element after populations element
+ Node measureNode = populationsNode.getParentNode();
+ Element measureElement = (Element) measureNode;
+ if (measureObservationsNode != null) {
+ measureElement.insertBefore(
+ stratificationElement, measureObservationsNode.getNextSibling());
+ } else {
+ measureElement.insertBefore(stratificationElement, populationsNode.getNextSibling());
+ }
+ } else if (measureStratificationsNode != null && RATIO.equalsIgnoreCase(scoringType)) {
+ Node measureNode = measureStratificationsNode.getParentNode();
+ Element measureElement = (Element) measureNode;
+
+ measureElement.removeChild(measureStratificationsNode);
}
-
- /**
- * Removes the from parent.
- *
- * @param node the node
- */
- public void removeFromParent(Node node) {
- if (node != null) {
- Node parentNode = node.getParentNode();
- parentNode.removeChild(node);
+ // Create supplementalDataElements node
+ createSupplementalDataElementNode(measureStratificationsNode);
+ /*
+ * All the adding and removing can put the children of 'populations' in
+ * a random order. Arrange the population nodes in correct order.*/
+ // If no children have been appended, dont go through the process of
+ // re-arranging the
+ // populations node children.
+ if (!childAppended) {
+ return;
+ }
+ // remove all the child nodes of populations node first
+ NodeList childNodes = populationsNode.getChildNodes();
+ List childNodesList = new ArrayList();
+ for (int c = 0; c < childNodes.getLength(); c++) {
+ childNodesList.add(childNodes.item(c));
+ }
+ for (int i = 0; i < childNodesList.size(); i++) {
+ populationsNode.removeChild(populationsNode.getChildNodes().item(0));
+ }
+ arrangeChildNodeList(populationsNode, childNodesList);
+ }
+
+ /**
+ * Take the child nodeList & re-arrange it according to this order "Initial Patient Populations",
+ * "Numerators", "Numerator Exclusions", "Denominators", "Denominator Exclusions", "Denominator
+ * Exceptions", "Measure Populations", "Measure Population Exclusions".
+ *
+ * @param populationsNode the population node
+ * @param childNodesList array list of nodes to be ordered
+ */
+ private void arrangeChildNodeList(Node populationsNode, List childNodesList) {
+ // Take the child nodeList & re-arrange it according to this order
+ // "Initial Patient Populations", "Numerators", "Numerator Exclusions",
+ // "Denominators", "Denominator Exclusions",
+ // "Denominator Exceptions", "Measure Populations", "Measure Population Exclusions"
+ for (String populationsChild : XmlProcessor.POPULATIONS) {
+ Node populationsChildNode = null;
+ for (int j = 0; j < childNodesList.size(); j++) {
+ Node child = childNodesList.get(j);
+ if (child.getNodeName().equals(populationsChild)) {
+ populationsChildNode = child;
+ break;
}
+ }
+ if (populationsChildNode != null) {
+ populationsNode.appendChild(populationsChildNode);
+ }
}
-
- /**
- * Find node.
- *
- * @param document the document
- * @param xPathString the x path string
- * @return the node
- * @throws XPathExpressionException the x path expression exception
- */
- public Node findNode(Document document, String xPathString) throws XPathExpressionException {
- javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
- Node node = (Node) xPath.evaluate(xPathString, document.getDocumentElement(), XPathConstants.NODE);
- return node;
+ }
+
+ /**
+ * Creates the Supplemental Data Element Node.
+ *
+ * @param measureStratificationsNode stratifications Node for the measure
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void createSupplementalDataElementNode(Node measureStratificationsNode)
+ throws XPathExpressionException {
+ Node supplementaDataElementsElement = findNode(originalDoc, XPATH_MEASURE_SD_ELEMENTS);
+ if (supplementaDataElementsElement == null) {
+ supplementaDataElementsElement = originalDoc.createElement("supplementalDataElements");
+ ((Element) measureStratificationsNode.getParentNode())
+ .insertBefore(
+ supplementaDataElementsElement, measureStratificationsNode.getNextSibling());
}
-
- /**
- * Find node list.
- *
- * @param document the document
- * @param xPathString the x path string
- * @return the node list
- * @throws XPathExpressionException the x path expression exception
- */
- public NodeList findNodeList(Document document, String xPathString) throws XPathExpressionException {
- javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
- XPathExpression expr = xPath.compile(xPathString);
- return (NodeList) expr.evaluate(document, XPathConstants.NODESET);
+ // Create elementLookUp node
+ if (findNode(originalDoc, XPATH_MEASURE_ELEMENT_LOOKUP) == null) {
+ Element elementLookUpElement = originalDoc.createElement("elementLookUp");
+ ((Element) supplementaDataElementsElement.getParentNode())
+ .insertBefore(elementLookUpElement, supplementaDataElementsElement.getNextSibling());
}
-
- /**
- * Gets the node count.
- *
- * @param document the document
- * @param xPathString the x path string
- * @return the node count
- * @throws XPathExpressionException the x path expression exception
- */
- public int getNodeCount(Document document, String xPathString) throws XPathExpressionException {
- javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
- XPathExpression expr = xPath.compile(xPathString);
- return ((Double) expr.evaluate(document, XPathConstants.NUMBER)).intValue();
+ if (findNode(originalDoc, XPATH_MEASURE_SUBTREE_LOOKUP) == null) {
+ Element subTreeLookUpElement = originalDoc.createElement("subTreeLookUp");
+ ((Element) supplementaDataElementsElement.getParentNode())
+ .insertBefore(subTreeLookUpElement, supplementaDataElementsElement.getNextSibling());
}
-
- /**
- * Gets the original doc.
- *
- * @return the originalDoc
- */
- public Document getOriginalDoc() {
- return originalDoc;
+ // create Measure Grouping node
+ if (findNode(originalDoc, XPATH_MEASURE_GROUPING) == null) {
+ Element measureGroupingElement = originalDoc.createElement("measureGrouping");
+ ((Element) supplementaDataElementsElement.getParentNode())
+ .insertBefore(measureGroupingElement, supplementaDataElementsElement.getNextSibling());
}
- /**
- * Sets the original doc.
- *
- * @param originalDoc the originalDoc to set
- */
- public void setOriginalDoc(Document originalDoc) {
- this.originalDoc = originalDoc;
+ Node riskAdjustmentVariablesElement = findNode(originalDoc, XPATH_MEASURE_RAV_ELEMENTS);
+ if (riskAdjustmentVariablesElement == null) {
+ riskAdjustmentVariablesElement = originalDoc.createElement("riskAdjustmentVariables");
+ ((Element) supplementaDataElementsElement.getParentNode())
+ .insertBefore(
+ riskAdjustmentVariablesElement, supplementaDataElementsElement.getNextSibling());
}
- /**
- * To camel case.
- *
- * @param name the name
- * @return the string
- */
- private static String toCamelCase(String name) {
- String nameNew = name.toLowerCase(Locale.US);
- String[] parts = nameNew.split(" ");
- StringBuffer camelCaseString = new StringBuffer(parts[0].substring(0, 1).toLowerCase()
- + parts[0].substring(1));
- for (int i = 1; i < parts.length; i++) {
- camelCaseString.append(toProperCase(parts[i]));
+ log.debug("Original Doc: " + originalDoc.toString());
+ }
+
+ /**
+ * Calculates whether we appended a child node or not.
+ *
+ * @param scoreBasedNodes the score Base Node
+ * @param populationsNode the node for the measures population
+ * @return Boolean true: if we appended a child false: if we didn't append a child
+ */
+ private boolean calculateChildAppend(List scoreBasedNodes, Node populationsNode) {
+ boolean childAppended = false;
+ for (String nodeName : scoreBasedNodes) {
+ boolean isNodePresent = false;
+ NodeList childNodes = populationsNode.getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ Node childNode = childNodes.item(i);
+ String childNodeName = childNode.getNodeName();
+ if (childNodeName.equals(nodeName)) {
+ isNodePresent = true;
+ break;
}
- return camelCaseString.toString();
+ }
+ if (!isNodePresent) {
+ String displayName = constantsMap.get(nodeName);
+ Element mainChildElem = createTemplateNode(nodeName, displayName);
+ populationsNode.appendChild(mainChildElem);
+ childAppended = true;
+ }
}
-
- /**
- * To proper case.
- *
- * @param str the s
- * @return the string
- */
- private static String toProperCase(String str) {
- return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
+ return childAppended;
+ }
+
+ /**
+ * Retrieves the Score Based nodes.
+ *
+ * @param scoringType the scoring type
+ * @return List the score based Nodes
+ */
+ private List retrieveScoreBasedNodes(String scoringType) {
+ List scoreBasedNodes = new ArrayList();
+ if (CONTINUOUS_VARIABLE.equalsIgnoreCase(scoringType)) {
+ scoreBasedNodes.add(INITIAL_POPULATIONS);
+ scoreBasedNodes.add(MEASURE_POPULATIONS);
+ scoreBasedNodes.add(MEASURE_POPULATION_EXCLUSIONS);
+ } else if (PROPORTION.equalsIgnoreCase(scoringType)) {
+ scoreBasedNodes.add(INITIAL_POPULATIONS);
+ scoreBasedNodes.add(NUMERATORS);
+ scoreBasedNodes.add(NUMERATOR_EXCLUSIONS);
+ scoreBasedNodes.add(DENOMINATORS);
+ scoreBasedNodes.add(DENOMINATOR_EXCLUSIONS);
+ scoreBasedNodes.add(DENOMINATOR_EXCEPTIONS);
+ } else if (RATIO.equalsIgnoreCase(scoringType)) {
+ scoreBasedNodes.add(INITIAL_POPULATIONS);
+ scoreBasedNodes.add(NUMERATORS);
+ scoreBasedNodes.add(NUMERATOR_EXCLUSIONS);
+ scoreBasedNodes.add(DENOMINATORS);
+ scoreBasedNodes.add(DENOMINATOR_EXCLUSIONS);
+ } else if (COHORT.equalsIgnoreCase(scoringType)) {
+ scoreBasedNodes.add(INITIAL_POPULATIONS);
}
-
- /**
- * Transform.
- *
- * @param node the node
- * @return the string
- */
- public String transform(Node node) {
- return transform(node, false);
+ return scoreBasedNodes;
+ }
+
+ /**
+ * This method will add a 'populations' node to the XML. It assumes that the 'measureDetails' node
+ * is already present in the XML Document and tries to add the 'populations' node after the
+ * 'measureDetails' node.
+ *
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node addPopulationsNode() throws XPathExpressionException {
+ Element populationsElem = originalDoc.createElement("populations");
+ populationsElem.setAttribute(DISPLAY_NAME, XmlProcessor.constantsMap.get("populations"));
+ Node measureNode = findNode(originalDoc, "/measure");
+ Element measureElement = (Element) measureNode;
+ measureElement.insertBefore(populationsElem, measureNode.getFirstChild());
+ return populationsElem;
+ }
+
+ /**
+ * This method creates blank nodes for Elements like 'child elements of populations node,
+ * measureObservations node and stratifications node' The method will return the newly created
+ * Element. The called needs to add this Element to the appropriate parent node in the Document.
+ *
+ * @param nodeName the node name
+ * @param clauseDisplayName the clause display name
+ * @return the element
+ */
+ private Element createTemplateNode(String nodeName, String clauseDisplayName) {
+ Element mainChildElem = originalDoc.createElement(nodeName);
+ mainChildElem.setAttribute(DISPLAY_NAME, constantsMap.get(nodeName));
+
+ Element clauseChildElem = originalDoc.createElement("clause");
+ String dispName = constantsMap.get(clauseDisplayName);
+ clauseChildElem.setAttribute(DISPLAY_NAME, dispName + " 1");
+ clauseChildElem.setAttribute(TYPE, toCamelCase(dispName));
+ clauseChildElem.setAttribute(UUID_STRING, UUID.randomUUID().toString());
+ mainChildElem.appendChild(clauseChildElem);
+
+ mainChildElem.appendChild(clauseChildElem);
+
+ return mainChildElem;
+ }
+
+ /**
+ * Removes the from parent.
+ *
+ * @param node the node
+ */
+ public void removeFromParent(Node node) {
+ if (node != null) {
+ Node parentNode = node.getParentNode();
+ parentNode.removeChild(node);
}
-
- /**
- * Convert xml document to string.
- *
- * @param node the node
- * @param isFormatted
- * @return the string
- */
- public String transform(Node node, boolean isFormatted) {
- log.debug("In transform() method");
- Transformer tf;
- Writer out = null;
- try {
- TransformerFactory transformerFactory = XMLUtility.getInstance().buildTransformerFactory();
- tf = transformerFactory.newTransformer();
- tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
-
- if (isFormatted) {
- tf.setOutputProperty(OutputKeys.INDENT, "yes");
- }
-
- tf.setOutputProperty(OutputKeys.STANDALONE, "yes");
- out = new StringWriter();
- tf.transform(new DOMSource(node), new StreamResult(out));
- } catch (TransformerFactoryConfigurationError | TransformerException e) {
- log.error(e.getMessage(), e);
- }
- log.debug("Document object to ByteArray transformation complete");
- return out.toString();
+ }
+
+ /**
+ * Find node.
+ *
+ * @param document the document
+ * @param xPathString the x path string
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ public Node findNode(Document document, String xPathString) throws XPathExpressionException {
+ javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
+ Node node =
+ (Node) xPath.evaluate(xPathString, document.getDocumentElement(), XPathConstants.NODE);
+ return node;
+ }
+
+ /**
+ * Find node list.
+ *
+ * @param document the document
+ * @param xPathString the x path string
+ * @return the node list
+ * @throws XPathExpressionException the x path expression exception
+ */
+ public NodeList findNodeList(Document document, String xPathString)
+ throws XPathExpressionException {
+ javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
+ XPathExpression expr = xPath.compile(xPathString);
+ return (NodeList) expr.evaluate(document, XPathConstants.NODESET);
+ }
+
+ /**
+ * Gets the node count.
+ *
+ * @param document the document
+ * @param xPathString the x path string
+ * @return the node count
+ * @throws XPathExpressionException the x path expression exception
+ */
+ public int getNodeCount(Document document, String xPathString) throws XPathExpressionException {
+ javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
+ XPathExpression expr = xPath.compile(xPathString);
+ return ((Double) expr.evaluate(document, XPathConstants.NUMBER)).intValue();
+ }
+
+ /**
+ * Gets the original doc.
+ *
+ * @return the originalDoc
+ */
+ public Document getOriginalDoc() {
+ return originalDoc;
+ }
+
+ /**
+ * Sets the original doc.
+ *
+ * @param originalDoc the originalDoc to set
+ */
+ public void setOriginalDoc(Document originalDoc) {
+ this.originalDoc = originalDoc;
+ }
+
+ /**
+ * To camel case.
+ *
+ * @param name the name
+ * @return the string
+ */
+ private static String toCamelCase(String name) {
+ String nameNew = name.toLowerCase(Locale.US);
+ String[] parts = nameNew.split(" ");
+ StringBuffer camelCaseString =
+ new StringBuffer(parts[0].substring(0, 1).toLowerCase() + parts[0].substring(1));
+ for (int i = 1; i < parts.length; i++) {
+ camelCaseString.append(toProperCase(parts[i]));
}
-
- /**
- * Takes the spaces out of the clauseName (attribute displayName in XML).
- *
- * @param xmlString the xml string
- * @param xPathString the x path string
- * @return the string
- * @throws XPathExpressionException the x path expression exception
- */
- public static String normalizeNodeForSpaces(String xmlString, String xPathString) throws XPathExpressionException {
- XmlProcessor xmlProcessor = new XmlProcessor(xmlString);
- Node node = xmlProcessor.findNode(xmlProcessor.getOriginalDoc(), xPathString);
- if (node != null) {
- String oldValue = node.getNodeValue();
- // Normalize by changing multiple spaces into one space
- String newValue = oldValue.replaceAll("( )+", " ");
- node.setNodeValue(newValue);
- }
- return xmlProcessor.transform(xmlProcessor.getOriginalDoc());
+ return camelCaseString.toString();
+ }
+
+ /**
+ * To proper case.
+ *
+ * @param str the s
+ * @return the string
+ */
+ private static String toProperCase(String str) {
+ return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
+ }
+
+ /**
+ * Transform.
+ *
+ * @param node the node
+ * @return the string
+ */
+ public String transform(Node node) {
+ return transform(node, false);
+ }
+
+ /**
+ * Convert xml document to string.
+ *
+ * @param node the node
+ * @param isFormatted
+ * @return the string
+ */
+ public String transform(Node node, boolean isFormatted) {
+ log.debug("In transform() method");
+ Transformer tf;
+ Writer out = null;
+ try {
+ TransformerFactory transformerFactory = XMLUtility.getInstance().buildTransformerFactory();
+ tf = transformerFactory.newTransformer();
+ tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+
+ if (isFormatted) {
+ tf.setOutputProperty(OutputKeys.INDENT, "yes");
+ }
+
+ tf.setOutputProperty(OutputKeys.STANDALONE, "yes");
+ out = new StringWriter();
+ tf.transform(new DOMSource(node), new StreamResult(out));
+ } catch (TransformerFactoryConfigurationError | TransformerException e) {
+ log.error(e.getMessage(), e);
}
-
- /**
- * Utility method to go through the Node and its children (upto nth level)
- * and remove all TEXT nodes.
- *
- * @param node the node
- */
- public static void clean(Node node) {
- NodeList childNodes = node.getChildNodes();
-
- for (int n = childNodes.getLength() - 1; n >= 0; n--) {
- Node child = childNodes.item(n);
- short nodeType = child.getNodeType();
-
- if (nodeType == Node.ELEMENT_NODE) {
- clean(child);
- } else if (nodeType == Node.TEXT_NODE) {
- String trimmedNodeVal = child.getNodeValue().trim();
- if (trimmedNodeVal.length() == 0) {
- node.removeChild(child);
- } else {
- child.setNodeValue(trimmedNodeVal);
- }
- } else if (nodeType == Node.COMMENT_NODE) {
- node.removeChild(child);
- }
- }
+ log.debug("Document object to ByteArray transformation complete");
+ return out.toString();
+ }
+
+ /**
+ * Takes the spaces out of the clauseName (attribute displayName in XML).
+ *
+ * @param xmlString the xml string
+ * @param xPathString the x path string
+ * @return the string
+ * @throws XPathExpressionException the x path expression exception
+ */
+ public static String normalizeNodeForSpaces(String xmlString, String xPathString)
+ throws XPathExpressionException {
+ XmlProcessor xmlProcessor = new XmlProcessor(xmlString);
+ Node node = xmlProcessor.findNode(xmlProcessor.getOriginalDoc(), xPathString);
+ if (node != null) {
+ String oldValue = node.getNodeValue();
+ // Normalize by changing multiple spaces into one space
+ String newValue = oldValue.replaceAll("( )+", " ");
+ node.setNodeValue(newValue);
}
-
- public void updateCQLLibraryName(String libraryName) throws XPathExpressionException {
-
- Node cqlLibraryNode = findNode(originalDoc, "//cqlLookUp/library");
-
- if (cqlLibraryNode != null) {
- libraryName = cleanString(libraryName);
-
- cqlLibraryNode.setTextContent(libraryName);
+ return xmlProcessor.transform(xmlProcessor.getOriginalDoc());
+ }
+
+ /**
+ * Utility method to go through the Node and its children (upto nth level) and remove all TEXT
+ * nodes.
+ *
+ * @param node the node
+ */
+ public static void clean(Node node) {
+ NodeList childNodes = node.getChildNodes();
+
+ for (int n = childNodes.getLength() - 1; n >= 0; n--) {
+ Node child = childNodes.item(n);
+ short nodeType = child.getNodeType();
+
+ if (nodeType == Node.ELEMENT_NODE) {
+ clean(child);
+ } else if (nodeType == Node.TEXT_NODE) {
+ String trimmedNodeVal = child.getNodeValue().trim();
+ if (trimmedNodeVal.length() == 0) {
+ node.removeChild(child);
+ } else {
+ child.setNodeValue(trimmedNodeVal);
}
+ } else if (nodeType == Node.COMMENT_NODE) {
+ node.removeChild(child);
+ }
}
+ }
- /**
- * This method will take a String and remove all non-alphabet/non-numeric characters
- * except underscore ("_") characters.
- *
- * @param originalString
- * @return cleanedString
- */
- private String cleanString(String originalString) {
- originalString = originalString.replaceAll(" ", "");
-
- String cleanedString = "";
- for (int i = 0; i < originalString.length(); i++) {
- char c = originalString.charAt(i);
- int intc = (int) c;
+ public void updateCQLLibraryName(String libraryName) throws XPathExpressionException {
- if (c == '_' || (intc >= 48 && intc <= 57) || (intc >= 65 && intc <= 90) || (intc >= 97 && intc <= 122)) {
+ Node cqlLibraryNode = findNode(originalDoc, "//cqlLookUp/library");
- if (!(cleanedString.isEmpty() && Character.isDigit(c))) {
- cleanedString = cleanedString + "" + c;
- }
-
- }
+ if (cqlLibraryNode != null) {
+ libraryName = cleanString(libraryName);
+ cqlLibraryNode.setTextContent(libraryName);
+ }
+ }
+
+ /**
+ * This method will take a String and remove all non-alphabet/non-numeric characters except
+ * underscore ("_") characters.
+ *
+ * @param originalString
+ * @return cleanedString
+ */
+ private String cleanString(String originalString) {
+ originalString = originalString.replaceAll(" ", "");
+
+ String cleanedString = "";
+ for (int i = 0; i < originalString.length(); i++) {
+ char c = originalString.charAt(i);
+ int intc = (int) c;
+
+ if (c == '_'
+ || (intc >= 48 && intc <= 57)
+ || (intc >= 65 && intc <= 90)
+ || (intc >= 97 && intc <= 122)) {
+
+ if (!(cleanedString.isEmpty() && Character.isDigit(c))) {
+ cleanedString = cleanedString + "" + c;
}
-
- return cleanedString;
+ }
}
- /**
- * Check for default parameter MeasurementPeriod.
- *
- * @return the list
- */
- public List checkForDefaultParameters() {
- List missingDefaultParameterList = new ArrayList();
-
- if (originalDoc != null) {
- try {
- // Measurement Period
- Node measurementPeriodNode = this.findNode(originalDoc,
- "/measure/cqlLookUp//parameter[@name='"
- + PARAMETER_MEASUREMENT_PERIOD + "']");
- if (measurementPeriodNode == null) {
- missingDefaultParameterList.add(PARAMETER_MEASUREMENT_PERIOD);
- }
-
- } catch (XPathExpressionException e) {
- log.error(e.getMessage(), e);
- }
+ return cleanedString;
+ }
+
+ /**
+ * Check for default parameter MeasurementPeriod.
+ *
+ * @return the list
+ */
+ public List checkForDefaultParameters() {
+ List missingDefaultParameterList = new ArrayList();
+
+ if (originalDoc != null) {
+ try {
+ // Measurement Period
+ Node measurementPeriodNode =
+ this.findNode(
+ originalDoc,
+ "/measure/cqlLookUp//parameter[@name='" + PARAMETER_MEASUREMENT_PERIOD + "']");
+ if (measurementPeriodNode == null) {
+ missingDefaultParameterList.add(PARAMETER_MEASUREMENT_PERIOD);
}
- return missingDefaultParameterList;
- }
- public void removeUnusedDefaultCodes(List usedCodeList) {
- try {
- NodeList nodeList = findNodeList(getOriginalDoc(), XPATH_FOR_CODES);
- List codeSystemOIDsToRemove = new ArrayList<>();
- for (int i = 0; i < nodeList.getLength(); i++) {
- Node currentNode = nodeList.item(i);
- if (null != currentNode.getAttributes().getNamedItem(ATTRIBUTE_READ_ONLY)) {
- String codeOID = currentNode.getAttributes().getNamedItem(ATTRIBUTE_CODE_OID).getNodeValue();
- Boolean readOnly = Boolean.parseBoolean(currentNode.getAttributes().getNamedItem(ATTRIBUTE_READ_ONLY).getNodeValue());
-
- if (readOnly && (codeOID.equals(ConstantMessages.BIRTHDATE_OID) || codeOID.equals(ConstantMessages.DEAD_OID))) {
- String codeName = currentNode.getAttributes().getNamedItem(ATTRIBUTE_CODE_NAME).getNodeValue();
- if (!usedCodeList.contains(codeName)) {
- String codeSystemOID = currentNode.getAttributes().getNamedItem(ATTRIBUTE_CODE_SYSTEM_OID).getNodeValue();
- codeSystemOIDsToRemove.add(codeSystemOID);
- Node parentNode = currentNode.getParentNode();
- parentNode.removeChild(currentNode);
- }
- }
- }
+ } catch (XPathExpressionException e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+ return missingDefaultParameterList;
+ }
+
+ public void removeUnusedDefaultCodes(List usedCodeList) {
+ try {
+ NodeList nodeList = findNodeList(getOriginalDoc(), XPATH_FOR_CODES);
+ List codeSystemOIDsToRemove = new ArrayList<>();
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node currentNode = nodeList.item(i);
+ if (null != currentNode.getAttributes().getNamedItem(ATTRIBUTE_READ_ONLY)) {
+ String codeOID =
+ currentNode.getAttributes().getNamedItem(ATTRIBUTE_CODE_OID).getNodeValue();
+ Boolean readOnly =
+ Boolean.parseBoolean(
+ currentNode.getAttributes().getNamedItem(ATTRIBUTE_READ_ONLY).getNodeValue());
+
+ if (readOnly
+ && (codeOID.equals(ConstantMessages.BIRTHDATE_OID)
+ || codeOID.equals(ConstantMessages.DEAD_OID))) {
+ String codeName =
+ currentNode.getAttributes().getNamedItem(ATTRIBUTE_CODE_NAME).getNodeValue();
+ if (!usedCodeList.contains(codeName)) {
+ String codeSystemOID =
+ currentNode
+ .getAttributes()
+ .getNamedItem(ATTRIBUTE_CODE_SYSTEM_OID)
+ .getNodeValue();
+ codeSystemOIDsToRemove.add(codeSystemOID);
+ Node parentNode = currentNode.getParentNode();
+ parentNode.removeChild(currentNode);
}
- removeUnusedCodeSystems(codeSystemOIDsToRemove);
- } catch (XPathExpressionException e) {
- log.error(e.getMessage(), e);
+ }
}
+ }
+ removeUnusedCodeSystems(codeSystemOIDsToRemove);
+ } catch (XPathExpressionException e) {
+ log.error(e.getMessage(), e);
}
-
- /**
- * When drafting or cloning a measure or cql library, the version attribute should become an empty string in the valueset tag.
- *
- * It is an empty string because MAT still needs to support the version attribute because valuesets that had a version in an already
- * versioned measure should retain those values.
- */
- public void clearValuesetVersionAttribute() {
- try {
- NodeList nodeList = findNodeList(getOriginalDoc(), XPATH_FOR_VALUESETS);
- for (int i = 0; i < nodeList.getLength(); i++) {
- Node valuesetNode = nodeList.item(i);
- Node version = valuesetNode.getAttributes().getNamedItem("version");
- if (version != null) {
- version.setNodeValue("");
- }
- }
- } catch (XPathExpressionException e) {
- log.error(e.getMessage(), e);
+ }
+
+ /**
+ * When drafting or cloning a measure or cql library, the version attribute should become an empty
+ * string in the valueset tag.
+ *
+ *
It is an empty string because MAT still needs to support the version attribute because
+ * valuesets that had a version in an already versioned measure should retain those values.
+ */
+ public void clearValuesetVersionAttribute() {
+ try {
+ NodeList nodeList = findNodeList(getOriginalDoc(), XPATH_FOR_VALUESETS);
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node valuesetNode = nodeList.item(i);
+ Node version = valuesetNode.getAttributes().getNamedItem("version");
+ if (version != null) {
+ version.setNodeValue("");
}
+ }
+ } catch (XPathExpressionException e) {
+ log.error(e.getMessage(), e);
}
-
- private void removeUnusedCodeSystems(List codeSystemOIDsToRemove) {
- try {
- NodeList nodeList = findNodeList(getOriginalDoc(), XPATH_FOR_CODES);
- for (int i = 0; i < nodeList.getLength(); i++) {
- Node currentNode = nodeList.item(i);
- String codeSystemOID = currentNode.getAttributes().getNamedItem(ATTRIBUTE_CODE_SYSTEM_OID).getNodeValue();
- if (codeSystemOIDsToRemove.contains(codeSystemOID)) {
- codeSystemOIDsToRemove.remove(codeSystemOIDsToRemove.indexOf(codeSystemOID));
- }
- }
-
- for (String codeSystemOID : codeSystemOIDsToRemove) {
- String codeSystemXPathString = "[@codeSystemOID =\"" + codeSystemOID + "\"]";
- Node codeSystemNode = findNode(getOriginalDoc(), codeSystemXPathString);
- Node parentNode = codeSystemNode.getParentNode();
- parentNode.removeChild(codeSystemNode);
- }
- } catch (Exception e) {
- log.error(e.getMessage(), e);
+ }
+
+ private void removeUnusedCodeSystems(List codeSystemOIDsToRemove) {
+ try {
+ NodeList nodeList = findNodeList(getOriginalDoc(), XPATH_FOR_CODES);
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node currentNode = nodeList.item(i);
+ String codeSystemOID =
+ currentNode.getAttributes().getNamedItem(ATTRIBUTE_CODE_SYSTEM_OID).getNodeValue();
+ if (codeSystemOIDsToRemove.contains(codeSystemOID)) {
+ codeSystemOIDsToRemove.remove(codeSystemOIDsToRemove.indexOf(codeSystemOID));
}
+ }
+
+ for (String codeSystemOID : codeSystemOIDsToRemove) {
+ String codeSystemXPathString = "[@codeSystemOID =\"" + codeSystemOID + "\"]";
+ Node codeSystemNode = findNode(getOriginalDoc(), codeSystemXPathString);
+ Node parentNode = codeSystemNode.getParentNode();
+ parentNode.removeChild(codeSystemNode);
+ }
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
}
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/dto/MeasureExport.java b/src/main/java/gov/cms/madie/hqmf/dto/MeasureExport.java
index 2d548d6..62da273 100644
--- a/src/main/java/gov/cms/madie/hqmf/dto/MeasureExport.java
+++ b/src/main/java/gov/cms/madie/hqmf/dto/MeasureExport.java
@@ -10,29 +10,29 @@
@Builder
public class MeasureExport {
- private String id;
+ private String id;
- private String simpleXml;
+ private String simpleXml;
- private Measure measure;
+ private Measure measure;
- private String humanReadable;
+ private String humanReadable;
- private String hqmf;
+ private String hqmf;
- private String cql;
+ private String cql;
- private String measureJson;
+ private String measureJson;
- private String elmXml;
+ private String elmXml;
- private String fhirIncludedLibsJson;
+ private String fhirIncludedLibsJson;
- private XmlProcessor hqmfXmlProcessor;
+ private XmlProcessor hqmfXmlProcessor;
- private XmlProcessor simpleXmlProcessor;
+ private XmlProcessor simpleXmlProcessor;
- private XmlProcessor humanReadableProcessor;
+ private XmlProcessor humanReadableProcessor;
- private String releaseVersion;
+ private String releaseVersion;
}
diff --git a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFClauseLogicGenerator.java b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFClauseLogicGenerator.java
index 1aa181e..78d6981 100644
--- a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFClauseLogicGenerator.java
+++ b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFClauseLogicGenerator.java
@@ -26,3283 +26,3396 @@
import java.util.TreeMap;
public class HQMFClauseLogicGenerator implements Generator {
- private static final String GROUPER_CRITERIA = "grouperCriteria";
- private static final String CONJUNCTION_CODE = "conjunctionCode";
- private static final String LOCAL_VARIABLE_NAME = "localVariableName";
- private static final String CRITERIA_REFERENCE = "criteriaReference";
-
- private static final String ROLE = "role";
-
- private static final String PARTICIPATION = "participation";
-
- private static final String EXCERPT = "excerpt";
-
- private static final String SEQUENCE_NUMBER = "sequenceNumber";
-
- private static final String GROUPER = "grouper";
-
- private static final String ENTRY = "entry";
-
- private static final String DATA_CRITERIA_SECTION = "dataCriteriaSection";
-
- private Map subTreeNodeMap = new HashMap<>();
-
- public MeasureExport measureExport;
-
- private static final Logger logger = LoggerFactory.getLogger(HQMFClauseLogicGenerator.class);
-
- /**
- * MAP of Functional Ops NON Subset Type.
- */
- private static final Map FUNCTIONAL_OPS_NON_SUBSET = new TreeMap<>(
- String.CASE_INSENSITIVE_ORDER);
- /**
- * MAP of Functional Ops Subset Type.
- */
- private static final Map FUNCTIONAL_OPS_SUBSET = new TreeMap<>(
- String.CASE_INSENSITIVE_ORDER);
- static {
- FUNCTIONAL_OPS_NON_SUBSET.put(MatConstants.FIRST, "1");
- FUNCTIONAL_OPS_NON_SUBSET.put(MatConstants.SECOND, "2");
- FUNCTIONAL_OPS_NON_SUBSET.put(MatConstants.THIRD, "3");
- FUNCTIONAL_OPS_NON_SUBSET.put(MatConstants.FOURTH, "4");
- FUNCTIONAL_OPS_NON_SUBSET.put(MatConstants.FIFTH, "5");
-
- FUNCTIONAL_OPS_SUBSET.put(MatConstants.MOST_RECENT, "QDM_LAST");
- FUNCTIONAL_OPS_SUBSET.put(MatConstants.COUNT, "QDM_SUM");
- FUNCTIONAL_OPS_SUBSET.put(MatConstants.MIN, "QDM_MIN");
- FUNCTIONAL_OPS_SUBSET.put(MatConstants.MAX, "QDM_MAX");
- FUNCTIONAL_OPS_SUBSET.put(MatConstants.SUM, "QDM_SUM");
- FUNCTIONAL_OPS_SUBSET.put(MatConstants.MEDIAN, "QDM_MEDIAN");
- FUNCTIONAL_OPS_SUBSET.put(MatConstants.AVG, "QDM_AVERAGE");
-
- }
-
- /** The Constant populations. */
- private static final List POPULATION_NAME_LIST = new ArrayList<>();
-
- static {
- POPULATION_NAME_LIST.add("initialPopulation");
- POPULATION_NAME_LIST.add("denominator");
- POPULATION_NAME_LIST.add("denominatorExclusions");
- POPULATION_NAME_LIST.add("denominatorExceptions");
- POPULATION_NAME_LIST.add("numerator");
- POPULATION_NAME_LIST.add("numeratorExclusions");
- POPULATION_NAME_LIST.add("measurePopulation");
- POPULATION_NAME_LIST.add("measurePopulationExclusions");
- POPULATION_NAME_LIST.add("stratum");
- }
-
- /** The sub tree node in mo map. */
- Map subTreeNodeInMOMap = new HashMap<>();
-
- /** The sub tree node in pop map. */
- Map subTreeNodeInPOPMap = new HashMap<>();
-
- /** The sub tree node in RA map. */
- Map subTreeNodeInRAMap = new HashMap<>();
-
- /** The Constant FUNCTIONAL_OP_RULES_IN_POP. */
- private static final Map> FUNCTIONAL_OP_RULES_IN_POP = new TreeMap<>(
- String.CASE_INSENSITIVE_ORDER);
-
- /** The Constant FUNCTIONAL_OP_RULES_IN_MO. */
- private static final Map> FUNCTIONAL_OP_RULES_IN_MO = new TreeMap<>(
- String.CASE_INSENSITIVE_ORDER);
-
- static {
- FUNCTIONAL_OP_RULES_IN_POP.put("MEDIAN", getFunctionalOpFirstChild("MEDIAN"));
- FUNCTIONAL_OP_RULES_IN_POP.put("AVG", getFunctionalOpFirstChild("AVG"));
- FUNCTIONAL_OP_RULES_IN_POP.put("MAX", getFunctionalOpFirstChild("MAX"));
- FUNCTIONAL_OP_RULES_IN_POP.put("MIN", getFunctionalOpFirstChild("MIN"));
- FUNCTIONAL_OP_RULES_IN_POP.put("SUM", getFunctionalOpFirstChild("SUM"));
- FUNCTIONAL_OP_RULES_IN_POP.put("COUNT", getFunctionalOpFirstChild("COUNT"));
- FUNCTIONAL_OP_RULES_IN_POP.put("FIRST", getFunctionalOpFirstChild("FIRST"));
- FUNCTIONAL_OP_RULES_IN_POP.put("SECOND", getFunctionalOpFirstChild("SECOND"));
- FUNCTIONAL_OP_RULES_IN_POP.put("THIRD", getFunctionalOpFirstChild("THIRD"));
- FUNCTIONAL_OP_RULES_IN_POP.put("FOURTH", getFunctionalOpFirstChild("FOURTH"));
- FUNCTIONAL_OP_RULES_IN_POP.put("FIFTH", getFunctionalOpFirstChild("FIFTH"));
- FUNCTIONAL_OP_RULES_IN_POP.put("MOST RECENT", getFunctionalOpFirstChild("MOST RECENT"));
- FUNCTIONAL_OP_RULES_IN_POP.put("AGE AT", getFunctionalOpFirstChild("AGE AT"));
-
- /* Rules for Functions in Measure Observations */
- FUNCTIONAL_OP_RULES_IN_MO.put("MEDIAN", getFunctionalOpFirstChildInMO("MEDIAN"));
- FUNCTIONAL_OP_RULES_IN_MO.put("AVERAGE", getFunctionalOpFirstChildInMO("AVERAGE"));
- FUNCTIONAL_OP_RULES_IN_MO.put("MIN", getFunctionalOpFirstChildInMO("MIN"));
- FUNCTIONAL_OP_RULES_IN_MO.put("SUM", getFunctionalOpFirstChildInMO("SUM"));
- FUNCTIONAL_OP_RULES_IN_MO.put("COUNT", getFunctionalOpFirstChildInMO("COUNT"));
- FUNCTIONAL_OP_RULES_IN_MO.put("DATETIMEDIFF", getFunctionalOpFirstChildInMO("DATETIMEDIFF"));
- }
-
- @Override
- public String generate(MeasureExport me) throws Exception {
- measureExport = me;
- createUsedSubTreeRefMap();
- generateSubTreeXML();
- return null;
- }
-
- /**
- * Generate sub tree xml.
- *
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private void generateSubTreeXML() throws XPathExpressionException {
- String xpath = "/measure/subTreeLookUp/subTree[not(@instance)]";
- NodeList subTreeNodeList = measureExport.getSimpleXmlProcessor()
- .findNodeList(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
- for (int i = 0; i < subTreeNodeList.getLength(); i++) {
- Node subTreeNode = subTreeNodeList.item(i);
- subTreeNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- String uuid = subTreeNode.getAttributes().getNamedItem(UUID).getNodeValue();
- if (subTreeNodeInPOPMap.containsKey(uuid) && subTreeNodeInMOMap.containsKey(uuid)
- || subTreeNodeInPOPMap.containsKey(uuid) || subTreeNodeInRAMap.containsKey(uuid)) {
- generateSubTreeXML(subTreeNode, false);
- }
- }
- String xpathOccurrence = "/measure/subTreeLookUp/subTree[(@instance)]";
- NodeList occurrenceSubTreeNodeList = measureExport.getSimpleXmlProcessor()
- .findNodeList(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpathOccurrence);
- for (int i = 0; i < occurrenceSubTreeNodeList.getLength(); i++) {
- Node subTreeNode = occurrenceSubTreeNodeList.item(i);
- generateOccHQMF(subTreeNode);
- }
- }
-
- /**
- * Generate sub tree xml.
- *
- * @param subTreeNode
- * the sub tree node
- * @param msrObsDateTimeDiffSubTree
- * the msr obs date time diff sub tree
- * @return the node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- protected Node generateSubTreeXML(Node subTreeNode, boolean msrObsDateTimeDiffSubTree)
- throws XPathExpressionException {
-
- // If this is an empty or NULL clause, return right now.
- if (subTreeNode == null || !subTreeNode.hasChildNodes()) {
- return null;
- }
-
- /*
- If this is a Occurrence clause then we need to find the base clause and
- generate HQMF for the base clause. Then we need to generate Occurrence HQMF
- for the occurrence clause.
- */
- if (subTreeNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- String baseClauseUUID = subTreeNode.getAttributes().getNamedItem(INSTANCE_OF).getNodeValue();
- String xpath = "/measure/subTreeLookUp/subTree[@uuid = '" + baseClauseUUID + "']";
- Node baseSubTreeNode = measureExport.getSimpleXmlProcessor()
- .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
- generateSubTreeXML(baseSubTreeNode, false);
- generateOccHQMF(subTreeNode);
- }
-
- String subTreeUUID = subTreeNode.getAttributes().getNamedItem(UUID).getNodeValue();
- String clauseName = subTreeNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- Boolean isRav = isRiskAdjustmentVariable(subTreeUUID, clauseName);
-
- // Check the 'subTreeNodeMap' to make sure the clause isn't already generated.
- if (subTreeNodeMap.containsKey(subTreeUUID) && !msrObsDateTimeDiffSubTree) {
- logger.debug("HQMF for Clause " + clauseName + " is already generated. Skipping.");
- return null;
- }
-
- // get the first child of the subTreeNode
- Node firstChild = subTreeNode.getFirstChild();
- String firstChildName = firstChild.getNodeName();
- logger.debug("Generating HQMF for clause:'" + clauseName + "' with first child named:'" + firstChildName + "'.");
-
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
- Element dataCriteriaSectionElem = (Element) hqmfXmlProcessor.getOriginalDoc()
- .getElementsByTagName(DATA_CRITERIA_SECTION).item(0);
-
- if (isRav) {
- Comment riskAdjustmentVariable = hqmfXmlProcessor.getOriginalDoc().createComment("Risk Adjustment Variable");
- dataCriteriaSectionElem.appendChild(riskAdjustmentVariable);
- }
- Node entryElement = null;
- switch (firstChildName) {
- case SET_OP:
- entryElement = generateSetOpHQMF(firstChild, dataCriteriaSectionElem, clauseName);
- break;
- case ELEMENT_REF:
- entryElement = generateElementRefHQMF(firstChild, dataCriteriaSectionElem, clauseName);
- break;
- case SUB_TREE_REF:
- entryElement = generateSubTreeHQMF(firstChild, dataCriteriaSectionElem, clauseName);
- break;
- case RELATIONAL_OP:
- entryElement = generateRelOpHQMF(firstChild, dataCriteriaSectionElem, clauseName);
- break;
- case FUNCTIONAL_OP:
- entryElement = generateFunctionalOpHQMF(firstChild, dataCriteriaSectionElem, clauseName);
- break;
- default:
- // Dont do anything
- break;
- }
- if (isRav) {
- Node temp = hqmfXmlProcessor.getOriginalDoc().createAttribute(RAV);
- temp.setNodeValue("true");
- entryElement.getAttributes().setNamedItem(temp);
- }
- /*
- The clause is generated now. Make an entry in the 'subTreeNodeMap' to keep
- track of its generation.
- */
- subTreeNodeMap.put(subTreeUUID, subTreeNode);
- return entryElement;
-
- }
-
- /**
- * This method is used to discover weither a given class name and UUID is a risk
- * adjustment variable.
- *
- * @param subTreeUUID
- * the sub tree uuid
- * @param clauseName
- * the clause name
- * @return the boolean
- */
- private Boolean isRiskAdjustmentVariable(String subTreeUUID, String clauseName) {
- String xPath = "/measure/riskAdjustmentVariables/subTreeRef[@displayName=\"" + clauseName + "\" and @id='"
- + subTreeUUID + "']";
- boolean isRiskAdjustmentVariable = false;
- try {
- Node riskAdjVarNode = measureExport.getSimpleXmlProcessor()
- .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xPath);
- if (riskAdjVarNode != null) {
- isRiskAdjustmentVariable = true;
- }
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- return isRiskAdjustmentVariable;
- }
-
- /**
- * Generate occ hqmf.
- *
- * @param subTreeNode
- * the sub tree node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private void generateOccHQMF(Node subTreeNode) throws XPathExpressionException {
- // If this is an empty or NULL clause, return right now.
- if (subTreeNode == null || subTreeNode.getAttributes().getNamedItem(INSTANCE_OF) == null) {
- return;
- }
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
- String occSubTreeUUID = subTreeNode.getAttributes().getNamedItem(UUID).getNodeValue();
- String qdmVariableSubTreeUUID = subTreeNode.getAttributes().getNamedItem(INSTANCE_OF).getNodeValue();
- String clauseName = subTreeNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- Boolean isRAV = isRiskAdjustmentVariable(qdmVariableSubTreeUUID, clauseName);
- // Check the 'subTreeNodeMap' to make sure the occ clause isn't already generated.
- if (subTreeNodeMap.containsKey(occSubTreeUUID)) {
- logger.debug("HQMF for Occ Clause " + clauseName + " is already generated. Skipping.");
- return;
- }
-
- if (!subTreeNodeMap.containsKey(qdmVariableSubTreeUUID)) {
- logger.debug("HQMF for Clause " + clauseName + " is not already generated. Skipping.");
- return;
- }
-
- String xpath = "/measure/subTreeLookUp/subTree[@uuid = '" + qdmVariableSubTreeUUID + "']";
- Node baseSubTreeNode = measureExport.getSimpleXmlProcessor()
- .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
- Node baseFirstChild = baseSubTreeNode.getFirstChild();
- String baseExt = baseFirstChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
-
- Node firstChild = subTreeNode.getFirstChild();
- String firstChildName = firstChild.getNodeName();
- String ext = firstChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- // Local Variable Name.
- String localVarName = clauseName.replace("$", "") + "_" + UUIDUtilClient.uuid(5);
- String root = subTreeNode.getAttributes().getNamedItem(INSTANCE_OF).getNodeValue();
- // Check for Element Ref as first CHild.
- if (firstChildName.equalsIgnoreCase(ELEMENT_REF)) {
- ext = getElementRefExt(firstChild, measureExport.getSimpleXmlProcessor());
- baseExt = getElementRefExt(baseFirstChild, measureExport.getSimpleXmlProcessor());
- } else if (RELATIONAL_OP.equals(firstChildName) || FUNCTIONAL_OP.equals(firstChildName)
- || SET_OP.equals(firstChildName)) {
- ext += "_" + firstChild.getAttributes().getNamedItem(UUID).getNodeValue();
- baseExt += "_" + baseFirstChild.getAttributes().getNamedItem(UUID).getNodeValue();
- }
-
- if (FUNCTIONAL_OP.equals(firstChildName) && firstChild.getFirstChild() != null) {
- Node functionChild = firstChild.getFirstChild();
- Node baseFunctionChild = baseFirstChild.getFirstChild();
-
- if (functionChild != null) {
- if (functionChild.getNodeName().equalsIgnoreCase(SUB_TREE_REF)) {
- ext = functionChild.getAttributes().getNamedItem(ID).getNodeValue();
- baseExt = baseFunctionChild.getAttributes().getNamedItem(ID).getNodeValue();
- } else if (functionChild.getNodeName().equalsIgnoreCase(ELEMENT_REF)) {
- ext = getElementRefExt(functionChild, measureExport.getSimpleXmlProcessor());
- baseExt = getElementRefExt(baseFunctionChild, measureExport.getSimpleXmlProcessor());
- } else {
- ext = StringUtils.deleteWhitespace(
- functionChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue() + "_"
- + functionChild.getAttributes().getNamedItem(UUID).getNodeValue())
- .replaceAll(":", "_");
- baseExt = StringUtils.deleteWhitespace(
- baseFunctionChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue() + "_"
- + baseFunctionChild.getAttributes().getNamedItem(UUID).getNodeValue())
- .replaceAll(":", "_");
- }
- }
- }
-
- String isQdmVariable = subTreeNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
- if (isQdmVariable.equalsIgnoreCase(TRUE)) {
- ext = "qdm_var_" + StringUtils.deleteWhitespace(ext);
- baseExt = "qdm_var_" + StringUtils.deleteWhitespace(baseExt);
- localVarName = "qdm_var_" + StringUtils.deleteWhitespace(localVarName);
- }
- String extForOccurrenceNode = "occ" + subTreeNode.getAttributes().getNamedItem("instance").getNodeValue()
- + "of_" + ext;
- ext = StringUtils.deleteWhitespace(ext);
- localVarName = StringUtils.deleteWhitespace(localVarName);
- logger.debug("generateOccHQMF " + "//entry/*/id[@root='" + root + "'][@extension=\"" + baseExt + "\"]");
-
- Node idNodeQDM = hqmfXmlProcessor.findNode(hqmfXmlProcessor.getOriginalDoc(),
- "//entry/*/id[@root='" + root + "'][@extension=\"" + baseExt + "\"]");
- logger.debug("idNodeQDM == null?" + (idNodeQDM == null));
-
- if (idNodeQDM != null) {
- // Add code here which will create a replica of the entry elem of 'idNodeQDM'
- // and assign it an extension
- // which has "Occ_X" string in it.
- Node cloneMainEntryNode = idNodeQDM.getParentNode().getParentNode().cloneNode(true);
- Node cloneIDNode = findNode(cloneMainEntryNode, "ID");
- if (cloneMainEntryNode != null) {
- Node localVariableNode = cloneMainEntryNode.getFirstChild();
- if (localVariableNode.getAttributes().getNamedItem("value") != null) {
- localVariableNode.getAttributes().getNamedItem("value").setNodeValue(localVarName);
- }
- }
- cloneIDNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(extForOccurrenceNode);
-
- Element dataCriteriaSectionElem = (Element) hqmfXmlProcessor.getOriginalDoc()
- .getElementsByTagName(DATA_CRITERIA_SECTION).item(0);
-
- dataCriteriaSectionElem.appendChild(cloneMainEntryNode);
-
- Node parentNode = cloneIDNode.getParentNode().cloneNode(false);
- if (isRAV) {
- Comment RAComment = hqmfXmlProcessor.getOriginalDoc().createComment("Risk Adjustment Variable");
- dataCriteriaSectionElem.appendChild(RAComment);
- }
- Element entryElem = hqmfXmlProcessor.getOriginalDoc().createElement(ENTRY);
- entryElem.setAttribute(TYPE_CODE, "DRIV");
- Element idElement = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- idElement.setAttribute(ROOT, subTreeNode.getAttributes().getNamedItem(UUID).getNodeValue());
- idElement.setAttribute(EXTENSION, extForOccurrenceNode);
- parentNode.appendChild(idElement);
- Element outboundRelElem = hqmfXmlProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
- outboundRelElem.setAttribute(TYPE_CODE, "OCCR");
-
- Element criteriaRefElem = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
- String refClassCodeValue = parentNode.getAttributes().getNamedItem(CLASS_CODE).getNodeValue();
- String refMoodValue = parentNode.getAttributes().getNamedItem(MOOD_CODE).getNodeValue();
- criteriaRefElem.setAttribute(CLASS_CODE, refClassCodeValue);
- criteriaRefElem.setAttribute(MOOD_CODE, refMoodValue);
-
- Element idRelElem = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- idRelElem.setAttribute(ROOT, root);
- idRelElem.setAttribute(EXTENSION, extForOccurrenceNode);
-
- criteriaRefElem.appendChild(idRelElem);
- outboundRelElem.appendChild(criteriaRefElem);
- parentNode.appendChild(outboundRelElem);
- entryElem.appendChild(parentNode);
- dataCriteriaSectionElem.appendChild(entryElem);
-
- subTreeNodeMap.put(occSubTreeUUID, subTreeNode);
- }
- }
-
- /**
- * Generate functional op hqmf.
- *
- * @param functionalNode
- * the functional node
- * @param dataCriteriaSectionElem
- * the data criteria section elem
- * @param clauseName
- * the clause name
- * @return the node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node generateFunctionalOpHQMF(Node functionalNode, Element dataCriteriaSectionElem, String clauseName)
- throws XPathExpressionException {
- Node node = null;
- if (functionalNode.getChildNodes() != null) {
- Node firstChildNode = functionalNode.getFirstChild();
- String firstChildName = firstChildNode.getNodeName();
- switch (firstChildName) {
- case SET_OP:
- String functionOpType = functionalNode.getAttributes().getNamedItem(TYPE).getNodeValue();
- if (FUNCTIONAL_OPS_NON_SUBSET.containsKey(functionOpType.toUpperCase())
- || FUNCTIONAL_OPS_SUBSET.containsKey(functionOpType.toUpperCase())) {
- node = generateSetOpHQMF(firstChildNode, dataCriteriaSectionElem, clauseName);
- }
- break;
- case ELEMENT_REF:
- node = generateElementRefHQMF(firstChildNode, dataCriteriaSectionElem, clauseName);
- break;
- case RELATIONAL_OP:
- node = generateRelOpHQMF(firstChildNode, dataCriteriaSectionElem, clauseName);
- break;
- case FUNCTIONAL_OP:
- // findFunctionalOpChild(firstChildNode, dataCriteriaSectionElem);
- break;
- case SUB_TREE_REF:
- node = generateSubTreeHQMFInFunctionalOp(firstChildNode, dataCriteriaSectionElem, clauseName);
- break;
- default:
- // Dont do anything
- break;
- }
-
- String localVarName = clauseName;
-
- localVarName = localVarName.replace("$", "");
- Node parentNode = functionalNode.getParentNode();
- if (parentNode != null && parentNode.getNodeName().equalsIgnoreCase("subTree")) {
- if (parentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
- String isQdmVariable = parentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
- if (TRUE.equalsIgnoreCase(isQdmVariable)) {
- localVarName = localVarName.replace("$", "");
- localVarName = "qdm_var_" + localVarName;
- }
- }
- localVarName = localVarName + "_" + UUIDUtilClient.uuid(5);
- localVarName = StringUtils.deleteWhitespace(localVarName);
- updateLocalVar(node, localVarName);
- }
- }
- return node;
-
- }
-
- /**
- * Method to generate HQMF for function Ops with first child as subTreeRef. In
- * this case grouperCriteria will be generated for SubTreeRef with Excerpt entry
- * inside it for functional Op.
- *
- * @param firstChildNode
- * - SubTreeRef Node.
- * @param dataCriteriaSectionElem
- * - Data Criteria Element.
- * @param clauseName
- * the clause name
- * @return the node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node generateSubTreeHQMFInFunctionalOp(Node firstChildNode, Element dataCriteriaSectionElem,
- String clauseName) throws XPathExpressionException {
- Node parentNode = firstChildNode.getParentNode();
-
- // temp node.
- String subTreeUUID = firstChildNode.getAttributes().getNamedItem(ID).getNodeValue();
- String xpath = "/measure/subTreeLookUp/subTree[@uuid='" + subTreeUUID + "']";
- Node subTreeNode = measureExport.getSimpleXmlProcessor()
- .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
- String firstChildNameOfSubTree = subTreeNode.getFirstChild().getNodeName();
- if (FUNCTIONAL_OP.equals(firstChildNameOfSubTree)) {
- String firstChildNodeName = parentNode.getAttributes().getNamedItem(TYPE).getNodeValue();
- if (!SATISFIES_ALL.equalsIgnoreCase(firstChildNodeName)
- || !SATISFIES_ANY.equalsIgnoreCase(firstChildNodeName) || !AGE_AT.equals(firstChildNodeName)) {
- return null;
- }
- }
- Element root = measureExport.getHqmfXmlProcessor().getOriginalDoc().createElement("temp");
- generateSubTreeHQMF(firstChildNode, root, clauseName);
- Element entryElement = (Element) root.getFirstChild();
- Node firstChild = entryElement.getFirstChild();
- if ("localVariableName".equals(firstChild.getNodeName())) {
- firstChild = firstChild.getNextSibling();
- }
- Element excerpt = generateExcerptEntryForFunctionalNode(parentNode, null, measureExport.getHqmfXmlProcessor(),
- entryElement);
- if (excerpt != null) {
- firstChild.appendChild(excerpt);
- }
- dataCriteriaSectionElem.appendChild(entryElement);
- return entryElement;
- }
-
- /**
- * This will take care of the use case where a user can create a Clause with
- * only one QDM elementRef inside it. We will make a copy of the original entry
- * for QDM and update the id@root and id@extension for it. This will server as
- * an entry for the Clause.
- *
- * @param elementRefNode
- * the element ref node
- * @param parentNode
- * the parent node
- * @param clauseName
- * the clause name
- * @return the node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node generateElementRefHQMF(Node elementRefNode, Node parentNode, String clauseName)
- throws XPathExpressionException {
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
- Node node = null;
- String ext = getElementRefExt(elementRefNode, measureExport.getSimpleXmlProcessor());
- String root = elementRefNode.getAttributes().getNamedItem(ID).getNodeValue();
- String localVariableName = clauseName;
- Node idNodeQDM = hqmfXmlProcessor.findNode(hqmfXmlProcessor.getOriginalDoc(),
- "//entry/*/id[@root='" + root + "'][@extension=\"" + ext + "\"]");
- if (idNodeQDM != null) {
- Node entryElem = idNodeQDM.getParentNode().getParentNode().cloneNode(true);
- Node newIdNode = getTagFromEntry(entryElem, ID);
-
- if (newIdNode == null) {
- return null;
- }
-
- String idroot = "0";
- Node parNode = elementRefNode.getParentNode();
- if (parNode != null && SUB_TREE.equals(parNode.getNodeName())) {
- idroot = parNode.getAttributes().getNamedItem(UUID).getNodeValue();
- // Added logic to show qdm_variable in extension if clause is of qdm variable
- // type.
- String isQdmVariable = parNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
- if (isQdmVariable.equalsIgnoreCase(TRUE)) {
- String occText = null;
- // Handled Occurrence Of QDM Variable.
- if (parNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- occText = "occ" + parNode.getAttributes().getNamedItem(INSTANCE).getNodeValue() + "of_";
- }
- if (occText != null) {
- ext = occText + "qdm_var_" + ext;
- } else {
- ext = "qdm_var_" + ext;
- localVariableName = "qdm_var_" + localVariableName;
- }
- }
- localVariableName = localVariableName + "_" + UUIDUtilClient.uuid(5);
- localVariableName = StringUtils.deleteWhitespace(localVariableName);
- ((Element) newIdNode).setAttribute(ROOT, idroot);
- ((Element) newIdNode).setAttribute(EXTENSION, ext);
- Node localVariableNode = entryElem.getFirstChild();
- if (localVariableNode.getAttributes().getNamedItem("value") != null) {
- localVariableNode.getAttributes().getNamedItem("value").setNodeValue(localVariableName);
- }
-
- parentNode.appendChild(entryElem);
- node = entryElem;
- } else {
- // if the the parentNode for ElementRef is other than SubTreeNode
- Element excerptElement = null;
- Node subTreeParentNode = checkIfSubTree(parNode);
- if (subTreeParentNode != null) {
- root = subTreeParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
- if (subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
- String isQdmVariable = subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE)
- .getNodeValue();
- if (TRUE.equalsIgnoreCase(isQdmVariable)) {
- String occText = null;
- // Handled Occurrence Of QDM Variable.
- if (subTreeParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- occText = "occ"
- + subTreeParentNode.getAttributes().getNamedItem("instance").getNodeValue()
- + "of_";
- }
- if (occText != null) {
- ext = occText + "qdm_var_" + ext;
- } else {
- ext = "qdm_var_" + ext;
- }
- }
- }
- } else {
- root = java.util.UUID.randomUUID().toString();
- }
-
- Node entryNodeForElementRef = idNodeQDM.getParentNode().getParentNode();
- Node clonedEntryNodeForElementRef = entryNodeForElementRef.cloneNode(true);
- NodeList idChildNodeList = ((Element) clonedEntryNodeForElementRef).getElementsByTagName(ID);
- if (idChildNodeList != null && idChildNodeList.getLength() > 0) {
- Node idChildNode = idChildNodeList.item(0);
- idChildNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
- idChildNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
- }
-
- Node firstChild = clonedEntryNodeForElementRef.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
- firstChild = firstChild.getNextSibling();
- }
- // Added logic to show qdm_variable in extension if clause is of qdm variable
- // type.
- if (FUNCTIONAL_OP.equals(parNode.getNodeName())) {
- excerptElement = generateExcerptEntryForFunctionalNode(parNode, elementRefNode, hqmfXmlProcessor,
- clonedEntryNodeForElementRef);
- }
-
- if (excerptElement != null) {
-
- firstChild.appendChild(excerptElement);
- }
- parentNode.appendChild(clonedEntryNodeForElementRef);
- node = clonedEntryNodeForElementRef;
-
- }
- updateLocalVar(node, ext);
- }
-
- return node;
- }
-
- /**
- * This will take care of the use case where a user can create a Clause with
- * only one child Clause inside it. If HQMF for the child clause is already
- * generated, then since we have no way of referencing this child clause using
- * directly, we are adding it to a default UNION grouper.
- *
- * If it isnt generated then we generate it and then add a criteriaRef to it
- * inside a default UNION.
- *
- * @param subTreeRefNode
- * the sub tree ref node
- * @param parentNode
- * the parent node
- * @param clauseName
- * the clause name
- * @return the node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node generateSubTreeHQMF(Node subTreeRefNode, Node parentNode, String clauseName)
- throws XPathExpressionException {
-
- String subTreeUUID = subTreeRefNode.getAttributes().getNamedItem(ID).getNodeValue();
-
- /*
- * Check if the Clause has already been generated. If it is not generated yet,
- * then generate it by calling the 'generateSubTreeXML' method.
- */
- if (!subTreeNodeMap.containsKey(subTreeUUID)) {
- String xpath = "/measure/subTreeLookUp/subTree[@uuid='" + subTreeUUID + "']";
- Node subTreeNode = measureExport.getSimpleXmlProcessor()
- .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
- generateSubTreeXML(subTreeNode, false);
- }
-
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
-
- // creating Entry Tag
- Element entryElem = hqmfXmlProcessor.getOriginalDoc().createElement(ENTRY);
- entryElem.setAttribute(TYPE_CODE, "DRIV");
- String root = java.util.UUID.randomUUID().toString();
- String ext = subTreeRefNode.getAttributes().getNamedItem(ID).getNodeValue();
- String localVarName = clauseName;
- localVarName = localVarName.replace("$", "");
- Node parNode = checkIfSubTree(subTreeRefNode.getParentNode());
- if (parNode != null) {
- root = parNode.getAttributes().getNamedItem(UUID).getNodeValue();
- if (parNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
- String isQdmVariable = parNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
- if (TRUE.equalsIgnoreCase(isQdmVariable)) {
- String occText = null;
- // Handled Occurrence Of QDM Variable.
- if (parNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- occText = "occ" + parNode.getAttributes().getNamedItem(INSTANCE).getNodeValue() + "of_";
- }
- if (occText != null) {
- ext = occText + "qdm_var_" + ext;
- } else {
- ext = "qdm_var_" + ext;
- localVarName = "qdm_var_" + localVarName;
- }
- }
- }
- }
-
- Node grouperElem = generateEmptyGrouper(hqmfXmlProcessor, root, ext);
-
- // generate comment
- Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment(
- "outBoundRelationship for " + subTreeRefNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- grouperElem.appendChild(comment);
-
- // generate outboundRelationship
- Element outboundRelElem = generateEmptyOutboundElem(hqmfXmlProcessor);
- Element conjunctionCodeElem = hqmfXmlProcessor.getOriginalDoc().createElement(CONJUNCTION_CODE);
- conjunctionCodeElem.setAttribute(CODE, "OR");
-
- outboundRelElem.appendChild(conjunctionCodeElem);
- generateCritRefForNode(outboundRelElem, subTreeRefNode);
-
- grouperElem.appendChild(outboundRelElem);
-
- Element localVarElem = hqmfXmlProcessor.getOriginalDoc().createElement(LOCAL_VARIABLE_NAME);
- localVarName = localVarName + "_" + UUIDUtilClient.uuid(5);
- localVarName = StringUtils.deleteWhitespace(localVarName);
- localVarElem.setAttribute(VALUE, localVarName);
- entryElem.appendChild(localVarElem);
-
- entryElem.appendChild(grouperElem);
- parentNode.appendChild(entryElem);
- return entryElem;
-
- }
-
- /**
- * This method wil generate HQMF code for setOp (UNION,INTERSECTION).
- *
- * @param setOpNode
- * the set op node
- * @param parentNode
- * the parent node
- * @param clauseName
- * the clause name
- * @return the node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node generateSetOpHQMF(Node setOpNode, Node parentNode, String clauseName) throws XPathExpressionException {
-
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
- // DISPLAY NAME is used instead of type as it is in Title case.
- String setOpType = setOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- String conjunctionType = "OR";
-
- if ("union".equalsIgnoreCase(setOpType) || SATISFIES_ANY.equalsIgnoreCase(setOpType)) {
- conjunctionType = "OR";
- } else if ("intersection".equalsIgnoreCase(setOpType) || SATISFIES_ALL.equalsIgnoreCase(setOpType)) {
- conjunctionType = "AND";
- }
-
- // creating Entry Tag
- Element entryElem = hqmfXmlProcessor.getOriginalDoc().createElement(ENTRY);
- entryElem.setAttribute(TYPE_CODE, "DRIV");
-
- // creating grouperCriteria element
- String root = "0";
- // String ext = setOpType.toUpperCase();
-
- String ext = setOpType + "_" + setOpNode.getAttributes().getNamedItem(UUID).getNodeValue();
- String localVariableName = clauseName + "_" + setOpNode.getAttributes().getNamedItem(UUID).getNodeValue();
- Node subTreeParentNode = checkIfSubTree(setOpNode.getParentNode());
- if (subTreeParentNode != null) {
- root = subTreeParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
- if (subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
- String isQdmVariable = subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
- if (TRUE.equalsIgnoreCase(isQdmVariable)) {
- String occText = null;
- // Handled Occurrence Of QDM Variable.
- if (subTreeParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- occText = "occ" + subTreeParentNode.getAttributes().getNamedItem(INSTANCE).getNodeValue()
- + "of_";
- }
- if (occText != null) {
- ext = occText + "qdm_var_" + ext;
- } else {
- ext = "qdm_var_" + ext;
- }
- localVariableName = "qdm_var_" + localVariableName;
- }
- }
- } else {
- root = java.util.UUID.randomUUID().toString();
- }
-
- Node grouperElem = generateEmptyGrouper(hqmfXmlProcessor, root, ext);
- Node templateIdNode = getTemplateIdForSatisfies(hqmfXmlProcessor, setOpType);
- if (templateIdNode != null) {
- grouperElem.insertBefore(templateIdNode, grouperElem.getFirstChild());
- }
-
- NodeList childNodes = setOpNode.getChildNodes();
- for (int i = 0; i < childNodes.getLength(); i++) {
- Node childNode = childNodes.item(i);
- String childName = childNode.getNodeName();
- if ("comment".equals(childName)) {
- continue;
- }
-
- // generate comment
- Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment(
- "outBoundRelationship for " + childNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- grouperElem.appendChild(comment);
-
- // generate outboundRelationship
- Element outboundRelElem = generateEmptyOutboundElem(hqmfXmlProcessor);
- Element conjunctionCodeElem = hqmfXmlProcessor.getOriginalDoc().createElement(CONJUNCTION_CODE);
- conjunctionCodeElem.setAttribute(CODE, conjunctionType);
-
- outboundRelElem.appendChild(conjunctionCodeElem);
- if (ELEMENT_REF.equals(childName) || SUB_TREE_REF.equals(childName)) {
- generateCritRefForNode(outboundRelElem, childNode);
- } else {
- switch (childName) {
- case SET_OP:
- generateCritRefSetOp(parentNode, hqmfXmlProcessor, childNode, outboundRelElem, clauseName);
- break;
- case RELATIONAL_OP:
- generateCritRefRelOp(parentNode, hqmfXmlProcessor, childNode, outboundRelElem, clauseName);
- break;
- case FUNCTIONAL_OP:
- generateCritRefFunctionalOp(childNode, outboundRelElem, clauseName);
- break;
-
- default:
- // Dont do anything
- break;
- }
- }
- grouperElem.appendChild(outboundRelElem);
- }
-
- // Added logic to show qdm_variable in extension if clause is of qdm variable
- // type.
- Node grouperEntryNode = grouperElem.cloneNode(true);
- if (FUNCTIONAL_OP.equals(setOpNode.getParentNode().getNodeName())) {
- Element excerptElement = generateExcerptEntryForFunctionalNode(setOpNode.getParentNode(), null,
- hqmfXmlProcessor, grouperEntryNode);
- // Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("excerpt
- // for
- // "+setOpNode.getParentNode().getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- // grouperElem.appendChild(comment);
- grouperElem.appendChild(excerptElement);
- }
- Element localVarElem = hqmfXmlProcessor.getOriginalDoc().createElement(LOCAL_VARIABLE_NAME);
- localVarElem.setAttribute(VALUE, StringUtils.deleteWhitespace(localVariableName));
- entryElem.appendChild(localVarElem);
-
- entryElem.appendChild(grouperElem);
- parentNode.appendChild(entryElem);
-
- return entryElem;
- }
-
- /**
- * Generate crit ref functional op.
- *
- * @param childNode
- * -Node
- * @param outboundRelElem
- * - outBoundElement
- * @param clauseName
- * the clause name
- * @throws XPathExpressionException
- * -Exception
- */
- private void generateCritRefFunctionalOp(Node childNode, Element outboundRelElem, String clauseName)
- throws XPathExpressionException {
- Element dataCriteriaSectionElem = (Element) measureExport.getHqmfXmlProcessor().getOriginalDoc()
- .getElementsByTagName(DATA_CRITERIA_SECTION).item(0);
- Node entryNode = generateFunctionalOpHQMF(childNode, dataCriteriaSectionElem, clauseName);
- if (entryNode != null && entryNode.getNodeName().equals(ENTRY)) {
- Node fChild = entryNode.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(fChild.getNodeName())) {
- fChild = fChild.getNextSibling();
- }
- // create criteriaRef
- Element criteriaReference = measureExport.getHqmfXmlProcessor().getOriginalDoc()
- .createElement(CRITERIA_REFERENCE);
- criteriaReference.setAttribute(CLASS_CODE, fChild.getAttributes().getNamedItem(CLASS_CODE).getNodeValue());
- criteriaReference.setAttribute(MOOD_CODE, fChild.getAttributes().getNamedItem(MOOD_CODE).getNodeValue());
- NodeList childNodeList = fChild.getChildNodes();
- for (int j = 0; j < childNodeList.getLength(); j++) {
- Node entryChildNodes = childNodeList.item(j);
- if (entryChildNodes.getNodeName().equalsIgnoreCase(ID)) {
- Element id = measureExport.getHqmfXmlProcessor().getOriginalDoc().createElement(ID);
- id.setAttribute(ROOT, entryChildNodes.getAttributes().getNamedItem(ROOT).getNodeValue());
- id.setAttribute(EXTENSION, entryChildNodes.getAttributes().getNamedItem(EXTENSION).getNodeValue());
- criteriaReference.appendChild(id);
- outboundRelElem.appendChild(criteriaReference);
- break;
- }
- }
- }
- }
-
- /**
- * This method is used to create a tag for SATISFIES ALL/SATISFIES
- * ANY functionalOps. These are functionalOp's but are converted to setOps and
- * treated as Groupers.
- *
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @param type
- * the type
- * @return the template id for satisfies
- */
- private Node getTemplateIdForSatisfies(XmlProcessor hqmfXmlProcessor, String type) {
- Node templateIdNode = null;
-
- if (SATISFIES_ALL.equalsIgnoreCase(type) || SATISFIES_ANY.equalsIgnoreCase(type)) {
- templateIdNode = hqmfXmlProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
- Element itemNode = hqmfXmlProcessor.getOriginalDoc().createElement(ITEM);
-
- // initialize rootOID with the OID for SATISFIES ALL
- String rootOID = "2.16.840.1.113883.10.20.28.3.109";
- // if we are dealing with SATISFIES ANY change the OID
- if (SATISFIES_ANY.equalsIgnoreCase(type)) {
- rootOID = "2.16.840.1.113883.10.20.28.3.108";
- }
- itemNode.setAttribute(ROOT, rootOID);
-
- templateIdNode.appendChild(itemNode);
- }
-
- return templateIdNode;
- }
-
- /**
- * Generate rel op hqmf.
- *
- * @param relOpNode
- * the rel op node
- * @param dataCriteriaSectionElem
- * the data criteria section elem
- * @param clauseName
- * the clause name
- * @return the node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node generateRelOpHQMF(Node relOpNode, Node dataCriteriaSectionElem, String clauseName)
- throws XPathExpressionException {
- Node finalNode = null;
- if (relOpNode.getChildNodes().getLength() == 2) {
- Node lhsNode = relOpNode.getFirstChild();
- Node rhsNode = relOpNode.getLastChild();
- String lhsName = lhsNode.getNodeName();
-
- // NamedNodeMap attribMap = relOpNode.getAttributes();
- // String relDisplayName =
- // StringUtils.deleteWhitespace(attribMap.getNamedItem(DISPLAY_NAME).getNodeValue());
- // String relUUID = attribMap.getNamedItem(UUID).getNodeValue();
- // String localVarName = "localVar_"+relDisplayName+"_"+relUUID;
-
- String localVarName = clauseName;
- Node parentNode = relOpNode.getParentNode();
- if (parentNode != null) {
- if (parentNode.getNodeName().equalsIgnoreCase("subTree") &&
- parentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
- String isQdmVariable = parentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
- if (TRUE.equalsIgnoreCase(isQdmVariable)) {
- localVarName = localVarName.replace("$", "");
- localVarName = "qdm_var_" + localVarName;
- }
- }
- }
- localVarName = localVarName + "_" + UUIDUtilClient.uuid(5);
- localVarName = StringUtils.deleteWhitespace(localVarName);
- if (ELEMENT_REF.equals(lhsName)) {
- finalNode = getrelOpLHSQDM(relOpNode, dataCriteriaSectionElem, lhsNode, rhsNode, clauseName);
- } else if (RELATIONAL_OP.equals(lhsName)) {
- finalNode = getrelOpLHSRelOp(relOpNode, dataCriteriaSectionElem, lhsNode, rhsNode, clauseName);
- Node relOpParentNode = relOpNode.getParentNode();
- if (relOpParentNode.getNodeName().equalsIgnoreCase(FUNCTIONAL_OP)) {
- Element excerptElement = generateExcerptEntryForFunctionalNode(relOpNode.getParentNode(), lhsNode,
- measureExport.getHqmfXmlProcessor(), finalNode);
- if (excerptElement != null) {
- Node firstNode = finalNode.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(firstNode.getNodeName())) {
- firstNode = firstNode.getNextSibling();
- }
- // Comment comment =
- // measureExport.getHQMFXmlProcessor().getOriginalDoc().createComment("entry for
- // "+relOpNode.getParentNode().getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- // firstNode.appendChild(comment);
- firstNode.appendChild(excerptElement);
- }
- }
- // return finalNode;
- } else if (SET_OP.equals(lhsName)) {
- finalNode = getrelOpLHSSetOp(relOpNode, dataCriteriaSectionElem, lhsNode, rhsNode, clauseName);
- Node relOpParentNode = relOpNode.getParentNode();
- if (relOpParentNode.getNodeName().equalsIgnoreCase(FUNCTIONAL_OP)) {
- Element excerptElement = generateExcerptEntryForFunctionalNode(relOpNode.getParentNode(), lhsNode,
- measureExport.getHqmfXmlProcessor(), finalNode);
- if (excerptElement != null) {
- Node firstNode = finalNode.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(firstNode.getNodeName())) {
- firstNode = firstNode.getNextSibling();
- }
- // Comment comment =
- // measureExport.getHQMFXmlProcessor().getOriginalDoc().createComment("entry for
- // "+relOpNode.getParentNode().getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- // firstNode.appendChild(comment);
- firstNode.appendChild(excerptElement);
- }
- }
- // return finalNode;
- } else if (SUB_TREE_REF.equals(lhsName) || FUNCTIONAL_OP.equalsIgnoreCase(lhsName)) {
- Node functionalOpNodeWithChildQDM = checkLHSFunctionalOpWithChildQDM(lhsNode);
- if (functionalOpNodeWithChildQDM != null) {
- // Do something godawful here.
- Node functionEntryNode = generateFunctionalOpHQMF(functionalOpNodeWithChildQDM,
- (Element) dataCriteriaSectionElem, clauseName);
- dataCriteriaSectionElem.appendChild(functionEntryNode);
- finalNode = createSpecialGrouperForRelOp(relOpNode, functionEntryNode, rhsNode,
- dataCriteriaSectionElem, clauseName);
- } else if (FUNCTIONAL_OP.equalsIgnoreCase(lhsName)) {
- finalNode = getFunctionalOpLHS(relOpNode, dataCriteriaSectionElem, lhsNode, rhsNode, clauseName);
- } else {
- finalNode = getrelOpLHSSubtree(relOpNode, dataCriteriaSectionElem, lhsNode, rhsNode, clauseName);
- }
-
- }
- // else if(FUNCTIONAL_OP.equalsIgnoreCase(lhsName)) {
- // finalNode = getFunctionalOpLHS(relOpNode, dataCriteriaSectionElem, lhsNode,
- // rhsNode, clauseName);
- // }
- if (parentNode.getNodeName().equalsIgnoreCase("subTree")) {
- updateLocalVar(finalNode, localVarName);
- }
- } else {
- logger.debug("Relational Op:" + relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
- + " does not have exactly 2 children. Skipping HQMF for it.");
- }
- return finalNode;
- }
-
- /**
- * When we have a case of "First:(Encounter,Performed:Inpatient) During
- * Measurement Period"; we need to generate a entry with Grouper.
- *
- * @param relOpNode
- * the rel op node
- * @param functionEntryNode
- * the function entry node
- * @param rhsNode
- * the rhs node
- * @param dataCriteriaSectionElem
- * the data criteria section elem
- * @param clauseName
- * the clause name
- * @return the node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node createSpecialGrouperForRelOp(Node relOpNode, Node functionEntryNode, Node rhsNode,
- Node dataCriteriaSectionElem, String clauseName) throws XPathExpressionException {
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
-
- // creating Entry Tag
- Element entryElem = hqmfXmlProcessor.getOriginalDoc().createElement(ENTRY);
- entryElem.setAttribute(TYPE_CODE, "DRIV");
-
- String localVariableName = relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- Element localVarElem = hqmfXmlProcessor.getOriginalDoc().createElement(LOCAL_VARIABLE_NAME);
- localVariableName = localVariableName + "_" + UUIDUtilClient.uuid(5);
- localVariableName = StringUtils.deleteWhitespace(localVariableName);
- localVarElem.setAttribute(VALUE, localVariableName);
- entryElem.appendChild(localVarElem);
-
- String root = relOpNode.getAttributes().getNamedItem(UUID).getNodeValue();
- String ext = StringUtils.deleteWhitespace(relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
- + "_" + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
-
- Node grouperElem = generateEmptyGrouper(hqmfXmlProcessor, root, ext);
- entryElem.appendChild(grouperElem);
-
- Node subTreeParentNode = checkIfSubTree(relOpNode.getParentNode());
- Node idNode = findNode(entryElem, "ID");
- if (idNode != null && subTreeParentNode != null) {
- String idExtension = idNode.getAttributes().getNamedItem(EXTENSION).getNodeValue();
- String idRoot = idNode.getAttributes().getNamedItem(ROOT).getNodeValue();
- root = subTreeParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
- ext = StringUtils.deleteWhitespace(relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
- + "_" + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
- if (subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
- String isQdmVariable = subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
- if (TRUE.equalsIgnoreCase(isQdmVariable)) {
- String occText = null;
- // Handled Occurrence Of QDM Variable.
- if (subTreeParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- occText = "occ" + subTreeParentNode.getAttributes().getNamedItem(INSTANCE).getNodeValue()
- + "of_";
- }
- if (occText != null) {
- ext = occText + "qdm_var_" + ext;
- } else {
- ext = "qdm_var_" + ext;
- }
- }
- }
- idNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
- idNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
- // Updated Excerpt tag idNode root and extension.
- // String hqmfXmlString = measureExport.getHQMFXmlProcessor().getOriginalXml();
- Node idNodeExcerpt = measureExport.getHqmfXmlProcessor().findNode(
- measureExport.getHqmfXmlProcessor().getOriginalDoc(),
- "//entry/*/excerpt/*/id[@root='" + idRoot + "'][@extension=\"" + idExtension + "\"]");
- if (idNodeExcerpt != null) {
- idNodeExcerpt.getAttributes().getNamedItem(ROOT).setNodeValue(root);
- idNodeExcerpt.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
- }
-
- }
-
- // Element temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode,
- // measureExport.getHQMFXmlProcessor());
- Element temporallyRelatedInfoNode = null;
- if (!FULFILLS.equalsIgnoreCase(relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
- temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode, measureExport.getHqmfXmlProcessor());
- } else {
- temporallyRelatedInfoNode = measureExport.getHqmfXmlProcessor().getOriginalDoc()
- .createElement(OUTBOUND_RELATIONSHIP);
- temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
- }
- handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
- Node firstChild = entryElem.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
- firstChild = firstChild.getNextSibling();
- }
- NodeList outBoundList = ((Element) firstChild).getElementsByTagName(OUTBOUND_RELATIONSHIP);
- if (outBoundList != null && outBoundList.getLength() > 0) {
- Node outBound = outBoundList.item(0);
- firstChild.insertBefore(temporallyRelatedInfoNode, outBound);
- } else {
- NodeList excerptList = ((Element) firstChild).getElementsByTagName(EXCERPT);
- if (excerptList != null && excerptList.getLength() > 0) {
- Node excerptNode = excerptList.item(0);
- firstChild.insertBefore(temporallyRelatedInfoNode, excerptNode);
- } else {
- firstChild.appendChild(temporallyRelatedInfoNode);
- }
- }
-
- // Add a outBound Relationship for the 'functionEntryNode' passed above.
- Element outBoundForFunction = measureExport.getHqmfXmlProcessor().getOriginalDoc()
- .createElement(OUTBOUND_RELATIONSHIP);
- outBoundForFunction.setAttribute(TYPE_CODE, "COMP");
- Node idNodeForFunctionEntryNode = findNode(functionEntryNode, "ID");
- Node excerptNodeForFunctionEntryNode = findNode(functionEntryNode, "excerpt");
- Node idNodeInExcerptNode = findNode(excerptNodeForFunctionEntryNode, "id");
- String newExtension = StringUtils.deleteWhitespace(clauseName) + "_"
- + idNodeForFunctionEntryNode.getAttributes().getNamedItem(EXTENSION).getNodeValue();
-
- idNodeForFunctionEntryNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(newExtension);
- idNodeInExcerptNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(newExtension);
-
- Node firstChildOfFunctionEntryElem = functionEntryNode.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(firstChildOfFunctionEntryElem.getNodeName())) {
- firstChildOfFunctionEntryElem = firstChildOfFunctionEntryElem.getNextSibling();
- }
- NamedNodeMap criteriaNodeAttributeMap = firstChildOfFunctionEntryElem.getAttributes();
- if (criteriaNodeAttributeMap.getNamedItem(CLASS_CODE) != null
- && criteriaNodeAttributeMap.getNamedItem(MOOD_CODE) != null) {
- // create criteriaRef
- Element criteriaReference = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
- criteriaReference.setAttribute(CLASS_CODE,
- criteriaNodeAttributeMap.getNamedItem(CLASS_CODE).getNodeValue());
- criteriaReference.setAttribute(MOOD_CODE,
- criteriaNodeAttributeMap.getNamedItem(MOOD_CODE).getNodeValue());
-
- Node idNodeForFunctionEntryNode_Clone = idNodeForFunctionEntryNode.cloneNode(true);
- criteriaReference.appendChild(idNodeForFunctionEntryNode_Clone);
-
- outBoundForFunction.appendChild(criteriaReference);
- grouperElem.appendChild(outBoundForFunction);
- }
- dataCriteriaSectionElem.appendChild(entryElem);
- return entryElem;
- }
-
- /**
- * This is to be called when you want to check If the node passed is a
- * FunctionOp with it's child being an elementRef/QDM. If the node passed is a
- * SubTree/Clause node then this will "recursively" look into the child of that
- * SubTree/Clause node to see if that child is a FunctionOp with child being an
- * elementRef/QDM.
- *
- * @param node
- * the node
- * @return the node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node checkLHSFunctionalOpWithChildQDM(Node node) throws XPathExpressionException {
- Node returnFunctionalNode = null;
-
- String nodeName = node.getNodeName();
- if (FUNCTIONAL_OP.equalsIgnoreCase(nodeName)) {
- returnFunctionalNode = node;
- /*
- * Node childNode = node.getFirstChild(); if(childNode != null &&
- * ELEMENT_REF.equals(childNode.getNodeName())){ returnFunctionalNode = node; }
- */
- } else if (SUB_TREE_REF.equals(nodeName)) {
- String subTreeUUID = node.getAttributes().getNamedItem(ID).getNodeValue();
-
- String xpath = "/measure/subTreeLookUp/subTree[@uuid='" + subTreeUUID + "']";
- Node subTreeNode = measureExport.getSimpleXmlProcessor()
- .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
-
- Node childNode = subTreeNode.getFirstChild();
- if (childNode != null) {
- returnFunctionalNode = checkLHSFunctionalOpWithChildQDM(childNode);
- }
- }
- return returnFunctionalNode;
- }
-
- /**
- * Gets the functional op lhs.
- *
- * @param relOpNode
- * the rel op node
- * @param dataCriteriaSectionElem
- * the data criteria section elem
- * @param lhsNode
- * the lhs node
- * @param rhsNode
- * the rhs node
- * @param clauseName
- * the clause name
- * @return the functional op lhs
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node getFunctionalOpLHS(Node relOpNode, Node dataCriteriaSectionElem, Node lhsNode, Node rhsNode,
- String clauseName) throws XPathExpressionException {
- Node entryNode = generateFunctionalOpHQMF(lhsNode, (Element) dataCriteriaSectionElem, clauseName);
-
- // Comment comment =
- // measureExport.getHQMFXmlProcessor().getOriginalDoc().createComment("entry for
- // "+relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- // dataCriteriaSectionElem.appendChild(comment);
- if (entryNode != null) {
- Node subTreeParentNode = checkIfSubTree(relOpNode.getParentNode());
- Node idNode = findNode(entryNode, "ID");
- if (idNode != null && subTreeParentNode != null) {
- String idExtension = idNode.getAttributes().getNamedItem(EXTENSION).getNodeValue();
- String idRoot = idNode.getAttributes().getNamedItem(ROOT).getNodeValue();
- String root = subTreeParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
- String ext = StringUtils
- .deleteWhitespace(relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue() + "_"
- + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
- if (subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
- String isQdmVariable = subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
- if (TRUE.equalsIgnoreCase(isQdmVariable)) {
- String occText = null;
- // Handled Occurrence Of QDM Variable.
- if (subTreeParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- occText = "occ" + subTreeParentNode.getAttributes().getNamedItem(INSTANCE).getNodeValue()
- + "of_";
- }
- if (occText != null) {
- ext = occText + "qdm_var_" + ext;
- } else {
- ext = "qdm_var_" + ext;
- }
- }
- }
- idNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
- idNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
- // Updated Excerpt tag idNode root and extension.
- // String hqmfXmlString = measureExport.getHQMFXmlProcessor().getOriginalXml();
- Node idNodeExcerpt = measureExport.getHqmfXmlProcessor().findNode(
- measureExport.getHqmfXmlProcessor().getOriginalDoc(),
- "//entry/*/excerpt/*/id[@root='" + idRoot + "'][@extension=\"" + idExtension + "\"]");
- if (idNodeExcerpt != null) {
- idNodeExcerpt.getAttributes().getNamedItem(ROOT).setNodeValue(root);
- idNodeExcerpt.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
- }
-
- }
-
- // Element temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode,
- // measureExport.getHQMFXmlProcessor());
- Element temporallyRelatedInfoNode = null;
- if (!FULFILLS.equalsIgnoreCase(relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
- temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode, measureExport.getHqmfXmlProcessor());
- } else {
- temporallyRelatedInfoNode = measureExport.getHqmfXmlProcessor().getOriginalDoc()
- .createElement(OUTBOUND_RELATIONSHIP);
- temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
- }
- handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
- Node firstChild = entryNode.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
- firstChild = firstChild.getNextSibling();
- }
- NodeList outBoundList = ((Element) firstChild).getElementsByTagName(OUTBOUND_RELATIONSHIP);
- if (outBoundList != null && outBoundList.getLength() > 0) {
- Node outBound = outBoundList.item(0);
- firstChild.insertBefore(temporallyRelatedInfoNode, outBound);
- } else {
- NodeList excerptList = ((Element) firstChild).getElementsByTagName(EXCERPT);
- if (excerptList != null && excerptList.getLength() > 0) {
- Node excerptNode = excerptList.item(0);
- firstChild.insertBefore(temporallyRelatedInfoNode, excerptNode);
- } else {
- firstChild.appendChild(temporallyRelatedInfoNode);
- }
- }
- dataCriteriaSectionElem.appendChild(entryNode);
- }
- /*
- * else{ Comment commnt = measureExport.getHQMFXmlProcessor().getOriginalDoc().
- * createComment("CHECK:Could not find an entry for functionalOp:"+lhsNode.
- * getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- * dataCriteriaSectionElem.appendChild(commnt); }
- */
- return entryNode;
- }
-
- /**
- * Find node.
- *
- * @param criteriaNodeInEntry
- * the criteria node in entry
- * @param nodeName
- * the node name
- * @return idNode
- */
- private Node findNode(Node criteriaNodeInEntry, String nodeName) {
- Node idNode = null;
- for (int i = 0; i < criteriaNodeInEntry.getChildNodes().getLength(); i++) {
- Node childNode = criteriaNodeInEntry.getChildNodes().item(i);
- String childNodeName = childNode.getNodeName();
- if (childNodeName.contains("Criteria")) {
- NodeList criteriaChildNodes = childNode.getChildNodes();
- for (int j = 0; j < criteriaChildNodes.getLength(); j++) {
- Node criteriaChildNode = criteriaChildNodes.item(j);
- if (nodeName.equalsIgnoreCase(criteriaChildNode.getNodeName())) {
- idNode = criteriaChildNode;
- break;
- }
- }
- break;
- }
- }
- return idNode;
- }
-
- /**
- * Gets the rel op lhs subtree.
- *
- * @param relOpNode
- * the rel op node
- * @param dataCriteriaSectionElem
- * the data criteria section elem
- * @param lhsNode
- * the lhs node
- * @param rhsNode
- * the rhs node
- * @param clauseName
- * the clause name
- * @return the rel op lhs subtree
- */
- private Node getrelOpLHSSubtree(Node relOpNode, Node dataCriteriaSectionElem, Node lhsNode, Node rhsNode,
- String clauseName) {
-
- try {
- String subTreeUUID = lhsNode.getAttributes().getNamedItem(ID).getNodeValue();
- String root = subTreeUUID;
-
- Node relOpParentNode = relOpNode.getParentNode();
-
- String xpath = "/measure/subTreeLookUp/subTree[@uuid='" + subTreeUUID + "']";
- Node subTreeNode = measureExport.getSimpleXmlProcessor()
- .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
- if (subTreeNode != null) {
- /**
- * Check if the Clause has already been generated. If it is not generated yet,
- * then generate it by calling the 'generateSubTreeXML' method.
- */
-
- if (!subTreeNodeMap.containsKey(subTreeUUID)) {
- generateSubTreeXML(subTreeNode, false);
- }
- String isQdmVariable = subTreeNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
- Node firstChild = subTreeNode.getFirstChild();
- String firstChildName = firstChild.getNodeName();
-
- String ext = StringUtils
- .deleteWhitespace(firstChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- if (FUNCTIONAL_OP.equals(firstChildName) || RELATIONAL_OP.equals(firstChildName)
- || SET_OP.equals(firstChildName)) {
- ext += "_" + firstChild.getAttributes().getNamedItem(UUID).getNodeValue();
- }
-
- if (ELEMENT_REF.equals(firstChildName)) {
- ext = getElementRefExt(firstChild, measureExport.getSimpleXmlProcessor());
- } else if (FUNCTIONAL_OP.equals(firstChildName)) {
- if (firstChild.getFirstChild() != null) {
- Node functionChild = firstChild.getFirstChild();
- if (functionChild != null) {
- if (functionChild.getNodeName().equalsIgnoreCase(SUB_TREE_REF)) {
- ext = functionChild.getAttributes().getNamedItem(ID).getNodeValue();
- } else if (functionChild.getNodeName().equalsIgnoreCase(ELEMENT_REF)) {
- ext = getElementRefExt(functionChild, measureExport.getSimpleXmlProcessor());
- } else {
- ext = StringUtils
- .deleteWhitespace(functionChild.getAttributes().getNamedItem(DISPLAY_NAME)
- .getNodeValue() + "_"
- + functionChild.getAttributes().getNamedItem(UUID).getNodeValue())
- .replaceAll(":", "_");
- }
- }
- }
- }
- if (TRUE.equalsIgnoreCase(isQdmVariable)) {
- String occText = null;
- // Handled Occurrence Of QDM Variable.
- if (subTreeNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- occText = "occ" + subTreeNode.getAttributes().getNamedItem("instance").getNodeValue() + "of_";
- }
- if (occText != null) {
- ext = occText + "qdm_var_" + ext;
- } else {
- ext = "qdm_var_" + ext;
- }
- }
-
- Node idNodeQDM = measureExport.getHqmfXmlProcessor().findNode(
- measureExport.getHqmfXmlProcessor().getOriginalDoc(),
- "//entry/*/id[@root='" + root + "'][@extension=\"" + ext + "\"]");
- if (idNodeQDM != null) {
- String newExt = StringUtils
- .deleteWhitespace(relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue() + "_"
- + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
- if (relOpParentNode != null && SUB_TREE.equals(relOpParentNode.getNodeName())) {
- root = relOpParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
- Node qdmVarNode = relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE);
- if (qdmVarNode != null) {
- String isQdmVar = relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
- if (TRUE.equalsIgnoreCase(isQdmVar)) {
- String occText = null;
- // Handled Occurrence Of QDM Variable.
- if (relOpParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- occText = "occ"
- + relOpParentNode.getAttributes().getNamedItem("instance").getNodeValue()
- + "of_";
- }
- if (occText != null) {
- newExt = occText + "qdm_var_" + newExt;
- } else {
- newExt = "qdm_var_" + newExt;
- }
- }
- }
- } else {
- Node tempParentNode = checkIfParentSubTree(relOpParentNode);
- if (tempParentNode != null) {
- root = tempParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
- }
- }
-
- Node parent = idNodeQDM.getParentNode();
- Node isOcc = subTreeNode.getAttributes().getNamedItem(INSTANCE_OF);
- Node newEntryNode = null;
-
- if (TRUE.equals(isQdmVariable) && isOcc == null) {
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
- // creating Entry Tag
- Element entryElem = hqmfXmlProcessor.getOriginalDoc().createElement(ENTRY);
- entryElem.setAttribute(TYPE_CODE, "DRIV");
- // create empty grouperCriteria
- Node grouperElem = generateEmptyGrouper(hqmfXmlProcessor, root, newExt);
-
- // generate outboundRelationship
- Element outboundRelElem = generateEmptyOutboundElem(hqmfXmlProcessor);
-
- NamedNodeMap attribMap = parent.getAttributes();
- String classCode = attribMap.getNamedItem(CLASS_CODE).getNodeValue();
- String moodCode = attribMap.getNamedItem(MOOD_CODE).getNodeValue();
-
- // create criteriaRef
- Element criteriaReference = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
- criteriaReference.setAttribute(CLASS_CODE, classCode);
- criteriaReference.setAttribute(MOOD_CODE, moodCode);
-
- Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- id.setAttribute(ROOT, subTreeUUID);
- id.setAttribute(EXTENSION, ext);
-
- criteriaReference.appendChild(id);
- outboundRelElem.appendChild(criteriaReference);
-
- Element localVarElem = hqmfXmlProcessor.getOriginalDoc().createElement(LOCAL_VARIABLE_NAME);
- localVarElem.setAttribute(VALUE, ext);
- entryElem.appendChild(localVarElem);
-
- grouperElem.appendChild(outboundRelElem);
- entryElem.appendChild(grouperElem);
-
- newEntryNode = entryElem;
- } else {
- Node entryNodeForSubTree = idNodeQDM.getParentNode().getParentNode();
- newEntryNode = entryNodeForSubTree.cloneNode(true);
-
- NodeList idChildNodeList = ((Element) newEntryNode).getElementsByTagName(ID);
- if (idChildNodeList != null && idChildNodeList.getLength() > 0) {
- Node idChildNode = idChildNodeList.item(0);
- idChildNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(newExt);
- idChildNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
- }
- }
-
- // Element temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode,
- // measureExport.getHQMFXmlProcessor());
- Element temporallyRelatedInfoNode = null;
- if (!FULFILLS.equalsIgnoreCase(relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
- temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode,
- measureExport.getHqmfXmlProcessor());
- } else {
- temporallyRelatedInfoNode = measureExport.getHqmfXmlProcessor().getOriginalDoc()
- .createElement(OUTBOUND_RELATIONSHIP);
- temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
- }
-
- handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
-
- Node firstNode = newEntryNode.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(firstNode.getNodeName())) {
- firstNode = firstNode.getNextSibling();
- }
- NodeList outBoundList = ((Element) firstNode).getElementsByTagName(OUTBOUND_RELATIONSHIP);
- if (outBoundList != null && outBoundList.getLength() > 0) {
- Node outBound = outBoundList.item(0);
- firstNode.insertBefore(temporallyRelatedInfoNode, outBound);
- } else {
- firstNode.appendChild(temporallyRelatedInfoNode);
- }
- // Entry for Functional Op.
- if (FUNCTIONAL_OP.equals(relOpParentNode.getNodeName())) {
- Element excerptElement = generateExcerptEntryForFunctionalNode(relOpParentNode, lhsNode,
- measureExport.getHqmfXmlProcessor(), firstNode.getParentNode());
- if (excerptElement != null) {
- // Comment comment =
- // measureExport.getHQMFXmlProcessor().getOriginalDoc().createComment("entry for
- // "+relOpParentNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- // firstNode.appendChild(comment);
- firstNode.appendChild(excerptElement);
- }
- }
- // create comment node
- // Comment comment =
- // measureExport.getHQMFXmlProcessor().getOriginalDoc().createComment("entry for
- // "+relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- // dataCriteriaSectionElem.appendChild(comment);
- dataCriteriaSectionElem.appendChild(newEntryNode);
- return newEntryNode;
-
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
- /**
- * Gets the rel op lhs set op.
- *
- * @param relOpNode
- * the rel op node
- * @param dataCriteriaSectionElem
- * the data criteria section elem
- * @param lhsNode
- * the lhs node
- * @param rhsNode
- * the rhs node
- * @param clauseName
- * the clause name
- * @return the rel op lhs set op
- */
- private Node getrelOpLHSSetOp(Node relOpNode, Node dataCriteriaSectionElem, Node lhsNode, Node rhsNode,
- String clauseName) {
-
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
- // Node relOpParentNode = relOpNode.getParentNode();
-
- try {
- Node setOpEntryNode = generateSetOpHQMF(lhsNode, dataCriteriaSectionElem, clauseName);
- // Element temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode,
- // hqmfXmlProcessor);
- Node relOpParentNode = checkIfSubTree(relOpNode.getParentNode());
- if (relOpParentNode != null) {
- NodeList idChildNodeList = ((Element) setOpEntryNode).getElementsByTagName(ID);
- if (idChildNodeList != null && idChildNodeList.getLength() > 0) {
- Node idChildNode = idChildNodeList.item(0);
- String root = relOpParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
- String ext = StringUtils
- .deleteWhitespace(relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue() + "_"
- + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
- if (relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
- String isQdmVariable = relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE)
- .getNodeValue();
- if (TRUE.equalsIgnoreCase(isQdmVariable)) {
- String occText = null;
- // Handled Occurrence Of QDM Variable.
- if (relOpParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- occText = "occ" + relOpParentNode.getAttributes().getNamedItem(INSTANCE).getNodeValue()
- + "of_";
- }
- if (occText != null) {
- ext = occText + "qdm_var_" + ext;
- } else {
- ext = "qdm_var_" + ext;
- }
- }
-
- }
- idChildNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
- idChildNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
- }
- }
- Element temporallyRelatedInfoNode = null;
- if (!FULFILLS.equalsIgnoreCase(relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
- temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode, hqmfXmlProcessor);
- } else {
- temporallyRelatedInfoNode = hqmfXmlProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
- temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
- }
- handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
-
- Node firstChild = setOpEntryNode.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
- firstChild = firstChild.getNextSibling();
- }
- NodeList outBoundList = ((Element) firstChild).getElementsByTagName(OUTBOUND_RELATIONSHIP);
- if (outBoundList != null && outBoundList.getLength() > 0) {
- Node outBound = outBoundList.item(0);
- firstChild.insertBefore(temporallyRelatedInfoNode, outBound);
- } else {
- firstChild.appendChild(temporallyRelatedInfoNode);
- }
-
- // create comment node
- // Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("entry for
- // "+relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- // dataCriteriaSectionElem.appendChild(comment);
- dataCriteriaSectionElem.appendChild(setOpEntryNode);
- return setOpEntryNode;
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return null;
- }
-
- /**
- * Gets the rel op lhs rel op.
- *
- * @param relOpNode
- * the rel op node
- * @param dataCriteriaSectionElem
- * the data criteria section elem
- * @param lhsNode
- * the lhs node
- * @param rhsNode
- * the rhs node
- * @param clauseName
- * the clause name
- * @return the rel op lhs rel op
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node getrelOpLHSRelOp(Node relOpNode, Node dataCriteriaSectionElem, Node lhsNode, Node rhsNode,
- String clauseName) throws XPathExpressionException {
-
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
- // Node relOpParentNode = relOpNode.getParentNode();
-
- try {
- Node relOpEntryNode = generateRelOpHQMF(lhsNode, dataCriteriaSectionElem, clauseName);
- /*
- * Element temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode,
- * hqmfXmlProcessor);
- */
-
- Node relOpParentNode = checkIfSubTree(relOpNode.getParentNode());
-
- if (relOpParentNode != null) {
- NodeList idChildNodeList = ((Element) relOpEntryNode).getElementsByTagName(ID);
-
- if (idChildNodeList != null && idChildNodeList.getLength() > 0) {
- Node idChildNode = idChildNodeList.item(0);
- String root = relOpParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
- String ext = StringUtils
- .deleteWhitespace(relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue() + "_"
- + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
- if (relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
- String isQdmVariable = relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE)
- .getNodeValue();
- if (TRUE.equalsIgnoreCase(isQdmVariable)) {
- String occText = null;
- // Handled Occurrence Of QDM Variable.
- if (relOpParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- occText = "occ"
- + relOpParentNode.getAttributes().getNamedItem("instance").getNodeValue()
- + "of_";
- }
- if (occText != null) {
- ext = occText + "qdm_var_" + ext;
- } else {
- ext = "qdm_var_" + ext;
- }
- }
- }
- idChildNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
- idChildNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
- }
- }
- Element temporallyRelatedInfoNode = null;
- if (!FULFILLS.equalsIgnoreCase(relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
- temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode, hqmfXmlProcessor);
- } else {
- temporallyRelatedInfoNode = hqmfXmlProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
- temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
- }
-
- handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
-
- Node firstChild = relOpEntryNode.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
- firstChild = firstChild.getNextSibling();
- }
- NodeList outBoundList = ((Element) firstChild).getElementsByTagName(OUTBOUND_RELATIONSHIP);
- if (outBoundList != null && outBoundList.getLength() > 0) {
- Node outBound = outBoundList.item(0);
- firstChild.insertBefore(temporallyRelatedInfoNode, outBound);
- } else {
- firstChild.appendChild(temporallyRelatedInfoNode);
- }
- // create comment node
- // Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("entry for
- // "+relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- // dataCriteriaSectionElem.appendChild(comment);
- dataCriteriaSectionElem.appendChild(relOpEntryNode);
- return relOpEntryNode;
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return null;
- }
-
- /**
- * Gets the rel op lhsqdm.
- *
- * @param relOpNode
- * the rel op node
- * @param dataCriteriaSectionElem
- * the data criteria section elem
- * @param lhsNode
- * the lhs node
- * @param rhsNode
- * the rhs node
- * @param clauseName
- * the clause name
- * @return the rel op lhsqdm
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node getrelOpLHSQDM(Node relOpNode, Node dataCriteriaSectionElem, Node lhsNode, Node rhsNode,
- String clauseName) throws XPathExpressionException {
-
- String ext = getElementRefExt(lhsNode, measureExport.getSimpleXmlProcessor());
- String root = lhsNode.getAttributes().getNamedItem(ID).getNodeValue();
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
- Node relOpParentNode = relOpNode.getParentNode();
- Element excerptElement = null;
- Node idNodeQDM = hqmfXmlProcessor.findNode(hqmfXmlProcessor.getOriginalDoc(),
- "//entry/*/id[@root='" + root + "'][@extension=\"" + ext + "\"]");
-
- if (relOpParentNode != null && idNodeQDM != null) {
- ext = StringUtils.deleteWhitespace(relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue() + "_"
- + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
- Node subTreeParentNode = checkIfSubTree(relOpParentNode);
- if (subTreeParentNode != null) {
- root = subTreeParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
- if (subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
- String isQdmVariable = subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
- if (TRUE.equalsIgnoreCase(isQdmVariable)) {
- String occText = null;
- // Handled Occurrence Of QDM Variable.
- if (relOpParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
- occText = "occ" + relOpParentNode.getAttributes().getNamedItem("instance").getNodeValue()
- + "of_";
- }
- if (occText != null) {
- ext = occText + "qdm_var_" + ext;
- } else {
- ext = "qdm_var_" + ext;
- }
- }
- }
- }
-
- Node entryNodeForElementRef = idNodeQDM.getParentNode().getParentNode();
- Node clonedEntryNodeForElementRef = entryNodeForElementRef.cloneNode(true);
- /*
- * Element localVarName = (Element)
- * ((Element)clonedEntryNodeForElementRef).getElementsByTagName(
- * "localVariableName").item(0);
- * localVarName.setAttribute(VALUE,findSubTreeDisplayName(lhsNode));
- */
- NodeList idChildNodeList = ((Element) clonedEntryNodeForElementRef).getElementsByTagName(ID);
- updateLocalVar(clonedEntryNodeForElementRef, ext);
- if (idChildNodeList != null && idChildNodeList.getLength() > 0) {
- Node idChildNode = idChildNodeList.item(0);
- idChildNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
- idChildNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
- }
-
- // Added logic to show qdm_variable in extension if clause is of qdm variable
- // type.
- if (FUNCTIONAL_OP.equals(relOpParentNode.getNodeName())) {
- excerptElement = generateExcerptEntryForFunctionalNode(relOpParentNode, lhsNode, hqmfXmlProcessor,
- clonedEntryNodeForElementRef);
- }
- Element temporallyRelatedInfoNode = null;
- if (!FULFILLS.equalsIgnoreCase(relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
- temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode, hqmfXmlProcessor);
- generateTemporalAttribute(hqmfXmlProcessor, lhsNode, temporallyRelatedInfoNode,
- clonedEntryNodeForElementRef, true);
- } else {
- temporallyRelatedInfoNode = hqmfXmlProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
- temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
- }
- handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
- Node firstChild = clonedEntryNodeForElementRef.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
- firstChild = firstChild.getNextSibling();
- }
- NodeList outBoundList = ((Element) firstChild).getElementsByTagName(OUTBOUND_RELATIONSHIP);
- if (outBoundList != null && outBoundList.getLength() > 0) {
- Node outBound = outBoundList.item(0);
- firstChild.insertBefore(temporallyRelatedInfoNode, outBound);
- } else {
- firstChild.appendChild(temporallyRelatedInfoNode);
- }
-
- if (excerptElement != null) {
- // Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("excerpt
- // for
- // "+relOpParentNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- // firstChild.appendChild(comment);
- firstChild.appendChild(excerptElement);
- }
- // create comment node
- // Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("entry for
- // "+relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- // dataCriteriaSectionElem.appendChild(comment);
- dataCriteriaSectionElem.appendChild(clonedEntryNodeForElementRef);
- return clonedEntryNodeForElementRef;
- }
- return null;
- }
-
- /**
- * Handle rel op rhs.
- *
- * @param rhsNode
- * the rhs node
- * @param temporallyRelatedInfoNode
- * the temporally related info node
- * @param clauseName
- * the clause name
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private void handleRelOpRHS(Node rhsNode, Element temporallyRelatedInfoNode, String clauseName) throws XPathExpressionException {
-
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
- String rhsName = rhsNode.getNodeName();
- Node dataCritSectionNode = hqmfXmlProcessor.findNode(temporallyRelatedInfoNode.getOwnerDocument(),
- "//dataCriteriaSection");
-
- if (ELEMENT_REF.equals(rhsName)) {
- Node entryNode = generateCritRefElementRef(temporallyRelatedInfoNode, rhsNode,
- measureExport.getHqmfXmlProcessor());
- generateTemporalAttribute(hqmfXmlProcessor, rhsNode, temporallyRelatedInfoNode, entryNode, false);
- } else if (SUB_TREE_REF.equals(rhsName)) {
- generateCritRefForNode(temporallyRelatedInfoNode, rhsNode);
- } else {
- switch (rhsName) {
- case SET_OP:
- generateCritRefSetOp(dataCritSectionNode, hqmfXmlProcessor, rhsNode, temporallyRelatedInfoNode,
- clauseName);
- break;
- case RELATIONAL_OP:
- generateRelOpHQMF(rhsNode, temporallyRelatedInfoNode, clauseName);
- Node lastChild = temporallyRelatedInfoNode.getLastChild();
- if (lastChild.getNodeName().equals(ENTRY)) {
- temporallyRelatedInfoNode.removeChild(lastChild);
-
- Node fChild = lastChild.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(fChild.getNodeName())) {
- fChild = fChild.getNextSibling();
- }
-
- Node criteriaNode = fChild;
- // temporallyRelatedInfoNode.appendChild(criteriaNode);
- dataCritSectionNode.appendChild(lastChild);
- // create criteriaRef
- Element criteriaReference = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
- criteriaReference.setAttribute(CLASS_CODE,
- criteriaNode.getAttributes().getNamedItem(CLASS_CODE).getNodeValue());
- criteriaReference.setAttribute(MOOD_CODE,
- criteriaNode.getAttributes().getNamedItem(MOOD_CODE).getNodeValue());
-
- NodeList childNodeList = criteriaNode.getChildNodes();
- for (int i = 0; i < childNodeList.getLength(); i++) {
- Node childNode = childNodeList.item(i);
- if (childNode.getNodeName().equalsIgnoreCase(ID)) {
- Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- id.setAttribute(ROOT, childNode.getAttributes().getNamedItem(ROOT).getNodeValue());
- id.setAttribute(EXTENSION,
- childNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
- criteriaReference.appendChild(id);
- temporallyRelatedInfoNode.appendChild(criteriaReference);
- break;
- }
- }
-
- NodeList childTemporalNodeList = ((Element) criteriaNode)
- .getElementsByTagName("temporallyRelatedInformation");
- if (childTemporalNodeList != null && childTemporalNodeList.getLength() > 0) {
- Node childTemporalNode = childTemporalNodeList.item(0);
- Node temporalInfoNode = childTemporalNode.getFirstChild();
- // find sourceAttribute
- NodeList childs = temporalInfoNode.getChildNodes();
- for (int c = 0; c < childs.getLength(); c++) {
- Node child = childs.item(c);
- String childName = child.getNodeName();
- if ("qdm:sourceAttribute".equals(childName)) {
- Node cloneAttNode = child.cloneNode(true);
- temporallyRelatedInfoNode.getFirstChild().appendChild(cloneAttNode);
- hqmfXmlProcessor.getOriginalDoc().renameNode(cloneAttNode, "", "qdm:targetAttribute");
- break;
- }
- }
- }
- }
- break;
- case FUNCTIONAL_OP:
- Node entryNode = generateFunctionalOpHQMF(rhsNode, (Element) dataCritSectionNode, clauseName);
- if (entryNode != null && entryNode.getNodeName().equals(ENTRY)) {
- Node fChild = entryNode.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(fChild.getNodeName())) {
- fChild = fChild.getNextSibling();
- }
- // create criteriaRef
- Element criteriaReference = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
- criteriaReference.setAttribute(CLASS_CODE,
- fChild.getAttributes().getNamedItem(CLASS_CODE).getNodeValue());
- criteriaReference.setAttribute(MOOD_CODE,
- fChild.getAttributes().getNamedItem(MOOD_CODE).getNodeValue());
- NodeList childNodeList = fChild.getChildNodes();
- for (int i = 0; i < childNodeList.getLength(); i++) {
- Node childNode = childNodeList.item(i);
- if (childNode.getNodeName().equalsIgnoreCase(ID)) {
- Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- id.setAttribute(ROOT, childNode.getAttributes().getNamedItem(ROOT).getNodeValue());
- id.setAttribute(EXTENSION,
- childNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
- criteriaReference.appendChild(id);
- temporallyRelatedInfoNode.appendChild(criteriaReference);
- break;
- }
- }
- }
- break;
- default:
- // Dont do anything
- break;
- }
- }
- }
-
- /**
- * Generate temporal attribute.
- *
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @param rhsNode
- * the rhs node
- * @param temporallyRelatedInfoNode
- * the temporally related info node
- * @param entryNode
- * the entry node
- * @param isSource
- * the is source
- * @return the node
- */
- private Node generateTemporalAttribute(XmlProcessor hqmfXmlProcessor, Node rhsNode,
- Element temporallyRelatedInfoNode, Node entryNode, boolean isSource) {
- if (entryNode != null) {
- Element entryElement = (Element) entryNode;
-
- if (!rhsNode.hasChildNodes()) {
- return null;
- } else {
- Node child = rhsNode.getFirstChild();
- if (!"attribute".equals(child.getNodeName())) {
- return null;
- }
-
- String value = child.getAttributes().getNamedItem(NAME).getNodeValue();
- List validAttribNames = new ArrayList<>();
- validAttribNames.add("incision datetime");
- validAttribNames.add("facility location arrival datetime");
- validAttribNames.add("facility location departure datetime");
- validAttribNames.add("recorded datetime");
- validAttribNames.add("signed datetime");
- validAttribNames.add("start datetime");
- validAttribNames.add("stop datetime");
- if (!validAttribNames.contains(value)) {
- return null;
- }
- if ("start datetime".equals(value) || "stop datetime".equals(value)) {
- String dataType = rhsNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- if (!dataType.endsWith("Order")) {
- return null;
- }
- }
-
- // create sourceAttribute/targetAttribute
- String attribName = "qdm:sourceAttribute";
- if (!isSource) {
- attribName = "qdm:targetAttribute";
- }
- Element attribute = hqmfXmlProcessor.getOriginalDoc().createElement(attribName);
- attribute.setAttribute(NAME, value);
- String boundValue = "effectiveTime.low";
-
- if ("incision datetime".equals(value)) {
- NodeList nodeList = entryElement.getElementsByTagName(OUTBOUND_RELATIONSHIP);
- if (nodeList != null && nodeList.getLength() > 0) {
- // Always get the last outBoundRelationShip tag, because this is the one
- // which will represent the
- Node outBoundNode = nodeList.item(nodeList.getLength() - 1);
- Node criteriaNode = outBoundNode.getFirstChild();
-
- NodeList idNodeList = ((Element) criteriaNode).getElementsByTagName(ID);
- if (idNodeList != null && idNodeList.getLength() > 0) {
- Node idNode = idNodeList.item(0);
- Element qdmId = hqmfXmlProcessor.getOriginalDoc().createElement("qdm:id");
- qdmId.setAttribute(ROOT, idNode.getAttributes().getNamedItem(ROOT).getNodeValue());
- qdmId.setAttribute(EXTENSION,
- idNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
- attribute.appendChild(qdmId);
- }
- }
- } else {
- NodeList nodeList = entryElement.getElementsByTagName(PARTICIPATION);
- if (nodeList != null && nodeList.getLength() > 0) {
- // Always get the last outBoundRelationShip tag, because this is the one
- // which will represent the
- Node participationNode = nodeList.item(nodeList.getLength() - 1);
- Node roleNode = ((Element) participationNode).getElementsByTagName(ROLE).item(0);
- NodeList idNodeList = ((Element) roleNode).getElementsByTagName(ID);
- if (idNodeList != null && idNodeList.getLength() > 0) {
- Node idNode = idNodeList.item(0);
- Node itemNode = idNode.getFirstChild();
- Element qdmId = hqmfXmlProcessor.getOriginalDoc().createElement("qdm:id");
- qdmId.setAttribute(ROOT, itemNode.getAttributes().getNamedItem(ROOT).getNodeValue());
- qdmId.setAttribute(EXTENSION,
- itemNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
- attribute.appendChild(qdmId);
-
- if ("facility location departure datetime".equals(value) || "stop datetime".equals(value)
- || "signed datetime".equals(value) || "recorded datetime".equals(value)) {
- boundValue = "effectiveTime.high";
- }
- }
- }
- }
- attribute.setAttribute("bound", boundValue);
- Node temporalInformation = temporallyRelatedInfoNode.getFirstChild();
- if (temporallyRelatedInfoNode.getElementsByTagName("qdm:delta").item(0) != null) {
- Node qdmDeltaNode = temporallyRelatedInfoNode.getElementsByTagName("qdm:delta").item(0);
- temporalInformation.insertBefore(attribute, qdmDeltaNode);
- } else {
- temporalInformation.appendChild(attribute);
- }
-
- return attribute;
- }
- }
- return null;
- }
-
- /**
- * Generate Excerpt for Functional Op used with timing/Relationship.
- *
- * @param functionalOpNode
- * the functional op node
- * @param lhsNode
- * the lhs node
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @param clonedNodeToAppendExcerpt
- * the cloned node to append excerpt
- * @return the element
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Element generateExcerptEntryForFunctionalNode(Node functionalOpNode, Node lhsNode,
- XmlProcessor hqmfXmlProcessor, Node clonedNodeToAppendExcerpt) throws XPathExpressionException {
- Element excerptElement = hqmfXmlProcessor.getOriginalDoc().createElement(EXCERPT);
- String functionalOpName = functionalOpNode.getAttributes().getNamedItem(TYPE).getNodeValue();
- Element criteriaElement = null;
- if (FUNCTIONAL_OPS_NON_SUBSET.containsKey(functionalOpName)) {
- Element sequenceElement = hqmfXmlProcessor.getOriginalDoc().createElement(SEQUENCE_NUMBER);
- sequenceElement.setAttribute(VALUE, FUNCTIONAL_OPS_NON_SUBSET.get(functionalOpName.toUpperCase()));
- excerptElement.appendChild(sequenceElement);
- if (clonedNodeToAppendExcerpt != null) {
- if (clonedNodeToAppendExcerpt.getNodeName().contains(GROUPER)) {
- criteriaElement = generateCriteriaElementForSetOpExcerpt(hqmfXmlProcessor,
- clonedNodeToAppendExcerpt);
- excerptElement.appendChild(criteriaElement);
- } else {
- NodeList entryChildNodes = clonedNodeToAppendExcerpt.getChildNodes();
- criteriaElement = generateCriteriaElementForExcerpt(hqmfXmlProcessor, entryChildNodes);
- excerptElement.appendChild(criteriaElement);
- }
- }
- } else if (FUNCTIONAL_OPS_SUBSET.containsKey(functionalOpName)) {
- NamedNodeMap attributeMap = functionalOpNode.getAttributes();
- if (clonedNodeToAppendExcerpt.getNodeName().contains(GROUPER)) {
- criteriaElement = generateCriteriaElementForSetOpExcerpt(hqmfXmlProcessor, clonedNodeToAppendExcerpt);
- excerptElement.appendChild(criteriaElement);
- } else {
- NodeList entryChildNodes = clonedNodeToAppendExcerpt.getChildNodes();
- criteriaElement = generateCriteriaElementForExcerpt(hqmfXmlProcessor, entryChildNodes);
- excerptElement.appendChild(criteriaElement);
- }
- if (clonedNodeToAppendExcerpt != null) {
-
- if ("count".equalsIgnoreCase(functionalOpName)) {
-
- createRepeatNumberTagForCountFuncttion(hqmfXmlProcessor, attributeMap, criteriaElement);
- Element qdmSubSetElement = hqmfXmlProcessor.getOriginalDoc().createElement("qdm:subsetCode");
- qdmSubSetElement.setAttribute(CODE, FUNCTIONAL_OPS_SUBSET.get(functionalOpName.toUpperCase()));
- Element subSetCodeElement = hqmfXmlProcessor.getOriginalDoc().createElement("subsetCode");
- subSetCodeElement.setAttribute(CODE, "SUM");
-
- excerptElement.appendChild(subSetCodeElement);
- excerptElement.appendChild(qdmSubSetElement);
- excerptElement.appendChild(criteriaElement);
- } else {
- if (attributeMap.getNamedItem(OPERATOR_TYPE) != null && lhsNode != null) {
- String lhsNodeType = lhsNode.getNodeName();
- if (ELEMENT_REF.equalsIgnoreCase(lhsNodeType)) {
- String qdmUUID = lhsNode.getAttributes().getNamedItem(ID).getNodeValue();
- String xPath = "/measure/elementLookUp/qdm[@uuid ='" + qdmUUID + "']";
- Node node = measureExport.getSimpleXmlProcessor()
- .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xPath);
- if (node != null && lhsNode.hasChildNodes()) {
- Node qdmNode = node.cloneNode(true);
- Node attributeNode = lhsNode.getFirstChild().cloneNode(true);
- attributeNode.setUserData(ATTRIBUTE_NAME,
- attributeNode.getAttributes().getNamedItem(NAME).getNodeValue(), null);
- attributeNode.setUserData(ATTRIBUTE_MODE,
- attributeMap.getNamedItem(OPERATOR_TYPE).getNodeValue(), null);
- attributeNode.setUserData(ATTRIBUTE_UUID,
- attributeNode.getAttributes().getNamedItem(ATTR_UUID).getNodeValue(), null);
- Element attributeElement = (Element) attributeNode;
-
- attributeElement.setAttribute(MODE,
- attributeMap.getNamedItem(OPERATOR_TYPE).getNodeValue());
- if (attributeElement.getAttributes().getNamedItem(ATTR_DATE) != null) {
- attributeNode.setUserData(ATTRIBUTE_DATE,
- attributeMap.getNamedItem(QUANTITY).getNodeValue(), null);
- } else {
- attributeElement.setAttribute(COMPARISON_VALUE,
- attributeMap.getNamedItem(QUANTITY).getNodeValue());
- }
- if (attributeMap.getNamedItem(UNIT) != null) {
- attributeElement.setAttribute(UNIT, attributeMap.getNamedItem(UNIT).getNodeValue());
- } else {
- if (attributeElement.getAttributes().getNamedItem(UNIT) != null) {
- attributeElement.removeAttribute(UNIT);
- }
- }
- attributeNode = attributeElement;
-
- // HQMFDataCriteriaElementGenerator hqmfDataCriteriaElementGenerator = new
- // HQMFDataCriteriaElementGenerator();
- // hqmfDataCriteriaElementGenerator.generateAttributeTagForFunctionalOp(measureExport,qdmNode,
- // criteriaElement, attributeNode);
- HQMFAttributeGenerator attributeGenerator = new HQMFAttributeGenerator();
- attributeGenerator.generateAttributeTagForFunctionalOp(measureExport, qdmNode,
- criteriaElement, attributeNode);
- }
- }
- }
- Element qdmSubSetElement = hqmfXmlProcessor.getOriginalDoc().createElement("qdm:subsetCode");
- qdmSubSetElement.setAttribute(CODE, FUNCTIONAL_OPS_SUBSET.get(functionalOpName.toUpperCase()));
-
- if ("sum".equalsIgnoreCase(functionalOpName)) {
- Element subSetCodeElement = hqmfXmlProcessor.getOriginalDoc().createElement("subsetCode");
- subSetCodeElement.setAttribute(CODE, "SUM");
- excerptElement.appendChild(subSetCodeElement);
- }
- excerptElement.appendChild(qdmSubSetElement);
- excerptElement.appendChild(criteriaElement);
- }
- }
- }
-
- return excerptElement;
- }
-
- /**
- * Check if parent sub tree.
- *
- * @param parentNode
- * the parent node
- * @return the node
- */
- protected Node checkIfParentSubTree(Node parentNode) {
- Node returnNode = null;
- if (parentNode != null) {
- String parentName = parentNode.getNodeName();
- if (SUB_TREE.equals(parentName)) {
- returnNode = parentNode;
- } else {
- returnNode = checkIfParentSubTree(parentNode.getParentNode());
- }
- }
-
- return returnNode;
- }
-
- /**
- * Generates RepeatNumber tags for Count Function.
- *
- * @param hqmfXmlProcessor
- * - XmlProcessor.
- * @param attributeMap
- * - NamedNodeMap.
- * @param criteriaElement
- * - Element.
- */
- private void createRepeatNumberTagForCountFuncttion(XmlProcessor hqmfXmlProcessor, NamedNodeMap attributeMap,
- Element criteriaElement) {
- Element repeatNumberElement = hqmfXmlProcessor.getOriginalDoc().createElement("repeatNumber");
- Element lowNode = hqmfXmlProcessor.getOriginalDoc().createElement("low");
- Element highNode = hqmfXmlProcessor.getOriginalDoc().createElement("high");
- if (attributeMap.getNamedItem(OPERATOR_TYPE) != null) {
- String operatorType = attributeMap.getNamedItem(OPERATOR_TYPE).getNodeValue();
- String quantity = attributeMap.getNamedItem(QUANTITY).getNodeValue();
- if (operatorType.startsWith("Greater Than")) {
- lowNode.setAttribute(VALUE, quantity);
- highNode.setAttribute(NULL_FLAVOR, "PINF");
- if ("Greater Than or Equal To".equals(operatorType)) {
- repeatNumberElement.setAttribute("lowClosed", TRUE);
- }
- } else if ("Equal To".equals(operatorType)) {
- repeatNumberElement.setAttribute("lowClosed", TRUE);
- repeatNumberElement.setAttribute("highClosed", TRUE);
- lowNode.setAttribute(VALUE, quantity);
- highNode.setAttribute(VALUE, quantity);
- } else if (operatorType.startsWith("Less Than")) {
- repeatNumberElement.setAttribute("lowClosed", TRUE);
- lowNode.setAttribute(VALUE, "0");
- highNode.setAttribute(VALUE, quantity);
- if ("Less Than or Equal To".equals(operatorType)) {
- repeatNumberElement.setAttribute("highClosed", TRUE);
- }
- }
- repeatNumberElement.appendChild(lowNode);
- repeatNumberElement.appendChild(highNode);
- criteriaElement.appendChild(repeatNumberElement);
- }
- }
-
- /**
- * Generate criteria element for excerpt.
- *
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @param entryChildNodes
- * the entry child nodes
- * @return the element
- */
- private Element generateCriteriaElementForExcerpt(XmlProcessor hqmfXmlProcessor, NodeList entryChildNodes) {
- Element criteriaElement = null;
- for (int i = 0; i < entryChildNodes.getLength(); i++) {
- Node childNode = entryChildNodes.item(i);
- String childNodeName = childNode.getNodeName();
- if (childNodeName.contains("Criteria")) {
- criteriaElement = hqmfXmlProcessor.getOriginalDoc().createElement(childNodeName);
- criteriaElement.setAttribute(CLASS_CODE,
- childNode.getAttributes().getNamedItem(CLASS_CODE).getNodeValue());
- criteriaElement.setAttribute(MOOD_CODE,
- childNode.getAttributes().getNamedItem(MOOD_CODE).getNodeValue());
- NodeList criteriaChildNodes = childNode.getChildNodes();
- for (int j = 0; j < criteriaChildNodes.getLength(); j++) {
- Node criteriaChildNode = criteriaChildNodes.item(j);
- if (ID.equalsIgnoreCase(criteriaChildNode.getNodeName())) {
- Element idElement = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- idElement.setAttribute(ROOT,
- criteriaChildNode.getAttributes().getNamedItem(ROOT).getNodeValue());
- idElement.setAttribute(EXTENSION,
- criteriaChildNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
- criteriaElement.appendChild(idElement);
- break;
- }
- }
-
- break;
- }
- }
- return criteriaElement;
- }
-
- /**
- * Generate criteria element for set op excerpt.
- *
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @param clonedNodeToAppendExcerpt
- * the cloned node to append excerpt
- * @return the element
- */
- private Element generateCriteriaElementForSetOpExcerpt(XmlProcessor hqmfXmlProcessor,
- Node clonedNodeToAppendExcerpt) {
- Element criteriaElement = null;
- for (int i = 0; i < clonedNodeToAppendExcerpt.getChildNodes().getLength(); i++) {
- Node childNode = clonedNodeToAppendExcerpt.getChildNodes().item(i);
- if (ID.equalsIgnoreCase(childNode.getNodeName())) {
- Node criteriaNode = generateEmptyGrouper(hqmfXmlProcessor,
- childNode.getAttributes().getNamedItem(ROOT).getNodeValue(),
- childNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
- criteriaElement = (Element) criteriaNode;
- break;
- }
- }
- return criteriaElement;
- }
-
- /**
- * Creates the base temporal node.
- *
- * @param relOpNode
- * the rel op node
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @return the element
- */
- private Element createBaseTemporalNode(Node relOpNode, XmlProcessor hqmfXmlProcessor) {
-
- NamedNodeMap attribMap = relOpNode.getAttributes();
- Element temporallyRelatedInfoNode = hqmfXmlProcessor.getOriginalDoc()
- .createElement("temporallyRelatedInformation");
- temporallyRelatedInfoNode.setAttribute(TYPE_CODE, attribMap.getNamedItem(TYPE).getNodeValue().toUpperCase());
-
- Element temporalInfoNode = hqmfXmlProcessor.getOriginalDoc().createElement("qdm:temporalInformation");
- String precisionUnit = "min"; // use min by default
-
- if (attribMap.getNamedItem(OPERATOR_TYPE) != null) {
- String operatorType = attribMap.getNamedItem(OPERATOR_TYPE).getNodeValue();
- String quantity = attribMap.getNamedItem(QUANTITY).getNodeValue();
- String unit = attribMap.getNamedItem(UNIT).getNodeValue();
-
- if ("seconds".equals(unit)) {
- precisionUnit = "s";
- unit = "s";
- } else if ("hours".equals(unit)) {
- unit = "h";
- } else if ("minutes".equals(unit)) {
- unit = "min";
- } else {
- precisionUnit = "d";
- if ("days".equals(unit)) {
- unit = "d";
- } else if ("weeks".equals(unit)) {
- unit = "wk";
- } else if ("months".equals(unit)) {
- unit = "mo";
- } else if ("years".equals(unit)) {
- unit = "a";
- }
- }
-
- Element deltaNode = hqmfXmlProcessor.getOriginalDoc().createElement("qdm:delta");
- Element lowNode = hqmfXmlProcessor.getOriginalDoc().createElement("low");
- lowNode.setAttribute(UNIT, unit);
-
- Element highNode = hqmfXmlProcessor.getOriginalDoc().createElement("high");
- highNode.setAttribute(UNIT, unit);
-
- if (operatorType.startsWith("Greater Than")) {
- lowNode.setAttribute(VALUE, quantity);
- highNode.removeAttribute(UNIT);
- highNode.setAttribute(NULL_FLAVOR, "PINF");
- if ("Greater Than or Equal To".equals(operatorType)) {
- deltaNode.setAttribute("lowClosed", TRUE);
- }
- } else if ("Equal To".equals(operatorType)) {
- deltaNode.setAttribute("lowClosed", TRUE);
- deltaNode.setAttribute("highClosed", TRUE);
- lowNode.setAttribute(VALUE, quantity);
- highNode.setAttribute(VALUE, quantity);
- } else if (operatorType.startsWith("Less Than")) {
- deltaNode.setAttribute("lowClosed", TRUE);
- lowNode.setAttribute(VALUE, "0");
- highNode.setAttribute(VALUE, quantity);
- if ("Less Than or Equal To".equals(operatorType)) {
- deltaNode.setAttribute("highClosed", TRUE);
- }
- }
- deltaNode.appendChild(lowNode);
- deltaNode.appendChild(highNode);
- temporalInfoNode.appendChild(deltaNode);
- }
- temporalInfoNode.setAttribute("precisionUnit", precisionUnit);
- temporallyRelatedInfoNode.appendChild(temporalInfoNode);
- return temporallyRelatedInfoNode;
- }
-
- /**
- * Generate crit ref rel op.
- *
- * @param parentNode
- * the parent node
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @param childNode
- * the child node
- * @param outboundRelElem
- * the outbound rel elem
- * @param clauseName
- * the clause name
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private void generateCritRefRelOp(Node parentNode, XmlProcessor hqmfXmlProcessor, Node childNode,
- Node outboundRelElem, String clauseName) throws XPathExpressionException {
- Node relOpEntryNode = generateRelOpHQMF(childNode, parentNode, clauseName);
-
- if (relOpEntryNode != null) {
- Node idNode = getTagFromEntry(relOpEntryNode, ID);
- // Node critNode = relOpEntryNode.getFirstChild();
- // NodeList nodeList = ((Element)critNode).getElementsByTagName(ID);
- // if(nodeList != null && nodeList.getLength() > 0){
- if (idNode != null) {
- // Node idNode = nodeList.item(0);
- NamedNodeMap idAttribMap = idNode.getAttributes();
- String idRoot = idAttribMap.getNamedItem(ROOT).getNodeValue();
- String idExt = idAttribMap.getNamedItem(EXTENSION).getNodeValue();
-
- Node parent = idNode.getParentNode();
-
- NamedNodeMap attribMap = parent.getAttributes();
- String classCode = attribMap.getNamedItem(CLASS_CODE).getNodeValue();
- String moodCode = attribMap.getNamedItem(MOOD_CODE).getNodeValue();
-
- // create criteriaRef
- Element criteriaReference = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
- criteriaReference.setAttribute(CLASS_CODE, classCode);
- criteriaReference.setAttribute(MOOD_CODE, moodCode);
-
- Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- id.setAttribute(ROOT, idRoot);
- id.setAttribute(EXTENSION, idExt);
-
- criteriaReference.appendChild(id);
- outboundRelElem.appendChild(criteriaReference);
- }
- }
- }
-
- /**
- * Generate crit ref set op.
- *
- * @param parentNode
- * the parent node
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @param childNode
- * the child node
- * @param outboundRelElem
- * the outbound rel elem
- * @param clauseName
- * the clause name
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private void generateCritRefSetOp(Node parentNode, XmlProcessor hqmfXmlProcessor, Node childNode,
- Node outboundRelElem, String clauseName) throws XPathExpressionException {
-
- Node setOpEntry = generateSetOpHQMF(childNode, parentNode, clauseName);
- NodeList childList = setOpEntry.getChildNodes();
- for (int j = 0; j < childList.getLength(); j++) {
- Node child = childList.item(j);
- if (GROUPER_CRITERIA.equals(child.getNodeName())) {
- NodeList idChildList = ((Element) child).getElementsByTagName(ID);
- if (idChildList.getLength() > 0) {
- Node idChild = idChildList.item(0);
- NamedNodeMap attribMap = idChild.getAttributes();
- String idRoot = attribMap.getNamedItem(ROOT).getNodeValue();
- String idExt = attribMap.getNamedItem(EXTENSION).getNodeValue();
-
- // create criteriaRef
- Element criteriaReference = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
- criteriaReference.setAttribute(CLASS_CODE, "GROUPER");
- criteriaReference.setAttribute(MOOD_CODE, "EVN");
-
- Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- id.setAttribute(ROOT, idRoot);
- id.setAttribute(EXTENSION, idExt);
-
- criteriaReference.appendChild(id);
- outboundRelElem.appendChild(criteriaReference);
- }
- }
- }
- }
-
- /**
- * Generate crit ref for node.
- *
- * @param outboundRelElem
- * the outbound rel elem
- * @param childNode
- * the child node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private void generateCritRefForNode(Node outboundRelElem, Node childNode)
- throws XPathExpressionException {
- XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
- String childName = childNode.getNodeName();
-
- switch (childName) {
- case ELEMENT_REF:
- generateCritRefElementRef(outboundRelElem, childNode, hqmfXmlProcessor);
- break;
- case SUB_TREE_REF:
- generateCritRefCQLDefine(outboundRelElem, childNode, hqmfXmlProcessor, true);
- break;
-
- default:
- break;
- }
-
- }
-
- /**
- * This method will basically create a with
- * classCode='GROUPER' and moodCode='EVN' and have the tag pointing to the
- * for the referenced subTree/clause.
- *
- * @param outboundRelElem
- * the outbound rel elem
- * @param subTreeRefNode
- * the sub tree ref node
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @throws XPathExpressionException
- * the x path expression exception
- */
- protected void generateCritRefCQLDefine(Node outboundRelElem, Node subTreeRefNode, XmlProcessor hqmfXmlProcessor)
- throws XPathExpressionException {
- generateCritRefCQLDefine(outboundRelElem, subTreeRefNode, hqmfXmlProcessor, false);
- }
-
- /**
- * This method will basically create a with
- * classCode='GROUPER' and moodCode='EVN' and have the tag pointing to the
- * for the referenced subTree/clause.
- *
- * @param outboundRelElem
- * the outbound rel elem
- * @param cqlDefineNode
- * the sub tree ref node
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @param checkExisting
- * check in the map if already existing
- * @throws XPathExpressionException
- * the x path expression exception
- */
-
- protected void generateCritRefCQLDefine(Node outboundRelElem, Node cqlDefineNode, XmlProcessor hqmfXmlProcessor,
- boolean checkExisting) throws XPathExpressionException {
-
- String cqlDefUUID = cqlDefineNode.getAttributes().getNamedItem(UUID).getNodeValue();
-
- String xpath = "/measure/cqlLookUp//definition[@id='" + cqlDefUUID + "']";
- Node definitionNode = measureExport.getSimpleXmlProcessor()
- .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
- if (definitionNode != null) {
- String defineName = definitionNode.getAttributes().getNamedItem("name").getNodeValue();
- Node cqlUUIDNode = measureExport.getSimpleXmlProcessor().findNode(
- measureExport.getSimpleXmlProcessor().getOriginalDoc(), "/measure/measureDetails/cqlUUID");
- Node cqlLibraryNode = measureExport.getSimpleXmlProcessor()
- .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), "/measure/cqlLookUp/library");
- if (cqlUUIDNode != null && cqlLibraryNode != null) {
- String uuid = cqlUUIDNode.getTextContent();
- String libraryName = cqlLibraryNode.getTextContent();
- String ext = libraryName + ".\"" + defineName + "\"";
- // create criteriaRef
- Element criteriaReference = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
- criteriaReference.setAttribute(CLASS_CODE, "OBS");
- criteriaReference.setAttribute(MOOD_CODE, "EVN");
-
- Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- id.setAttribute(ROOT, uuid);
- id.setAttribute(EXTENSION, ext);
-
- criteriaReference.appendChild(id);
- outboundRelElem.appendChild(criteriaReference);
- }
- }
- }
-
- /**
- * Generate crit ref element ref.
- *
- * @param outboundRelElem
- * the outbound rel elem
- * @param elementRefNode
- * the element ref node
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @return the node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private Node generateCritRefElementRef(Node outboundRelElem, Node elementRefNode, XmlProcessor hqmfXmlProcessor)
- throws XPathExpressionException {
- String ext = getElementRefExt(elementRefNode, measureExport.getSimpleXmlProcessor());
- String root = elementRefNode.getAttributes().getNamedItem(ID).getNodeValue();
- Node idNodeQDM = hqmfXmlProcessor.findNode(hqmfXmlProcessor.getOriginalDoc(),
- "//entry/*/id[@root=\"" + root + "\"][@extension=\"" + ext + "\"]");
- if (idNodeQDM != null) {
- Node parent = idNodeQDM.getParentNode();
- if (parent != null) {
- NamedNodeMap attribMap = parent.getAttributes();
- String classCode = attribMap.getNamedItem(CLASS_CODE).getNodeValue();
- String moodCode = attribMap.getNamedItem(MOOD_CODE).getNodeValue();
-
- // create criteriaRef
- Element criteriaReference = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
- criteriaReference.setAttribute(CLASS_CODE, classCode);
- criteriaReference.setAttribute(MOOD_CODE, moodCode);
-
- Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- id.setAttribute(ROOT, root);
- id.setAttribute(EXTENSION, ext);
-
- criteriaReference.appendChild(id);
- outboundRelElem.appendChild(criteriaReference);
- // return element
- return parent.getParentNode();
- }
- } else {
- // check if this is a measurement period
- String displayName = elementRefNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- if ("Measurement Period : Timing Element".equals(displayName)) {
- // create criteriaRef
- Element criteriaReference = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
- criteriaReference.setAttribute(CLASS_CODE, "OBS");
- criteriaReference.setAttribute(MOOD_CODE, "EVN");
-
- Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- id.setAttribute(ROOT, elementRefNode.getAttributes().getNamedItem(ID).getNodeValue());
- id.setAttribute(EXTENSION, "measureperiod");
-
- criteriaReference.appendChild(id);
- outboundRelElem.appendChild(criteriaReference);
- }
- }
- return null;
- }
-
- /**
- * Generate item count element ref.
- *
- * @param me
- * the me
- * @param populationTypeCriteriaElement
- * the population type criteria element
- * @param elementRefNode
- * the element ref node
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @throws XPathExpressionException
- * the x path expression exception
- */
- public void generateItemCountElementRef(MeasureExport me, Element populationTypeCriteriaElement,
- Node elementRefNode, XmlProcessor hqmfXmlProcessor) throws XPathExpressionException {
- String ext = getElementRefExt(elementRefNode, me.getSimpleXmlProcessor());
- String root = elementRefNode.getAttributes().getNamedItem(ID).getNodeValue();
- Node idNodeQDM = hqmfXmlProcessor.findNode(hqmfXmlProcessor.getOriginalDoc(),
- "//entry/*/id[@root='" + root + "'][@extension=\"" + ext + "\"]");
- if (idNodeQDM != null) {
- Node parent = idNodeQDM.getParentNode();
- if (parent != null) {
- String classCode = parent.getAttributes().getNamedItem("classCode").getNodeValue();
- String moodCode = parent.getAttributes().getNamedItem("moodCode").getNodeValue();
- // item count Criteria Ref for Measure Observations
- if ("measureObservationDefinition".equals(populationTypeCriteriaElement.getNodeName())) {
- Element componentOfElem = hqmfXmlProcessor.getOriginalDoc().createElement("componentOf");
- componentOfElem.setAttribute(TYPE_CODE, "COMP");
- Element criteriaRef = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
- criteriaRef.setAttribute(CLASS_CODE, classCode);
- criteriaRef.setAttribute(MOOD_CODE, moodCode);
- Element idElement = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- idElement.setAttribute(ROOT, root);
- idElement.setAttribute(EXTENSION, ext);
- criteriaRef.appendChild(idElement);
- componentOfElem.appendChild(criteriaRef);
- Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("Item Count ");
- populationTypeCriteriaElement.appendChild(comment);
- populationTypeCriteriaElement.appendChild(componentOfElem);
- } else { // item count Criteria Ref for Populations
- // create component for ItemCount ElmentRef
- Element componentElem = hqmfXmlProcessor.getOriginalDoc().createElement("component");
- componentElem.setAttribute(TYPE_CODE, "COMP");
- Element measureAttrElem = hqmfXmlProcessor.getOriginalDoc().createElement("measureAttribute");
- componentElem.appendChild(measureAttrElem);
- Element codeElem = hqmfXmlProcessor.getOriginalDoc().createElement("code");
- codeElem.setAttribute(CODE, "ITMCNT");
- codeElem.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.5.4");
- codeElem.setAttribute(CODE_SYSTEM_NAME, "HL7 Observation Value");
- Element displayNameElem = hqmfXmlProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
- displayNameElem.setAttribute(VALUE, "Items to count");
- codeElem.appendChild(displayNameElem);
- Element valueElem = hqmfXmlProcessor.getOriginalDoc().createElement(VALUE);
- valueElem.setAttribute("xsi:type", "II");
- valueElem.setAttribute(ROOT, root);
- valueElem.setAttribute(EXTENSION, ext);
- measureAttrElem.appendChild(codeElem);
- measureAttrElem.appendChild(valueElem);
- populationTypeCriteriaElement.appendChild(componentElem);
- }
- }
- }
- }
-
- /**
- * Gets the element ref ext.
- *
- * @param elementRefNode
- * the element ref node
- * @param simpleXmlProcessor
- * the simple xml processor
- * @return the element ref ext
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private String getElementRefExt(Node elementRefNode, XmlProcessor simpleXmlProcessor)
- throws XPathExpressionException {
- String extension = "";
- if (elementRefNode.hasChildNodes()) {
- Node childNode = elementRefNode.getFirstChild();
- if ("attribute".equals(childNode.getNodeName())) {
- extension = childNode.getAttributes().getNamedItem(ATTR_UUID).getNodeValue();
- }
- } else {
- String id = elementRefNode.getAttributes().getNamedItem(ID).getNodeValue();
- Node qdmNode = simpleXmlProcessor.findNode(simpleXmlProcessor.getOriginalDoc(),
- "/measure/elementLookUp/qdm[@uuid='" + id + "']");
- if (qdmNode != null) {
- String dataType = qdmNode.getAttributes().getNamedItem(DATATYPE).getNodeValue();
- String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
- extension = qdmName + "_" + dataType;
- if (qdmNode.getAttributes().getNamedItem(INSTANCE) != null) {
- extension = qdmNode.getAttributes().getNamedItem(INSTANCE).getNodeValue() + "_" + extension;
- }
- }
- }
- return StringUtils.deleteWhitespace(extension);
- }
-
- /**
- * Generate empty grouper.
- *
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @param root
- * the root
- * @param ext
- * the ext
- * @return the node
- */
- private Node generateEmptyGrouper(XmlProcessor hqmfXmlProcessor, String root, String ext) {
- Element grouperElem = hqmfXmlProcessor.getOriginalDoc().createElement(GROUPER_CRITERIA);
- grouperElem.setAttribute(CLASS_CODE, "GROUPER");
- grouperElem.setAttribute(MOOD_CODE, "EVN");
-
- Element idElem = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
- idElem.setAttribute(ROOT, root);
- idElem.setAttribute(EXTENSION, StringUtils.deleteWhitespace(ext));
-
- grouperElem.appendChild(idElem);
-
- return grouperElem;
- }
-
- /**
- * Generate empty outbound elem.
- *
- * @param hqmfXmlProcessor
- * the hqmf xml processor
- * @return the element
- */
- private Element generateEmptyOutboundElem(XmlProcessor hqmfXmlProcessor) {
- Element outboundRelElem = hqmfXmlProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
- outboundRelElem.setAttribute(TYPE_CODE, "COMP");
- return outboundRelElem;
- }
-
- /**
- * Gets the tag from entry.
- *
- * @param entryElem
- * the entry elem
- * @param tagName
- * the tag name
- * @return the tag from entry
- */
- private Node getTagFromEntry(Node entryElem, String tagName) {
-
- String entryElemName = entryElem.getNodeName();
- if (ENTRY.equals(entryElemName)) {
- Node firstChild = entryElem.getFirstChild();
- if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
- NodeList nodeList = ((Element) firstChild.getNextSibling()).getElementsByTagName(tagName);
- if (nodeList != null && nodeList.getLength() > 0) {
- return nodeList.item(0);
- }
- } else {
- NodeList nodeList = ((Element) firstChild).getElementsByTagName(tagName);
- if (nodeList != null && nodeList.getLength() > 0) {
- return nodeList.item(0);
- }
- }
- }
- return null;
- }
-
- /**
- * Check If the parentNode is a SUB_TREE node. Or else, if parent is a
- * 'functionalOp' then recursively check if the parentNode's parent is a
- * 'subTree'. If yes, then return true.
- *
- * @param parentNode
- * the parent node
- * @return boolean
- */
- private Node checkIfSubTree(Node parentNode) {
- Node returnNode = null;
- if (parentNode != null) {
- String parentName = parentNode.getNodeName();
- if (SUB_TREE.equals(parentName)) {
- returnNode = parentNode;
- } else if (FUNCTIONAL_OP.equals(parentName)) {
- returnNode = checkIfSubTree(parentNode.getParentNode());
- }
- }
- return returnNode;
- }
-
- /**
- * Gets the firt child list.
- *
- * @param function
- * the function
- * @return the firt child list
- */
- public static List getFunctionalOpFirstChild(String function) {
- List childList = new ArrayList<>();
- if (AGE_AT.equalsIgnoreCase(function)) {
- childList.add(SUB_TREE_REF);
- childList.add(RELATIONAL_OP);
- childList.add(FUNCTIONAL_OP);
- childList.add(ELEMENT_REF);
- } else {
- childList.add(ELEMENT_REF);
- childList.add(SET_OP);
- childList.add(SUB_TREE_REF);
- childList.add(RELATIONAL_OP);
- }
- return childList;
- }
-
- /**
- * Gets the aggregate and instance function childs.
- *
- * @param typeChild
- * the type child
- * @return the aggregate and instance function childs
- */
- public static List getAggregateAndInstanceFunctionChilds(String typeChild) {
- List aggregateList = new ArrayList<>();
- aggregateList.add("FIRST");
- aggregateList.add("SECOND");
- aggregateList.add("THIRD");
- aggregateList.add("FOURTH");
- aggregateList.add("FIFTH");
- aggregateList.add("MOST RECENT");
- if ("AGGREGATE".equals(typeChild)) {
- aggregateList.add("DATETIMEDIFF");
- }
- return aggregateList;
- }
-
- /**
- * Gets the functional op first child in mo.
- *
- * @param function
- * the function
- * @return the functional op first child in mo
- */
- public static List getFunctionalOpFirstChildInMO(String function) {
- List childList = new ArrayList<>();
- if ("DATETIMEDIFF".equalsIgnoreCase(function)) {
- childList.add(ELEMENT_REF);
- childList.add(SUB_TREE_REF);
- childList.add(RELATIONAL_OP);
- childList.addAll(getAggregateAndInstanceFunctionChilds("INSTANCE"));
- } else {
- childList.addAll(getFunctionalOpFirstChild(function));
- childList.addAll(getAggregateAndInstanceFunctionChilds("AGGREGATE"));
- }
- return childList;
- }
-
- /**
- * Check for used Used sub tree ref Node map in Populations and Meausre
- * Observations.
- */
- private void createUsedSubTreeRefMap() {
-
- XmlProcessor simpleXmlProcessor = measureExport.getSimpleXmlProcessor();
- String typeXpathString = "";
- List usedSubTreeRefIdsPop = new ArrayList<>();
- List usedSubTreeRefIdsMO = new ArrayList<>();
- List usedSubTreeRefIDsRA = new ArrayList<>();
- for (String typeString : POPULATION_NAME_LIST) {
- typeXpathString += "@type = '" + typeString + "' or";
- }
- typeXpathString = typeXpathString.substring(0, typeXpathString.lastIndexOf(" or"));
- String xpathForSubTreeInPOPClause = "/measure/measureGrouping//clause[" + typeXpathString + "]//subTreeRef/@id";
- String xpathForSubTreeInMOClause = "/measure/measureGrouping//clause[@type='measureObservation']//subTreeRef/@id";
- String xpathForSubTreeInRAClause = "/measure//riskAdjustmentVariables/subTreeRef/@id";
- try {
-
- // creating used Subtree Red Map in Populations
- NodeList populationsSubTreeNode = simpleXmlProcessor.findNodeList(simpleXmlProcessor.getOriginalDoc(),
- xpathForSubTreeInPOPClause);
- for (int i = 0; i < populationsSubTreeNode.getLength(); i++) {
- String uuid = populationsSubTreeNode.item(i).getNodeValue();
- uuid = checkIfQDMVarInstanceIsPresent(uuid, simpleXmlProcessor);
- if (!usedSubTreeRefIdsPop.contains(uuid)) {
- usedSubTreeRefIdsPop.add(uuid);
- }
- }
- usedSubTreeRefIdsPop = checkUnUsedSubTreeRef(simpleXmlProcessor, usedSubTreeRefIdsPop);
- for (String uuid : usedSubTreeRefIdsPop) {
- Node subTreeNode = createUsedSubTreeRefMap(simpleXmlProcessor, uuid);
- subTreeNodeInPOPMap.put(uuid, subTreeNode);
- }
-
- // creating used Subtree Red Map in Measure Observations
- NodeList measureObsSubTreeNode = simpleXmlProcessor.findNodeList(simpleXmlProcessor.getOriginalDoc(),
- xpathForSubTreeInMOClause);
- for (int i = 0; i < measureObsSubTreeNode.getLength(); i++) {
- String uuid = measureObsSubTreeNode.item(i).getNodeValue();
- uuid = checkIfQDMVarInstanceIsPresent(uuid, simpleXmlProcessor);
- if (!usedSubTreeRefIdsMO.contains(uuid)) {
- usedSubTreeRefIdsMO.add(uuid);
- }
- }
- usedSubTreeRefIdsMO = checkUnUsedSubTreeRef(simpleXmlProcessor, usedSubTreeRefIdsMO);
- for (String uuid : usedSubTreeRefIdsMO) {
- Node subTreeNode = createUsedSubTreeRefMap(simpleXmlProcessor, uuid);
- subTreeNodeInMOMap.put(uuid, subTreeNode);
- }
- // creating used Subtree Red in Risk Adjustment
- NodeList riskAdjSubTreeNode = simpleXmlProcessor.findNodeList(simpleXmlProcessor.getOriginalDoc(),
- xpathForSubTreeInRAClause);
- for (int i = 0; i < riskAdjSubTreeNode.getLength(); i++) {
- String uuid = riskAdjSubTreeNode.item(i).getNodeValue();
- uuid = checkIfQDMVarInstanceIsPresent(uuid, simpleXmlProcessor);
- if (!usedSubTreeRefIDsRA.contains(uuid)) {
- usedSubTreeRefIDsRA.add(uuid);
- }
- }
- usedSubTreeRefIDsRA = checkUnUsedSubTreeRef(simpleXmlProcessor, usedSubTreeRefIDsRA);
- for (String uuid : usedSubTreeRefIDsRA) {
- Node subTreeNode = createUsedSubTreeRefMap(simpleXmlProcessor, uuid);
- subTreeNodeInRAMap.put(uuid, subTreeNode);
- }
-
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Creates the used sub tree ref map.
- *
- * @param simpleXmlProcessor
- * the simple xml processor
- * @param uuid
- * the uuid
- * @return the node
- */
- private Node createUsedSubTreeRefMap(XmlProcessor simpleXmlProcessor, String uuid) {
- String xpathforUsedSubTreeMap = "/measure/subTreeLookUp/subTree[@uuid='" + uuid + "']";
- Node subTreeNode = null;
- try {
- subTreeNode = simpleXmlProcessor.findNode(simpleXmlProcessor.getOriginalDoc(), xpathforUsedSubTreeMap);
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- return subTreeNode;
- }
-
- /**
- * Check un used sub tree ref.
- *
- * @param xmlProcessor
- * the xml processor
- * @param usedSubTreeRefIds
- * the used sub tree ref ids
- * @return the list
- */
- private List checkUnUsedSubTreeRef(XmlProcessor xmlProcessor, List usedSubTreeRefIds) {
-
- List allSubTreeRefIds = new ArrayList<>();
- NodeList subTreeRefIdsNodeList;
- javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
- try {
- subTreeRefIdsNodeList = xmlProcessor.findNodeList(xmlProcessor.getOriginalDoc(),
- "/measure//subTreeRef/@id");
-
- for (int i = 0; i < subTreeRefIdsNodeList.getLength(); i++) {
- Node SubTreeRefIdAttributeNode = subTreeRefIdsNodeList.item(i);
- if (!allSubTreeRefIds.contains(SubTreeRefIdAttributeNode.getNodeValue())) {
- allSubTreeRefIds.add(SubTreeRefIdAttributeNode.getNodeValue());
- }
- }
- allSubTreeRefIds.removeAll(usedSubTreeRefIds);
-
- for (int i = 0; i < usedSubTreeRefIds.size(); i++) {
- for (int j = 0; j < allSubTreeRefIds.size(); j++) {
- Node usedSubTreeRefNode = xmlProcessor.findNode(xmlProcessor.getOriginalDoc(),
- "/measure/subTreeLookUp/subTree[@uuid='" + usedSubTreeRefIds.get(i) + "']//subTreeRef[@id='"
- + allSubTreeRefIds.get(j) + "']");
- if (usedSubTreeRefNode != null) {
-
- String subTreeUUID = usedSubTreeRefNode.getAttributes().getNamedItem(ID).getNodeValue();
- String XPATH_IS_INSTANCE_OF = "//subTree [boolean(@instanceOf)]/@uuid ='" + subTreeUUID + "'";
- boolean isOccurrenceNode = (Boolean) xPath.evaluate(XPATH_IS_INSTANCE_OF,
- xmlProcessor.getOriginalDoc(), XPathConstants.BOOLEAN);
- if (isOccurrenceNode) {
- String XPATH_PARENT_UUID = "//subTree [@uuid ='" + subTreeUUID + "']/@instanceOf";
- String parentUUID = (String) xPath.evaluate(XPATH_PARENT_UUID,
- xmlProcessor.getOriginalDoc(), XPathConstants.STRING);
- if (!usedSubTreeRefIds.contains(parentUUID)) {
- usedSubTreeRefIds.add(parentUUID);
- }
-
- }
- if (!usedSubTreeRefIds.contains(allSubTreeRefIds.get(j))) {
-
- usedSubTreeRefIds.add(allSubTreeRefIds.get(j));
- }
- }
- }
-
- }
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- return usedSubTreeRefIds;
- }
-
- /**
- * Validate sub tree ref in pop.
- *
- * @param subTreeNode
- * the sub tree node
- * @param functionalOpNode
- * the functional op node
- * @return true, if successful
- */
- public boolean validateSubTreeRefInPOP(Node subTreeNode, Node functionalOpNode) {
- if (subTreeNodeInPOPMap.get(subTreeNode.getAttributes().getNamedItem(UUID).getNodeValue()) != null) {
- String firstChildName = functionalOpNode.getFirstChild().getNodeName();
- String functionalOpType = functionalOpNode.getAttributes().getNamedItem(TYPE).getNodeValue();
- List childsList = FUNCTIONAL_OP_RULES_IN_POP.get(functionalOpType);
- if (childsList.contains(firstChildName)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Utility method which will try to find the tag "localVariableName" and set the
- * given string value to its VALUE attribute.
- *
- * @param node
- * the node
- * @param localVarName
- * the local var name
- */
- private void updateLocalVar(Node node, String localVarName) {
- if (node == null) {
- return;
- }
- NodeList localVarNodeList = ((Element) node).getElementsByTagName(LOCAL_VARIABLE_NAME);
- if (localVarNodeList != null && localVarNodeList.getLength() > 0) {
- Element localVar = (Element) localVarNodeList.item(0);
- localVar.setAttribute(VALUE, localVarName);
- }
- }
-
- /**
- * Check if qdm var instance is present.
- *
- * @param usedSubtreeRefId
- * the used subtree ref id
- * @param xmlProcessor
- * the xml processor
- * @return the string
- */
- private String checkIfQDMVarInstanceIsPresent(String usedSubtreeRefId, XmlProcessor xmlProcessor) {
-
- String XPATH_INSTANCE_QDM_VAR = "/measure/subTreeLookUp/subTree[@uuid='" + usedSubtreeRefId + "']/@instance";
- String XPATH_INSTANCE_OF_QDM_VAR = "/measure/subTreeLookUp/subTree[@uuid='" + usedSubtreeRefId
- + "']/@instanceOf";
- try {
- Node nodesSDE_SubTree = xmlProcessor.findNode(xmlProcessor.getOriginalDoc(), XPATH_INSTANCE_QDM_VAR);
- if (nodesSDE_SubTree != null) {
- Node nodesSDE_SubTreeInstance = xmlProcessor.findNode(xmlProcessor.getOriginalDoc(),
- XPATH_INSTANCE_OF_QDM_VAR);
- usedSubtreeRefId = nodesSDE_SubTreeInstance.getNodeValue();
- }
-
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
-
- return usedSubtreeRefId;
- }
-
- /**
- * Gets the sub tree node map.
- *
- * @return the subTreeNodeMap
- */
- public Map getSubTreeNodeMap() {
- return subTreeNodeMap;
- }
-
- /**
- * Sets the sub tree node map.
- *
- * @param subTreeNodeMap
- * the subTreeNodeMap to set
- */
- public void setSubTreeNodeMap(Map subTreeNodeMap) {
- this.subTreeNodeMap = subTreeNodeMap;
- }
-
- /**
- * Gets the measure export.
- *
- * @return the measureExport
- */
- public MeasureExport getMeasureExport() {
- return measureExport;
- }
-
- /**
- * Sets the measure export.
- *
- * @param measureExport
- * the measureExport to set
- */
- public void setMeasureExport(MeasureExport measureExport) {
- this.measureExport = measureExport;
- }
-
- /**
- * Gets the sub tree node in mo map.
- *
- * @return the subTreeNodeInMOMap
- */
- public Map getSubTreeNodeInMOMap() {
- return subTreeNodeInMOMap;
- }
-
- /**
- * Sets the sub tree node in mo map.
- *
- * @param subTreeNodeInMOMap
- * the subTreeNodeInMOMap to set
- */
- public void setSubTreeNodeInMOMap(Map subTreeNodeInMOMap) {
- this.subTreeNodeInMOMap = subTreeNodeInMOMap;
- }
-
- /**
- * Gets the sub tree node in ra map.
- *
- * @return the subTreeNodeInMOMap
- */
- public Map getSubTreeNodeInRAMap() {
- return subTreeNodeInRAMap;
- }
-
- /**
- * Sets the sub tree node in ra map.
- *
- * @param subTreeNodeInRAMap
- * the sub tree node in ra map
- */
- public void setSubTreeNodeInRAMap(Map subTreeNodeInRAMap) {
- this.subTreeNodeInRAMap = subTreeNodeInRAMap;
- }
-
- /**
- * Gets the sub tree node in pop map.
- *
- * @return the subTreeNodeInPOPMap
- */
- public Map getSubTreeNodeInPOPMap() {
- return subTreeNodeInPOPMap;
- }
-
- /**
- * Sets the sub tree node in pop map.
- *
- * @param subTreeNodeInPOPMap
- * the subTreeNodeInPOPMap to set
- */
- public void setSubTreeNodeInPOPMap(Map subTreeNodeInPOPMap) {
- this.subTreeNodeInPOPMap = subTreeNodeInPOPMap;
- }
+ private static final String GROUPER_CRITERIA = "grouperCriteria";
+ private static final String CONJUNCTION_CODE = "conjunctionCode";
+ private static final String LOCAL_VARIABLE_NAME = "localVariableName";
+ private static final String CRITERIA_REFERENCE = "criteriaReference";
+
+ private static final String ROLE = "role";
+
+ private static final String PARTICIPATION = "participation";
+
+ private static final String EXCERPT = "excerpt";
+
+ private static final String SEQUENCE_NUMBER = "sequenceNumber";
+
+ private static final String GROUPER = "grouper";
+
+ private static final String ENTRY = "entry";
+
+ private static final String DATA_CRITERIA_SECTION = "dataCriteriaSection";
+
+ private Map subTreeNodeMap = new HashMap<>();
+
+ public MeasureExport measureExport;
+
+ private static final Logger logger = LoggerFactory.getLogger(HQMFClauseLogicGenerator.class);
+
+ /** MAP of Functional Ops NON Subset Type. */
+ private static final Map FUNCTIONAL_OPS_NON_SUBSET =
+ new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+ /** MAP of Functional Ops Subset Type. */
+ private static final Map FUNCTIONAL_OPS_SUBSET =
+ new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+ static {
+ FUNCTIONAL_OPS_NON_SUBSET.put(MatConstants.FIRST, "1");
+ FUNCTIONAL_OPS_NON_SUBSET.put(MatConstants.SECOND, "2");
+ FUNCTIONAL_OPS_NON_SUBSET.put(MatConstants.THIRD, "3");
+ FUNCTIONAL_OPS_NON_SUBSET.put(MatConstants.FOURTH, "4");
+ FUNCTIONAL_OPS_NON_SUBSET.put(MatConstants.FIFTH, "5");
+
+ FUNCTIONAL_OPS_SUBSET.put(MatConstants.MOST_RECENT, "QDM_LAST");
+ FUNCTIONAL_OPS_SUBSET.put(MatConstants.COUNT, "QDM_SUM");
+ FUNCTIONAL_OPS_SUBSET.put(MatConstants.MIN, "QDM_MIN");
+ FUNCTIONAL_OPS_SUBSET.put(MatConstants.MAX, "QDM_MAX");
+ FUNCTIONAL_OPS_SUBSET.put(MatConstants.SUM, "QDM_SUM");
+ FUNCTIONAL_OPS_SUBSET.put(MatConstants.MEDIAN, "QDM_MEDIAN");
+ FUNCTIONAL_OPS_SUBSET.put(MatConstants.AVG, "QDM_AVERAGE");
+ }
+
+ /** The Constant populations. */
+ private static final List POPULATION_NAME_LIST = new ArrayList<>();
+
+ static {
+ POPULATION_NAME_LIST.add("initialPopulation");
+ POPULATION_NAME_LIST.add("denominator");
+ POPULATION_NAME_LIST.add("denominatorExclusions");
+ POPULATION_NAME_LIST.add("denominatorExceptions");
+ POPULATION_NAME_LIST.add("numerator");
+ POPULATION_NAME_LIST.add("numeratorExclusions");
+ POPULATION_NAME_LIST.add("measurePopulation");
+ POPULATION_NAME_LIST.add("measurePopulationExclusions");
+ POPULATION_NAME_LIST.add("stratum");
+ }
+
+ /** The sub tree node in mo map. */
+ Map subTreeNodeInMOMap = new HashMap<>();
+
+ /** The sub tree node in pop map. */
+ Map subTreeNodeInPOPMap = new HashMap<>();
+
+ /** The sub tree node in RA map. */
+ Map subTreeNodeInRAMap = new HashMap<>();
+
+ /** The Constant FUNCTIONAL_OP_RULES_IN_POP. */
+ private static final Map> FUNCTIONAL_OP_RULES_IN_POP =
+ new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+ /** The Constant FUNCTIONAL_OP_RULES_IN_MO. */
+ private static final Map> FUNCTIONAL_OP_RULES_IN_MO =
+ new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+ static {
+ FUNCTIONAL_OP_RULES_IN_POP.put("MEDIAN", getFunctionalOpFirstChild("MEDIAN"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("AVG", getFunctionalOpFirstChild("AVG"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("MAX", getFunctionalOpFirstChild("MAX"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("MIN", getFunctionalOpFirstChild("MIN"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("SUM", getFunctionalOpFirstChild("SUM"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("COUNT", getFunctionalOpFirstChild("COUNT"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("FIRST", getFunctionalOpFirstChild("FIRST"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("SECOND", getFunctionalOpFirstChild("SECOND"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("THIRD", getFunctionalOpFirstChild("THIRD"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("FOURTH", getFunctionalOpFirstChild("FOURTH"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("FIFTH", getFunctionalOpFirstChild("FIFTH"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("MOST RECENT", getFunctionalOpFirstChild("MOST RECENT"));
+ FUNCTIONAL_OP_RULES_IN_POP.put("AGE AT", getFunctionalOpFirstChild("AGE AT"));
+
+ /* Rules for Functions in Measure Observations */
+ FUNCTIONAL_OP_RULES_IN_MO.put("MEDIAN", getFunctionalOpFirstChildInMO("MEDIAN"));
+ FUNCTIONAL_OP_RULES_IN_MO.put("AVERAGE", getFunctionalOpFirstChildInMO("AVERAGE"));
+ FUNCTIONAL_OP_RULES_IN_MO.put("MIN", getFunctionalOpFirstChildInMO("MIN"));
+ FUNCTIONAL_OP_RULES_IN_MO.put("SUM", getFunctionalOpFirstChildInMO("SUM"));
+ FUNCTIONAL_OP_RULES_IN_MO.put("COUNT", getFunctionalOpFirstChildInMO("COUNT"));
+ FUNCTIONAL_OP_RULES_IN_MO.put("DATETIMEDIFF", getFunctionalOpFirstChildInMO("DATETIMEDIFF"));
+ }
+
+ @Override
+ public String generate(MeasureExport me) throws Exception {
+ measureExport = me;
+ createUsedSubTreeRefMap();
+ generateSubTreeXML();
+ return null;
+ }
+
+ /**
+ * Generate sub tree xml.
+ *
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void generateSubTreeXML() throws XPathExpressionException {
+ String xpath = "/measure/subTreeLookUp/subTree[not(@instance)]";
+ NodeList subTreeNodeList =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNodeList(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
+ for (int i = 0; i < subTreeNodeList.getLength(); i++) {
+ Node subTreeNode = subTreeNodeList.item(i);
+ subTreeNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ String uuid = subTreeNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ if (subTreeNodeInPOPMap.containsKey(uuid) && subTreeNodeInMOMap.containsKey(uuid)
+ || subTreeNodeInPOPMap.containsKey(uuid)
+ || subTreeNodeInRAMap.containsKey(uuid)) {
+ generateSubTreeXML(subTreeNode, false);
+ }
+ }
+ String xpathOccurrence = "/measure/subTreeLookUp/subTree[(@instance)]";
+ NodeList occurrenceSubTreeNodeList =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNodeList(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpathOccurrence);
+ for (int i = 0; i < occurrenceSubTreeNodeList.getLength(); i++) {
+ Node subTreeNode = occurrenceSubTreeNodeList.item(i);
+ generateOccHQMF(subTreeNode);
+ }
+ }
+
+ /**
+ * Generate sub tree xml.
+ *
+ * @param subTreeNode the sub tree node
+ * @param msrObsDateTimeDiffSubTree the msr obs date time diff sub tree
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ protected Node generateSubTreeXML(Node subTreeNode, boolean msrObsDateTimeDiffSubTree)
+ throws XPathExpressionException {
+
+ // If this is an empty or NULL clause, return right now.
+ if (subTreeNode == null || !subTreeNode.hasChildNodes()) {
+ return null;
+ }
+
+ /*
+ If this is a Occurrence clause then we need to find the base clause and
+ generate HQMF for the base clause. Then we need to generate Occurrence HQMF
+ for the occurrence clause.
+ */
+ if (subTreeNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ String baseClauseUUID = subTreeNode.getAttributes().getNamedItem(INSTANCE_OF).getNodeValue();
+ String xpath = "/measure/subTreeLookUp/subTree[@uuid = '" + baseClauseUUID + "']";
+ Node baseSubTreeNode =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
+ generateSubTreeXML(baseSubTreeNode, false);
+ generateOccHQMF(subTreeNode);
+ }
+
+ String subTreeUUID = subTreeNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ String clauseName = subTreeNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ Boolean isRav = isRiskAdjustmentVariable(subTreeUUID, clauseName);
+
+ // Check the 'subTreeNodeMap' to make sure the clause isn't already generated.
+ if (subTreeNodeMap.containsKey(subTreeUUID) && !msrObsDateTimeDiffSubTree) {
+ logger.debug("HQMF for Clause " + clauseName + " is already generated. Skipping.");
+ return null;
+ }
+
+ // get the first child of the subTreeNode
+ Node firstChild = subTreeNode.getFirstChild();
+ String firstChildName = firstChild.getNodeName();
+ logger.debug(
+ "Generating HQMF for clause:'"
+ + clauseName
+ + "' with first child named:'"
+ + firstChildName
+ + "'.");
+
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+ Element dataCriteriaSectionElem =
+ (Element)
+ hqmfXmlProcessor.getOriginalDoc().getElementsByTagName(DATA_CRITERIA_SECTION).item(0);
+
+ if (isRav) {
+ Comment riskAdjustmentVariable =
+ hqmfXmlProcessor.getOriginalDoc().createComment("Risk Adjustment Variable");
+ dataCriteriaSectionElem.appendChild(riskAdjustmentVariable);
+ }
+ Node entryElement = null;
+ switch (firstChildName) {
+ case SET_OP:
+ entryElement = generateSetOpHQMF(firstChild, dataCriteriaSectionElem, clauseName);
+ break;
+ case ELEMENT_REF:
+ entryElement = generateElementRefHQMF(firstChild, dataCriteriaSectionElem, clauseName);
+ break;
+ case SUB_TREE_REF:
+ entryElement = generateSubTreeHQMF(firstChild, dataCriteriaSectionElem, clauseName);
+ break;
+ case RELATIONAL_OP:
+ entryElement = generateRelOpHQMF(firstChild, dataCriteriaSectionElem, clauseName);
+ break;
+ case FUNCTIONAL_OP:
+ entryElement = generateFunctionalOpHQMF(firstChild, dataCriteriaSectionElem, clauseName);
+ break;
+ default:
+ // Dont do anything
+ break;
+ }
+ if (isRav) {
+ Node temp = hqmfXmlProcessor.getOriginalDoc().createAttribute(RAV);
+ temp.setNodeValue("true");
+ entryElement.getAttributes().setNamedItem(temp);
+ }
+ /*
+ The clause is generated now. Make an entry in the 'subTreeNodeMap' to keep
+ track of its generation.
+ */
+ subTreeNodeMap.put(subTreeUUID, subTreeNode);
+ return entryElement;
+ }
+
+ /**
+ * This method is used to discover weither a given class name and UUID is a risk adjustment
+ * variable.
+ *
+ * @param subTreeUUID the sub tree uuid
+ * @param clauseName the clause name
+ * @return the boolean
+ */
+ private Boolean isRiskAdjustmentVariable(String subTreeUUID, String clauseName) {
+ String xPath =
+ "/measure/riskAdjustmentVariables/subTreeRef[@displayName=\""
+ + clauseName
+ + "\" and @id='"
+ + subTreeUUID
+ + "']";
+ boolean isRiskAdjustmentVariable = false;
+ try {
+ Node riskAdjVarNode =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xPath);
+ if (riskAdjVarNode != null) {
+ isRiskAdjustmentVariable = true;
+ }
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ return isRiskAdjustmentVariable;
+ }
+
+ /**
+ * Generate occ hqmf.
+ *
+ * @param subTreeNode the sub tree node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void generateOccHQMF(Node subTreeNode) throws XPathExpressionException {
+ // If this is an empty or NULL clause, return right now.
+ if (subTreeNode == null || subTreeNode.getAttributes().getNamedItem(INSTANCE_OF) == null) {
+ return;
+ }
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+ String occSubTreeUUID = subTreeNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ String qdmVariableSubTreeUUID =
+ subTreeNode.getAttributes().getNamedItem(INSTANCE_OF).getNodeValue();
+ String clauseName = subTreeNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ Boolean isRAV = isRiskAdjustmentVariable(qdmVariableSubTreeUUID, clauseName);
+ // Check the 'subTreeNodeMap' to make sure the occ clause isn't already generated.
+ if (subTreeNodeMap.containsKey(occSubTreeUUID)) {
+ logger.debug("HQMF for Occ Clause " + clauseName + " is already generated. Skipping.");
+ return;
+ }
+
+ if (!subTreeNodeMap.containsKey(qdmVariableSubTreeUUID)) {
+ logger.debug("HQMF for Clause " + clauseName + " is not already generated. Skipping.");
+ return;
+ }
+
+ String xpath = "/measure/subTreeLookUp/subTree[@uuid = '" + qdmVariableSubTreeUUID + "']";
+ Node baseSubTreeNode =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
+ Node baseFirstChild = baseSubTreeNode.getFirstChild();
+ String baseExt = baseFirstChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+
+ Node firstChild = subTreeNode.getFirstChild();
+ String firstChildName = firstChild.getNodeName();
+ String ext = firstChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ // Local Variable Name.
+ String localVarName = clauseName.replace("$", "") + "_" + UUIDUtilClient.uuid(5);
+ String root = subTreeNode.getAttributes().getNamedItem(INSTANCE_OF).getNodeValue();
+ // Check for Element Ref as first CHild.
+ if (firstChildName.equalsIgnoreCase(ELEMENT_REF)) {
+ ext = getElementRefExt(firstChild, measureExport.getSimpleXmlProcessor());
+ baseExt = getElementRefExt(baseFirstChild, measureExport.getSimpleXmlProcessor());
+ } else if (RELATIONAL_OP.equals(firstChildName)
+ || FUNCTIONAL_OP.equals(firstChildName)
+ || SET_OP.equals(firstChildName)) {
+ ext += "_" + firstChild.getAttributes().getNamedItem(UUID).getNodeValue();
+ baseExt += "_" + baseFirstChild.getAttributes().getNamedItem(UUID).getNodeValue();
+ }
+
+ if (FUNCTIONAL_OP.equals(firstChildName) && firstChild.getFirstChild() != null) {
+ Node functionChild = firstChild.getFirstChild();
+ Node baseFunctionChild = baseFirstChild.getFirstChild();
+
+ if (functionChild != null) {
+ if (functionChild.getNodeName().equalsIgnoreCase(SUB_TREE_REF)) {
+ ext = functionChild.getAttributes().getNamedItem(ID).getNodeValue();
+ baseExt = baseFunctionChild.getAttributes().getNamedItem(ID).getNodeValue();
+ } else if (functionChild.getNodeName().equalsIgnoreCase(ELEMENT_REF)) {
+ ext = getElementRefExt(functionChild, measureExport.getSimpleXmlProcessor());
+ baseExt = getElementRefExt(baseFunctionChild, measureExport.getSimpleXmlProcessor());
+ } else {
+ ext =
+ StringUtils.deleteWhitespace(
+ functionChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
+ + "_"
+ + functionChild.getAttributes().getNamedItem(UUID).getNodeValue())
+ .replaceAll(":", "_");
+ baseExt =
+ StringUtils.deleteWhitespace(
+ baseFunctionChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
+ + "_"
+ + baseFunctionChild.getAttributes().getNamedItem(UUID).getNodeValue())
+ .replaceAll(":", "_");
+ }
+ }
+ }
+
+ String isQdmVariable = subTreeNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (isQdmVariable.equalsIgnoreCase(TRUE)) {
+ ext = "qdm_var_" + StringUtils.deleteWhitespace(ext);
+ baseExt = "qdm_var_" + StringUtils.deleteWhitespace(baseExt);
+ localVarName = "qdm_var_" + StringUtils.deleteWhitespace(localVarName);
+ }
+ String extForOccurrenceNode =
+ "occ" + subTreeNode.getAttributes().getNamedItem("instance").getNodeValue() + "of_" + ext;
+ ext = StringUtils.deleteWhitespace(ext);
+ localVarName = StringUtils.deleteWhitespace(localVarName);
+ logger.debug(
+ "generateOccHQMF " + "//entry/*/id[@root='" + root + "'][@extension=\"" + baseExt + "\"]");
+
+ Node idNodeQDM =
+ hqmfXmlProcessor.findNode(
+ hqmfXmlProcessor.getOriginalDoc(),
+ "//entry/*/id[@root='" + root + "'][@extension=\"" + baseExt + "\"]");
+ logger.debug("idNodeQDM == null?" + (idNodeQDM == null));
+
+ if (idNodeQDM != null) {
+ // Add code here which will create a replica of the entry elem of 'idNodeQDM'
+ // and assign it an extension
+ // which has "Occ_X" string in it.
+ Node cloneMainEntryNode = idNodeQDM.getParentNode().getParentNode().cloneNode(true);
+ Node cloneIDNode = findNode(cloneMainEntryNode, "ID");
+ if (cloneMainEntryNode != null) {
+ Node localVariableNode = cloneMainEntryNode.getFirstChild();
+ if (localVariableNode.getAttributes().getNamedItem("value") != null) {
+ localVariableNode.getAttributes().getNamedItem("value").setNodeValue(localVarName);
+ }
+ }
+ cloneIDNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(extForOccurrenceNode);
+
+ Element dataCriteriaSectionElem =
+ (Element)
+ hqmfXmlProcessor.getOriginalDoc().getElementsByTagName(DATA_CRITERIA_SECTION).item(0);
+
+ dataCriteriaSectionElem.appendChild(cloneMainEntryNode);
+
+ Node parentNode = cloneIDNode.getParentNode().cloneNode(false);
+ if (isRAV) {
+ Comment RAComment =
+ hqmfXmlProcessor.getOriginalDoc().createComment("Risk Adjustment Variable");
+ dataCriteriaSectionElem.appendChild(RAComment);
+ }
+ Element entryElem = hqmfXmlProcessor.getOriginalDoc().createElement(ENTRY);
+ entryElem.setAttribute(TYPE_CODE, "DRIV");
+ Element idElement = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ idElement.setAttribute(ROOT, subTreeNode.getAttributes().getNamedItem(UUID).getNodeValue());
+ idElement.setAttribute(EXTENSION, extForOccurrenceNode);
+ parentNode.appendChild(idElement);
+ Element outboundRelElem =
+ hqmfXmlProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
+ outboundRelElem.setAttribute(TYPE_CODE, "OCCR");
+
+ Element criteriaRefElem = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ String refClassCodeValue = parentNode.getAttributes().getNamedItem(CLASS_CODE).getNodeValue();
+ String refMoodValue = parentNode.getAttributes().getNamedItem(MOOD_CODE).getNodeValue();
+ criteriaRefElem.setAttribute(CLASS_CODE, refClassCodeValue);
+ criteriaRefElem.setAttribute(MOOD_CODE, refMoodValue);
+
+ Element idRelElem = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ idRelElem.setAttribute(ROOT, root);
+ idRelElem.setAttribute(EXTENSION, extForOccurrenceNode);
+
+ criteriaRefElem.appendChild(idRelElem);
+ outboundRelElem.appendChild(criteriaRefElem);
+ parentNode.appendChild(outboundRelElem);
+ entryElem.appendChild(parentNode);
+ dataCriteriaSectionElem.appendChild(entryElem);
+
+ subTreeNodeMap.put(occSubTreeUUID, subTreeNode);
+ }
+ }
+
+ /**
+ * Generate functional op hqmf.
+ *
+ * @param functionalNode the functional node
+ * @param dataCriteriaSectionElem the data criteria section elem
+ * @param clauseName the clause name
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node generateFunctionalOpHQMF(
+ Node functionalNode, Element dataCriteriaSectionElem, String clauseName)
+ throws XPathExpressionException {
+ Node node = null;
+ if (functionalNode.getChildNodes() != null) {
+ Node firstChildNode = functionalNode.getFirstChild();
+ String firstChildName = firstChildNode.getNodeName();
+ switch (firstChildName) {
+ case SET_OP:
+ String functionOpType = functionalNode.getAttributes().getNamedItem(TYPE).getNodeValue();
+ if (FUNCTIONAL_OPS_NON_SUBSET.containsKey(functionOpType.toUpperCase())
+ || FUNCTIONAL_OPS_SUBSET.containsKey(functionOpType.toUpperCase())) {
+ node = generateSetOpHQMF(firstChildNode, dataCriteriaSectionElem, clauseName);
+ }
+ break;
+ case ELEMENT_REF:
+ node = generateElementRefHQMF(firstChildNode, dataCriteriaSectionElem, clauseName);
+ break;
+ case RELATIONAL_OP:
+ node = generateRelOpHQMF(firstChildNode, dataCriteriaSectionElem, clauseName);
+ break;
+ case FUNCTIONAL_OP:
+ // findFunctionalOpChild(firstChildNode, dataCriteriaSectionElem);
+ break;
+ case SUB_TREE_REF:
+ node =
+ generateSubTreeHQMFInFunctionalOp(
+ firstChildNode, dataCriteriaSectionElem, clauseName);
+ break;
+ default:
+ // Dont do anything
+ break;
+ }
+
+ String localVarName = clauseName;
+
+ localVarName = localVarName.replace("$", "");
+ Node parentNode = functionalNode.getParentNode();
+ if (parentNode != null && parentNode.getNodeName().equalsIgnoreCase("subTree")) {
+ if (parentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
+ String isQdmVariable =
+ parentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (TRUE.equalsIgnoreCase(isQdmVariable)) {
+ localVarName = localVarName.replace("$", "");
+ localVarName = "qdm_var_" + localVarName;
+ }
+ }
+ localVarName = localVarName + "_" + UUIDUtilClient.uuid(5);
+ localVarName = StringUtils.deleteWhitespace(localVarName);
+ updateLocalVar(node, localVarName);
+ }
+ }
+ return node;
+ }
+
+ /**
+ * Method to generate HQMF for function Ops with first child as subTreeRef. In this case
+ * grouperCriteria will be generated for SubTreeRef with Excerpt entry inside it for functional
+ * Op.
+ *
+ * @param firstChildNode - SubTreeRef Node.
+ * @param dataCriteriaSectionElem - Data Criteria Element.
+ * @param clauseName the clause name
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node generateSubTreeHQMFInFunctionalOp(
+ Node firstChildNode, Element dataCriteriaSectionElem, String clauseName)
+ throws XPathExpressionException {
+ Node parentNode = firstChildNode.getParentNode();
+
+ // temp node.
+ String subTreeUUID = firstChildNode.getAttributes().getNamedItem(ID).getNodeValue();
+ String xpath = "/measure/subTreeLookUp/subTree[@uuid='" + subTreeUUID + "']";
+ Node subTreeNode =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
+ String firstChildNameOfSubTree = subTreeNode.getFirstChild().getNodeName();
+ if (FUNCTIONAL_OP.equals(firstChildNameOfSubTree)) {
+ String firstChildNodeName = parentNode.getAttributes().getNamedItem(TYPE).getNodeValue();
+ if (!SATISFIES_ALL.equalsIgnoreCase(firstChildNodeName)
+ || !SATISFIES_ANY.equalsIgnoreCase(firstChildNodeName)
+ || !AGE_AT.equals(firstChildNodeName)) {
+ return null;
+ }
+ }
+ Element root = measureExport.getHqmfXmlProcessor().getOriginalDoc().createElement("temp");
+ generateSubTreeHQMF(firstChildNode, root, clauseName);
+ Element entryElement = (Element) root.getFirstChild();
+ Node firstChild = entryElement.getFirstChild();
+ if ("localVariableName".equals(firstChild.getNodeName())) {
+ firstChild = firstChild.getNextSibling();
+ }
+ Element excerpt =
+ generateExcerptEntryForFunctionalNode(
+ parentNode, null, measureExport.getHqmfXmlProcessor(), entryElement);
+ if (excerpt != null) {
+ firstChild.appendChild(excerpt);
+ }
+ dataCriteriaSectionElem.appendChild(entryElement);
+ return entryElement;
+ }
+
+ /**
+ * This will take care of the use case where a user can create a Clause with only one QDM
+ * elementRef inside it. We will make a copy of the original entry for QDM and update the id@root
+ * and id@extension for it. This will server as an entry for the Clause.
+ *
+ * @param elementRefNode the element ref node
+ * @param parentNode the parent node
+ * @param clauseName the clause name
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node generateElementRefHQMF(Node elementRefNode, Node parentNode, String clauseName)
+ throws XPathExpressionException {
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+ Node node = null;
+ String ext = getElementRefExt(elementRefNode, measureExport.getSimpleXmlProcessor());
+ String root = elementRefNode.getAttributes().getNamedItem(ID).getNodeValue();
+ String localVariableName = clauseName;
+ Node idNodeQDM =
+ hqmfXmlProcessor.findNode(
+ hqmfXmlProcessor.getOriginalDoc(),
+ "//entry/*/id[@root='" + root + "'][@extension=\"" + ext + "\"]");
+ if (idNodeQDM != null) {
+ Node entryElem = idNodeQDM.getParentNode().getParentNode().cloneNode(true);
+ Node newIdNode = getTagFromEntry(entryElem, ID);
+
+ if (newIdNode == null) {
+ return null;
+ }
+
+ String idroot = "0";
+ Node parNode = elementRefNode.getParentNode();
+ if (parNode != null && SUB_TREE.equals(parNode.getNodeName())) {
+ idroot = parNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ // Added logic to show qdm_variable in extension if clause is of qdm variable
+ // type.
+ String isQdmVariable = parNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (isQdmVariable.equalsIgnoreCase(TRUE)) {
+ String occText = null;
+ // Handled Occurrence Of QDM Variable.
+ if (parNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ occText = "occ" + parNode.getAttributes().getNamedItem(INSTANCE).getNodeValue() + "of_";
+ }
+ if (occText != null) {
+ ext = occText + "qdm_var_" + ext;
+ } else {
+ ext = "qdm_var_" + ext;
+ localVariableName = "qdm_var_" + localVariableName;
+ }
+ }
+ localVariableName = localVariableName + "_" + UUIDUtilClient.uuid(5);
+ localVariableName = StringUtils.deleteWhitespace(localVariableName);
+ ((Element) newIdNode).setAttribute(ROOT, idroot);
+ ((Element) newIdNode).setAttribute(EXTENSION, ext);
+ Node localVariableNode = entryElem.getFirstChild();
+ if (localVariableNode.getAttributes().getNamedItem("value") != null) {
+ localVariableNode.getAttributes().getNamedItem("value").setNodeValue(localVariableName);
+ }
+
+ parentNode.appendChild(entryElem);
+ node = entryElem;
+ } else {
+ // if the the parentNode for ElementRef is other than SubTreeNode
+ Element excerptElement = null;
+ Node subTreeParentNode = checkIfSubTree(parNode);
+ if (subTreeParentNode != null) {
+ root = subTreeParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ if (subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
+ String isQdmVariable =
+ subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (TRUE.equalsIgnoreCase(isQdmVariable)) {
+ String occText = null;
+ // Handled Occurrence Of QDM Variable.
+ if (subTreeParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ occText =
+ "occ"
+ + subTreeParentNode.getAttributes().getNamedItem("instance").getNodeValue()
+ + "of_";
+ }
+ if (occText != null) {
+ ext = occText + "qdm_var_" + ext;
+ } else {
+ ext = "qdm_var_" + ext;
+ }
+ }
+ }
+ } else {
+ root = java.util.UUID.randomUUID().toString();
+ }
+
+ Node entryNodeForElementRef = idNodeQDM.getParentNode().getParentNode();
+ Node clonedEntryNodeForElementRef = entryNodeForElementRef.cloneNode(true);
+ NodeList idChildNodeList =
+ ((Element) clonedEntryNodeForElementRef).getElementsByTagName(ID);
+ if (idChildNodeList != null && idChildNodeList.getLength() > 0) {
+ Node idChildNode = idChildNodeList.item(0);
+ idChildNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
+ idChildNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
+ }
+
+ Node firstChild = clonedEntryNodeForElementRef.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
+ firstChild = firstChild.getNextSibling();
+ }
+ // Added logic to show qdm_variable in extension if clause is of qdm variable
+ // type.
+ if (FUNCTIONAL_OP.equals(parNode.getNodeName())) {
+ excerptElement =
+ generateExcerptEntryForFunctionalNode(
+ parNode, elementRefNode, hqmfXmlProcessor, clonedEntryNodeForElementRef);
+ }
+
+ if (excerptElement != null) {
+
+ firstChild.appendChild(excerptElement);
+ }
+ parentNode.appendChild(clonedEntryNodeForElementRef);
+ node = clonedEntryNodeForElementRef;
+ }
+ updateLocalVar(node, ext);
+ }
+
+ return node;
+ }
+
+ /**
+ * This will take care of the use case where a user can create a Clause with only one child Clause
+ * inside it. If HQMF for the child clause is already generated, then since we have no way of
+ * referencing this child clause using directly, we are adding it to a
+ * default UNION grouper.
+ *
+ * If it isnt generated then we generate it and then add a criteriaRef to it inside a default
+ * UNION.
+ *
+ * @param subTreeRefNode the sub tree ref node
+ * @param parentNode the parent node
+ * @param clauseName the clause name
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node generateSubTreeHQMF(Node subTreeRefNode, Node parentNode, String clauseName)
+ throws XPathExpressionException {
+
+ String subTreeUUID = subTreeRefNode.getAttributes().getNamedItem(ID).getNodeValue();
+
+ /*
+ * Check if the Clause has already been generated. If it is not generated yet,
+ * then generate it by calling the 'generateSubTreeXML' method.
+ */
+ if (!subTreeNodeMap.containsKey(subTreeUUID)) {
+ String xpath = "/measure/subTreeLookUp/subTree[@uuid='" + subTreeUUID + "']";
+ Node subTreeNode =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
+ generateSubTreeXML(subTreeNode, false);
+ }
+
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+
+ // creating Entry Tag
+ Element entryElem = hqmfXmlProcessor.getOriginalDoc().createElement(ENTRY);
+ entryElem.setAttribute(TYPE_CODE, "DRIV");
+ String root = java.util.UUID.randomUUID().toString();
+ String ext = subTreeRefNode.getAttributes().getNamedItem(ID).getNodeValue();
+ String localVarName = clauseName;
+ localVarName = localVarName.replace("$", "");
+ Node parNode = checkIfSubTree(subTreeRefNode.getParentNode());
+ if (parNode != null) {
+ root = parNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ if (parNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
+ String isQdmVariable = parNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (TRUE.equalsIgnoreCase(isQdmVariable)) {
+ String occText = null;
+ // Handled Occurrence Of QDM Variable.
+ if (parNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ occText = "occ" + parNode.getAttributes().getNamedItem(INSTANCE).getNodeValue() + "of_";
+ }
+ if (occText != null) {
+ ext = occText + "qdm_var_" + ext;
+ } else {
+ ext = "qdm_var_" + ext;
+ localVarName = "qdm_var_" + localVarName;
+ }
+ }
+ }
+ }
+
+ Node grouperElem = generateEmptyGrouper(hqmfXmlProcessor, root, ext);
+
+ // generate comment
+ Comment comment =
+ hqmfXmlProcessor
+ .getOriginalDoc()
+ .createComment(
+ "outBoundRelationship for "
+ + subTreeRefNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ grouperElem.appendChild(comment);
+
+ // generate outboundRelationship
+ Element outboundRelElem = generateEmptyOutboundElem(hqmfXmlProcessor);
+ Element conjunctionCodeElem = hqmfXmlProcessor.getOriginalDoc().createElement(CONJUNCTION_CODE);
+ conjunctionCodeElem.setAttribute(CODE, "OR");
+
+ outboundRelElem.appendChild(conjunctionCodeElem);
+ generateCritRefForNode(outboundRelElem, subTreeRefNode);
+
+ grouperElem.appendChild(outboundRelElem);
+
+ Element localVarElem = hqmfXmlProcessor.getOriginalDoc().createElement(LOCAL_VARIABLE_NAME);
+ localVarName = localVarName + "_" + UUIDUtilClient.uuid(5);
+ localVarName = StringUtils.deleteWhitespace(localVarName);
+ localVarElem.setAttribute(VALUE, localVarName);
+ entryElem.appendChild(localVarElem);
+
+ entryElem.appendChild(grouperElem);
+ parentNode.appendChild(entryElem);
+ return entryElem;
+ }
+
+ /**
+ * This method wil generate HQMF code for setOp (UNION,INTERSECTION).
+ *
+ * @param setOpNode the set op node
+ * @param parentNode the parent node
+ * @param clauseName the clause name
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node generateSetOpHQMF(Node setOpNode, Node parentNode, String clauseName)
+ throws XPathExpressionException {
+
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+ // DISPLAY NAME is used instead of type as it is in Title case.
+ String setOpType = setOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ String conjunctionType = "OR";
+
+ if ("union".equalsIgnoreCase(setOpType) || SATISFIES_ANY.equalsIgnoreCase(setOpType)) {
+ conjunctionType = "OR";
+ } else if ("intersection".equalsIgnoreCase(setOpType)
+ || SATISFIES_ALL.equalsIgnoreCase(setOpType)) {
+ conjunctionType = "AND";
+ }
+
+ // creating Entry Tag
+ Element entryElem = hqmfXmlProcessor.getOriginalDoc().createElement(ENTRY);
+ entryElem.setAttribute(TYPE_CODE, "DRIV");
+
+ // creating grouperCriteria element
+ String root = "0";
+ // String ext = setOpType.toUpperCase();
+
+ String ext = setOpType + "_" + setOpNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ String localVariableName =
+ clauseName + "_" + setOpNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ Node subTreeParentNode = checkIfSubTree(setOpNode.getParentNode());
+ if (subTreeParentNode != null) {
+ root = subTreeParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ if (subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
+ String isQdmVariable =
+ subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (TRUE.equalsIgnoreCase(isQdmVariable)) {
+ String occText = null;
+ // Handled Occurrence Of QDM Variable.
+ if (subTreeParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ occText =
+ "occ"
+ + subTreeParentNode.getAttributes().getNamedItem(INSTANCE).getNodeValue()
+ + "of_";
+ }
+ if (occText != null) {
+ ext = occText + "qdm_var_" + ext;
+ } else {
+ ext = "qdm_var_" + ext;
+ }
+ localVariableName = "qdm_var_" + localVariableName;
+ }
+ }
+ } else {
+ root = java.util.UUID.randomUUID().toString();
+ }
+
+ Node grouperElem = generateEmptyGrouper(hqmfXmlProcessor, root, ext);
+ Node templateIdNode = getTemplateIdForSatisfies(hqmfXmlProcessor, setOpType);
+ if (templateIdNode != null) {
+ grouperElem.insertBefore(templateIdNode, grouperElem.getFirstChild());
+ }
+
+ NodeList childNodes = setOpNode.getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ Node childNode = childNodes.item(i);
+ String childName = childNode.getNodeName();
+ if ("comment".equals(childName)) {
+ continue;
+ }
+
+ // generate comment
+ Comment comment =
+ hqmfXmlProcessor
+ .getOriginalDoc()
+ .createComment(
+ "outBoundRelationship for "
+ + childNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ grouperElem.appendChild(comment);
+
+ // generate outboundRelationship
+ Element outboundRelElem = generateEmptyOutboundElem(hqmfXmlProcessor);
+ Element conjunctionCodeElem =
+ hqmfXmlProcessor.getOriginalDoc().createElement(CONJUNCTION_CODE);
+ conjunctionCodeElem.setAttribute(CODE, conjunctionType);
+
+ outboundRelElem.appendChild(conjunctionCodeElem);
+ if (ELEMENT_REF.equals(childName) || SUB_TREE_REF.equals(childName)) {
+ generateCritRefForNode(outboundRelElem, childNode);
+ } else {
+ switch (childName) {
+ case SET_OP:
+ generateCritRefSetOp(
+ parentNode, hqmfXmlProcessor, childNode, outboundRelElem, clauseName);
+ break;
+ case RELATIONAL_OP:
+ generateCritRefRelOp(
+ parentNode, hqmfXmlProcessor, childNode, outboundRelElem, clauseName);
+ break;
+ case FUNCTIONAL_OP:
+ generateCritRefFunctionalOp(childNode, outboundRelElem, clauseName);
+ break;
+
+ default:
+ // Dont do anything
+ break;
+ }
+ }
+ grouperElem.appendChild(outboundRelElem);
+ }
+
+ // Added logic to show qdm_variable in extension if clause is of qdm variable
+ // type.
+ Node grouperEntryNode = grouperElem.cloneNode(true);
+ if (FUNCTIONAL_OP.equals(setOpNode.getParentNode().getNodeName())) {
+ Element excerptElement =
+ generateExcerptEntryForFunctionalNode(
+ setOpNode.getParentNode(), null, hqmfXmlProcessor, grouperEntryNode);
+ // Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("excerpt
+ // for
+ // "+setOpNode.getParentNode().getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ // grouperElem.appendChild(comment);
+ grouperElem.appendChild(excerptElement);
+ }
+ Element localVarElem = hqmfXmlProcessor.getOriginalDoc().createElement(LOCAL_VARIABLE_NAME);
+ localVarElem.setAttribute(VALUE, StringUtils.deleteWhitespace(localVariableName));
+ entryElem.appendChild(localVarElem);
+
+ entryElem.appendChild(grouperElem);
+ parentNode.appendChild(entryElem);
+
+ return entryElem;
+ }
+
+ /**
+ * Generate crit ref functional op.
+ *
+ * @param childNode -Node
+ * @param outboundRelElem - outBoundElement
+ * @param clauseName the clause name
+ * @throws XPathExpressionException -Exception
+ */
+ private void generateCritRefFunctionalOp(
+ Node childNode, Element outboundRelElem, String clauseName) throws XPathExpressionException {
+ Element dataCriteriaSectionElem =
+ (Element)
+ measureExport
+ .getHqmfXmlProcessor()
+ .getOriginalDoc()
+ .getElementsByTagName(DATA_CRITERIA_SECTION)
+ .item(0);
+ Node entryNode = generateFunctionalOpHQMF(childNode, dataCriteriaSectionElem, clauseName);
+ if (entryNode != null && entryNode.getNodeName().equals(ENTRY)) {
+ Node fChild = entryNode.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(fChild.getNodeName())) {
+ fChild = fChild.getNextSibling();
+ }
+ // create criteriaRef
+ Element criteriaReference =
+ measureExport.getHqmfXmlProcessor().getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ criteriaReference.setAttribute(
+ CLASS_CODE, fChild.getAttributes().getNamedItem(CLASS_CODE).getNodeValue());
+ criteriaReference.setAttribute(
+ MOOD_CODE, fChild.getAttributes().getNamedItem(MOOD_CODE).getNodeValue());
+ NodeList childNodeList = fChild.getChildNodes();
+ for (int j = 0; j < childNodeList.getLength(); j++) {
+ Node entryChildNodes = childNodeList.item(j);
+ if (entryChildNodes.getNodeName().equalsIgnoreCase(ID)) {
+ Element id = measureExport.getHqmfXmlProcessor().getOriginalDoc().createElement(ID);
+ id.setAttribute(ROOT, entryChildNodes.getAttributes().getNamedItem(ROOT).getNodeValue());
+ id.setAttribute(
+ EXTENSION, entryChildNodes.getAttributes().getNamedItem(EXTENSION).getNodeValue());
+ criteriaReference.appendChild(id);
+ outboundRelElem.appendChild(criteriaReference);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * This method is used to create a tag for SATISFIES ALL/SATISFIES ANY functionalOps.
+ * These are functionalOp's but are converted to setOps and treated as Groupers.
+ *
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @param type the type
+ * @return the template id for satisfies
+ */
+ private Node getTemplateIdForSatisfies(XmlProcessor hqmfXmlProcessor, String type) {
+ Node templateIdNode = null;
+
+ if (SATISFIES_ALL.equalsIgnoreCase(type) || SATISFIES_ANY.equalsIgnoreCase(type)) {
+ templateIdNode = hqmfXmlProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
+ Element itemNode = hqmfXmlProcessor.getOriginalDoc().createElement(ITEM);
+
+ // initialize rootOID with the OID for SATISFIES ALL
+ String rootOID = "2.16.840.1.113883.10.20.28.3.109";
+ // if we are dealing with SATISFIES ANY change the OID
+ if (SATISFIES_ANY.equalsIgnoreCase(type)) {
+ rootOID = "2.16.840.1.113883.10.20.28.3.108";
+ }
+ itemNode.setAttribute(ROOT, rootOID);
+
+ templateIdNode.appendChild(itemNode);
+ }
+
+ return templateIdNode;
+ }
+
+ /**
+ * Generate rel op hqmf.
+ *
+ * @param relOpNode the rel op node
+ * @param dataCriteriaSectionElem the data criteria section elem
+ * @param clauseName the clause name
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node generateRelOpHQMF(Node relOpNode, Node dataCriteriaSectionElem, String clauseName)
+ throws XPathExpressionException {
+ Node finalNode = null;
+ if (relOpNode.getChildNodes().getLength() == 2) {
+ Node lhsNode = relOpNode.getFirstChild();
+ Node rhsNode = relOpNode.getLastChild();
+ String lhsName = lhsNode.getNodeName();
+
+ // NamedNodeMap attribMap = relOpNode.getAttributes();
+ // String relDisplayName =
+ // StringUtils.deleteWhitespace(attribMap.getNamedItem(DISPLAY_NAME).getNodeValue());
+ // String relUUID = attribMap.getNamedItem(UUID).getNodeValue();
+ // String localVarName = "localVar_"+relDisplayName+"_"+relUUID;
+
+ String localVarName = clauseName;
+ Node parentNode = relOpNode.getParentNode();
+ if (parentNode != null) {
+ if (parentNode.getNodeName().equalsIgnoreCase("subTree")
+ && parentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
+ String isQdmVariable =
+ parentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (TRUE.equalsIgnoreCase(isQdmVariable)) {
+ localVarName = localVarName.replace("$", "");
+ localVarName = "qdm_var_" + localVarName;
+ }
+ }
+ }
+ localVarName = localVarName + "_" + UUIDUtilClient.uuid(5);
+ localVarName = StringUtils.deleteWhitespace(localVarName);
+ if (ELEMENT_REF.equals(lhsName)) {
+ finalNode =
+ getrelOpLHSQDM(relOpNode, dataCriteriaSectionElem, lhsNode, rhsNode, clauseName);
+ } else if (RELATIONAL_OP.equals(lhsName)) {
+ finalNode =
+ getrelOpLHSRelOp(relOpNode, dataCriteriaSectionElem, lhsNode, rhsNode, clauseName);
+ Node relOpParentNode = relOpNode.getParentNode();
+ if (relOpParentNode.getNodeName().equalsIgnoreCase(FUNCTIONAL_OP)) {
+ Element excerptElement =
+ generateExcerptEntryForFunctionalNode(
+ relOpNode.getParentNode(),
+ lhsNode,
+ measureExport.getHqmfXmlProcessor(),
+ finalNode);
+ if (excerptElement != null) {
+ Node firstNode = finalNode.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(firstNode.getNodeName())) {
+ firstNode = firstNode.getNextSibling();
+ }
+ // Comment comment =
+ // measureExport.getHQMFXmlProcessor().getOriginalDoc().createComment("entry for
+ // "+relOpNode.getParentNode().getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ // firstNode.appendChild(comment);
+ firstNode.appendChild(excerptElement);
+ }
+ }
+ // return finalNode;
+ } else if (SET_OP.equals(lhsName)) {
+ finalNode =
+ getrelOpLHSSetOp(relOpNode, dataCriteriaSectionElem, lhsNode, rhsNode, clauseName);
+ Node relOpParentNode = relOpNode.getParentNode();
+ if (relOpParentNode.getNodeName().equalsIgnoreCase(FUNCTIONAL_OP)) {
+ Element excerptElement =
+ generateExcerptEntryForFunctionalNode(
+ relOpNode.getParentNode(),
+ lhsNode,
+ measureExport.getHqmfXmlProcessor(),
+ finalNode);
+ if (excerptElement != null) {
+ Node firstNode = finalNode.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(firstNode.getNodeName())) {
+ firstNode = firstNode.getNextSibling();
+ }
+ // Comment comment =
+ // measureExport.getHQMFXmlProcessor().getOriginalDoc().createComment("entry for
+ // "+relOpNode.getParentNode().getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ // firstNode.appendChild(comment);
+ firstNode.appendChild(excerptElement);
+ }
+ }
+ // return finalNode;
+ } else if (SUB_TREE_REF.equals(lhsName) || FUNCTIONAL_OP.equalsIgnoreCase(lhsName)) {
+ Node functionalOpNodeWithChildQDM = checkLHSFunctionalOpWithChildQDM(lhsNode);
+ if (functionalOpNodeWithChildQDM != null) {
+ // Do something godawful here.
+ Node functionEntryNode =
+ generateFunctionalOpHQMF(
+ functionalOpNodeWithChildQDM, (Element) dataCriteriaSectionElem, clauseName);
+ dataCriteriaSectionElem.appendChild(functionEntryNode);
+ finalNode =
+ createSpecialGrouperForRelOp(
+ relOpNode, functionEntryNode, rhsNode, dataCriteriaSectionElem, clauseName);
+ } else if (FUNCTIONAL_OP.equalsIgnoreCase(lhsName)) {
+ finalNode =
+ getFunctionalOpLHS(relOpNode, dataCriteriaSectionElem, lhsNode, rhsNode, clauseName);
+ } else {
+ finalNode =
+ getrelOpLHSSubtree(relOpNode, dataCriteriaSectionElem, lhsNode, rhsNode, clauseName);
+ }
+ }
+ // else if(FUNCTIONAL_OP.equalsIgnoreCase(lhsName)) {
+ // finalNode = getFunctionalOpLHS(relOpNode, dataCriteriaSectionElem, lhsNode,
+ // rhsNode, clauseName);
+ // }
+ if (parentNode.getNodeName().equalsIgnoreCase("subTree")) {
+ updateLocalVar(finalNode, localVarName);
+ }
+ } else {
+ logger.debug(
+ "Relational Op:"
+ + relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
+ + " does not have exactly 2 children. Skipping HQMF for it.");
+ }
+ return finalNode;
+ }
+
+ /**
+ * When we have a case of "First:(Encounter,Performed:Inpatient) During Measurement Period"; we
+ * need to generate a entry with Grouper.
+ *
+ * @param relOpNode the rel op node
+ * @param functionEntryNode the function entry node
+ * @param rhsNode the rhs node
+ * @param dataCriteriaSectionElem the data criteria section elem
+ * @param clauseName the clause name
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node createSpecialGrouperForRelOp(
+ Node relOpNode,
+ Node functionEntryNode,
+ Node rhsNode,
+ Node dataCriteriaSectionElem,
+ String clauseName)
+ throws XPathExpressionException {
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+
+ // creating Entry Tag
+ Element entryElem = hqmfXmlProcessor.getOriginalDoc().createElement(ENTRY);
+ entryElem.setAttribute(TYPE_CODE, "DRIV");
+
+ String localVariableName = relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ Element localVarElem = hqmfXmlProcessor.getOriginalDoc().createElement(LOCAL_VARIABLE_NAME);
+ localVariableName = localVariableName + "_" + UUIDUtilClient.uuid(5);
+ localVariableName = StringUtils.deleteWhitespace(localVariableName);
+ localVarElem.setAttribute(VALUE, localVariableName);
+ entryElem.appendChild(localVarElem);
+
+ String root = relOpNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ String ext =
+ StringUtils.deleteWhitespace(
+ relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
+ + "_"
+ + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
+
+ Node grouperElem = generateEmptyGrouper(hqmfXmlProcessor, root, ext);
+ entryElem.appendChild(grouperElem);
+
+ Node subTreeParentNode = checkIfSubTree(relOpNode.getParentNode());
+ Node idNode = findNode(entryElem, "ID");
+ if (idNode != null && subTreeParentNode != null) {
+ String idExtension = idNode.getAttributes().getNamedItem(EXTENSION).getNodeValue();
+ String idRoot = idNode.getAttributes().getNamedItem(ROOT).getNodeValue();
+ root = subTreeParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ ext =
+ StringUtils.deleteWhitespace(
+ relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
+ + "_"
+ + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
+ if (subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
+ String isQdmVariable =
+ subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (TRUE.equalsIgnoreCase(isQdmVariable)) {
+ String occText = null;
+ // Handled Occurrence Of QDM Variable.
+ if (subTreeParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ occText =
+ "occ"
+ + subTreeParentNode.getAttributes().getNamedItem(INSTANCE).getNodeValue()
+ + "of_";
+ }
+ if (occText != null) {
+ ext = occText + "qdm_var_" + ext;
+ } else {
+ ext = "qdm_var_" + ext;
+ }
+ }
+ }
+ idNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
+ idNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
+ // Updated Excerpt tag idNode root and extension.
+ // String hqmfXmlString = measureExport.getHQMFXmlProcessor().getOriginalXml();
+ Node idNodeExcerpt =
+ measureExport
+ .getHqmfXmlProcessor()
+ .findNode(
+ measureExport.getHqmfXmlProcessor().getOriginalDoc(),
+ "//entry/*/excerpt/*/id[@root='"
+ + idRoot
+ + "'][@extension=\""
+ + idExtension
+ + "\"]");
+ if (idNodeExcerpt != null) {
+ idNodeExcerpt.getAttributes().getNamedItem(ROOT).setNodeValue(root);
+ idNodeExcerpt.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
+ }
+ }
+
+ // Element temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode,
+ // measureExport.getHQMFXmlProcessor());
+ Element temporallyRelatedInfoNode = null;
+ if (!FULFILLS.equalsIgnoreCase(relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
+ temporallyRelatedInfoNode =
+ createBaseTemporalNode(relOpNode, measureExport.getHqmfXmlProcessor());
+ } else {
+ temporallyRelatedInfoNode =
+ measureExport.getHqmfXmlProcessor().getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
+ temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
+ }
+ handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
+ Node firstChild = entryElem.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
+ firstChild = firstChild.getNextSibling();
+ }
+ NodeList outBoundList = ((Element) firstChild).getElementsByTagName(OUTBOUND_RELATIONSHIP);
+ if (outBoundList != null && outBoundList.getLength() > 0) {
+ Node outBound = outBoundList.item(0);
+ firstChild.insertBefore(temporallyRelatedInfoNode, outBound);
+ } else {
+ NodeList excerptList = ((Element) firstChild).getElementsByTagName(EXCERPT);
+ if (excerptList != null && excerptList.getLength() > 0) {
+ Node excerptNode = excerptList.item(0);
+ firstChild.insertBefore(temporallyRelatedInfoNode, excerptNode);
+ } else {
+ firstChild.appendChild(temporallyRelatedInfoNode);
+ }
+ }
+
+ // Add a outBound Relationship for the 'functionEntryNode' passed above.
+ Element outBoundForFunction =
+ measureExport.getHqmfXmlProcessor().getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
+ outBoundForFunction.setAttribute(TYPE_CODE, "COMP");
+ Node idNodeForFunctionEntryNode = findNode(functionEntryNode, "ID");
+ Node excerptNodeForFunctionEntryNode = findNode(functionEntryNode, "excerpt");
+ Node idNodeInExcerptNode = findNode(excerptNodeForFunctionEntryNode, "id");
+ String newExtension =
+ StringUtils.deleteWhitespace(clauseName)
+ + "_"
+ + idNodeForFunctionEntryNode.getAttributes().getNamedItem(EXTENSION).getNodeValue();
+
+ idNodeForFunctionEntryNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(newExtension);
+ idNodeInExcerptNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(newExtension);
+
+ Node firstChildOfFunctionEntryElem = functionEntryNode.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(firstChildOfFunctionEntryElem.getNodeName())) {
+ firstChildOfFunctionEntryElem = firstChildOfFunctionEntryElem.getNextSibling();
+ }
+ NamedNodeMap criteriaNodeAttributeMap = firstChildOfFunctionEntryElem.getAttributes();
+ if (criteriaNodeAttributeMap.getNamedItem(CLASS_CODE) != null
+ && criteriaNodeAttributeMap.getNamedItem(MOOD_CODE) != null) {
+ // create criteriaRef
+ Element criteriaReference =
+ hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ criteriaReference.setAttribute(
+ CLASS_CODE, criteriaNodeAttributeMap.getNamedItem(CLASS_CODE).getNodeValue());
+ criteriaReference.setAttribute(
+ MOOD_CODE, criteriaNodeAttributeMap.getNamedItem(MOOD_CODE).getNodeValue());
+
+ Node idNodeForFunctionEntryNode_Clone = idNodeForFunctionEntryNode.cloneNode(true);
+ criteriaReference.appendChild(idNodeForFunctionEntryNode_Clone);
+
+ outBoundForFunction.appendChild(criteriaReference);
+ grouperElem.appendChild(outBoundForFunction);
+ }
+ dataCriteriaSectionElem.appendChild(entryElem);
+ return entryElem;
+ }
+
+ /**
+ * This is to be called when you want to check If the node passed is a FunctionOp with it's child
+ * being an elementRef/QDM. If the node passed is a SubTree/Clause node then this will
+ * "recursively" look into the child of that SubTree/Clause node to see if that child is a
+ * FunctionOp with child being an elementRef/QDM.
+ *
+ * @param node the node
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node checkLHSFunctionalOpWithChildQDM(Node node) throws XPathExpressionException {
+ Node returnFunctionalNode = null;
+
+ String nodeName = node.getNodeName();
+ if (FUNCTIONAL_OP.equalsIgnoreCase(nodeName)) {
+ returnFunctionalNode = node;
+ /*
+ * Node childNode = node.getFirstChild(); if(childNode != null &&
+ * ELEMENT_REF.equals(childNode.getNodeName())){ returnFunctionalNode = node; }
+ */
+ } else if (SUB_TREE_REF.equals(nodeName)) {
+ String subTreeUUID = node.getAttributes().getNamedItem(ID).getNodeValue();
+
+ String xpath = "/measure/subTreeLookUp/subTree[@uuid='" + subTreeUUID + "']";
+ Node subTreeNode =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
+
+ Node childNode = subTreeNode.getFirstChild();
+ if (childNode != null) {
+ returnFunctionalNode = checkLHSFunctionalOpWithChildQDM(childNode);
+ }
+ }
+ return returnFunctionalNode;
+ }
+
+ /**
+ * Gets the functional op lhs.
+ *
+ * @param relOpNode the rel op node
+ * @param dataCriteriaSectionElem the data criteria section elem
+ * @param lhsNode the lhs node
+ * @param rhsNode the rhs node
+ * @param clauseName the clause name
+ * @return the functional op lhs
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node getFunctionalOpLHS(
+ Node relOpNode, Node dataCriteriaSectionElem, Node lhsNode, Node rhsNode, String clauseName)
+ throws XPathExpressionException {
+ Node entryNode =
+ generateFunctionalOpHQMF(lhsNode, (Element) dataCriteriaSectionElem, clauseName);
+
+ // Comment comment =
+ // measureExport.getHQMFXmlProcessor().getOriginalDoc().createComment("entry for
+ // "+relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ // dataCriteriaSectionElem.appendChild(comment);
+ if (entryNode != null) {
+ Node subTreeParentNode = checkIfSubTree(relOpNode.getParentNode());
+ Node idNode = findNode(entryNode, "ID");
+ if (idNode != null && subTreeParentNode != null) {
+ String idExtension = idNode.getAttributes().getNamedItem(EXTENSION).getNodeValue();
+ String idRoot = idNode.getAttributes().getNamedItem(ROOT).getNodeValue();
+ String root = subTreeParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ String ext =
+ StringUtils.deleteWhitespace(
+ relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
+ + "_"
+ + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
+ if (subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
+ String isQdmVariable =
+ subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (TRUE.equalsIgnoreCase(isQdmVariable)) {
+ String occText = null;
+ // Handled Occurrence Of QDM Variable.
+ if (subTreeParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ occText =
+ "occ"
+ + subTreeParentNode.getAttributes().getNamedItem(INSTANCE).getNodeValue()
+ + "of_";
+ }
+ if (occText != null) {
+ ext = occText + "qdm_var_" + ext;
+ } else {
+ ext = "qdm_var_" + ext;
+ }
+ }
+ }
+ idNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
+ idNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
+ // Updated Excerpt tag idNode root and extension.
+ // String hqmfXmlString = measureExport.getHQMFXmlProcessor().getOriginalXml();
+ Node idNodeExcerpt =
+ measureExport
+ .getHqmfXmlProcessor()
+ .findNode(
+ measureExport.getHqmfXmlProcessor().getOriginalDoc(),
+ "//entry/*/excerpt/*/id[@root='"
+ + idRoot
+ + "'][@extension=\""
+ + idExtension
+ + "\"]");
+ if (idNodeExcerpt != null) {
+ idNodeExcerpt.getAttributes().getNamedItem(ROOT).setNodeValue(root);
+ idNodeExcerpt.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
+ }
+ }
+
+ // Element temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode,
+ // measureExport.getHQMFXmlProcessor());
+ Element temporallyRelatedInfoNode = null;
+ if (!FULFILLS.equalsIgnoreCase(relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
+ temporallyRelatedInfoNode =
+ createBaseTemporalNode(relOpNode, measureExport.getHqmfXmlProcessor());
+ } else {
+ temporallyRelatedInfoNode =
+ measureExport
+ .getHqmfXmlProcessor()
+ .getOriginalDoc()
+ .createElement(OUTBOUND_RELATIONSHIP);
+ temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
+ }
+ handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
+ Node firstChild = entryNode.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
+ firstChild = firstChild.getNextSibling();
+ }
+ NodeList outBoundList = ((Element) firstChild).getElementsByTagName(OUTBOUND_RELATIONSHIP);
+ if (outBoundList != null && outBoundList.getLength() > 0) {
+ Node outBound = outBoundList.item(0);
+ firstChild.insertBefore(temporallyRelatedInfoNode, outBound);
+ } else {
+ NodeList excerptList = ((Element) firstChild).getElementsByTagName(EXCERPT);
+ if (excerptList != null && excerptList.getLength() > 0) {
+ Node excerptNode = excerptList.item(0);
+ firstChild.insertBefore(temporallyRelatedInfoNode, excerptNode);
+ } else {
+ firstChild.appendChild(temporallyRelatedInfoNode);
+ }
+ }
+ dataCriteriaSectionElem.appendChild(entryNode);
+ }
+ /*
+ * else{ Comment commnt = measureExport.getHQMFXmlProcessor().getOriginalDoc().
+ * createComment("CHECK:Could not find an entry for functionalOp:"+lhsNode.
+ * getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ * dataCriteriaSectionElem.appendChild(commnt); }
+ */
+ return entryNode;
+ }
+
+ /**
+ * Find node.
+ *
+ * @param criteriaNodeInEntry the criteria node in entry
+ * @param nodeName the node name
+ * @return idNode
+ */
+ private Node findNode(Node criteriaNodeInEntry, String nodeName) {
+ Node idNode = null;
+ for (int i = 0; i < criteriaNodeInEntry.getChildNodes().getLength(); i++) {
+ Node childNode = criteriaNodeInEntry.getChildNodes().item(i);
+ String childNodeName = childNode.getNodeName();
+ if (childNodeName.contains("Criteria")) {
+ NodeList criteriaChildNodes = childNode.getChildNodes();
+ for (int j = 0; j < criteriaChildNodes.getLength(); j++) {
+ Node criteriaChildNode = criteriaChildNodes.item(j);
+ if (nodeName.equalsIgnoreCase(criteriaChildNode.getNodeName())) {
+ idNode = criteriaChildNode;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ return idNode;
+ }
+
+ /**
+ * Gets the rel op lhs subtree.
+ *
+ * @param relOpNode the rel op node
+ * @param dataCriteriaSectionElem the data criteria section elem
+ * @param lhsNode the lhs node
+ * @param rhsNode the rhs node
+ * @param clauseName the clause name
+ * @return the rel op lhs subtree
+ */
+ private Node getrelOpLHSSubtree(
+ Node relOpNode, Node dataCriteriaSectionElem, Node lhsNode, Node rhsNode, String clauseName) {
+
+ try {
+ String subTreeUUID = lhsNode.getAttributes().getNamedItem(ID).getNodeValue();
+ String root = subTreeUUID;
+
+ Node relOpParentNode = relOpNode.getParentNode();
+
+ String xpath = "/measure/subTreeLookUp/subTree[@uuid='" + subTreeUUID + "']";
+ Node subTreeNode =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
+ if (subTreeNode != null) {
+ /**
+ * Check if the Clause has already been generated. If it is not generated yet, then generate
+ * it by calling the 'generateSubTreeXML' method.
+ */
+ if (!subTreeNodeMap.containsKey(subTreeUUID)) {
+ generateSubTreeXML(subTreeNode, false);
+ }
+ String isQdmVariable =
+ subTreeNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ Node firstChild = subTreeNode.getFirstChild();
+ String firstChildName = firstChild.getNodeName();
+
+ String ext =
+ StringUtils.deleteWhitespace(
+ firstChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ if (FUNCTIONAL_OP.equals(firstChildName)
+ || RELATIONAL_OP.equals(firstChildName)
+ || SET_OP.equals(firstChildName)) {
+ ext += "_" + firstChild.getAttributes().getNamedItem(UUID).getNodeValue();
+ }
+
+ if (ELEMENT_REF.equals(firstChildName)) {
+ ext = getElementRefExt(firstChild, measureExport.getSimpleXmlProcessor());
+ } else if (FUNCTIONAL_OP.equals(firstChildName)) {
+ if (firstChild.getFirstChild() != null) {
+ Node functionChild = firstChild.getFirstChild();
+ if (functionChild != null) {
+ if (functionChild.getNodeName().equalsIgnoreCase(SUB_TREE_REF)) {
+ ext = functionChild.getAttributes().getNamedItem(ID).getNodeValue();
+ } else if (functionChild.getNodeName().equalsIgnoreCase(ELEMENT_REF)) {
+ ext = getElementRefExt(functionChild, measureExport.getSimpleXmlProcessor());
+ } else {
+ ext =
+ StringUtils.deleteWhitespace(
+ functionChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
+ + "_"
+ + functionChild.getAttributes().getNamedItem(UUID).getNodeValue())
+ .replaceAll(":", "_");
+ }
+ }
+ }
+ }
+ if (TRUE.equalsIgnoreCase(isQdmVariable)) {
+ String occText = null;
+ // Handled Occurrence Of QDM Variable.
+ if (subTreeNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ occText =
+ "occ" + subTreeNode.getAttributes().getNamedItem("instance").getNodeValue() + "of_";
+ }
+ if (occText != null) {
+ ext = occText + "qdm_var_" + ext;
+ } else {
+ ext = "qdm_var_" + ext;
+ }
+ }
+
+ Node idNodeQDM =
+ measureExport
+ .getHqmfXmlProcessor()
+ .findNode(
+ measureExport.getHqmfXmlProcessor().getOriginalDoc(),
+ "//entry/*/id[@root='" + root + "'][@extension=\"" + ext + "\"]");
+ if (idNodeQDM != null) {
+ String newExt =
+ StringUtils.deleteWhitespace(
+ relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
+ + "_"
+ + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
+ if (relOpParentNode != null && SUB_TREE.equals(relOpParentNode.getNodeName())) {
+ root = relOpParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ Node qdmVarNode = relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE);
+ if (qdmVarNode != null) {
+ String isQdmVar =
+ relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (TRUE.equalsIgnoreCase(isQdmVar)) {
+ String occText = null;
+ // Handled Occurrence Of QDM Variable.
+ if (relOpParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ occText =
+ "occ"
+ + relOpParentNode.getAttributes().getNamedItem("instance").getNodeValue()
+ + "of_";
+ }
+ if (occText != null) {
+ newExt = occText + "qdm_var_" + newExt;
+ } else {
+ newExt = "qdm_var_" + newExt;
+ }
+ }
+ }
+ } else {
+ Node tempParentNode = checkIfParentSubTree(relOpParentNode);
+ if (tempParentNode != null) {
+ root = tempParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ }
+ }
+
+ Node parent = idNodeQDM.getParentNode();
+ Node isOcc = subTreeNode.getAttributes().getNamedItem(INSTANCE_OF);
+ Node newEntryNode = null;
+
+ if (TRUE.equals(isQdmVariable) && isOcc == null) {
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+ // creating Entry Tag
+ Element entryElem = hqmfXmlProcessor.getOriginalDoc().createElement(ENTRY);
+ entryElem.setAttribute(TYPE_CODE, "DRIV");
+ // create empty grouperCriteria
+ Node grouperElem = generateEmptyGrouper(hqmfXmlProcessor, root, newExt);
+
+ // generate outboundRelationship
+ Element outboundRelElem = generateEmptyOutboundElem(hqmfXmlProcessor);
+
+ NamedNodeMap attribMap = parent.getAttributes();
+ String classCode = attribMap.getNamedItem(CLASS_CODE).getNodeValue();
+ String moodCode = attribMap.getNamedItem(MOOD_CODE).getNodeValue();
+
+ // create criteriaRef
+ Element criteriaReference =
+ hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ criteriaReference.setAttribute(CLASS_CODE, classCode);
+ criteriaReference.setAttribute(MOOD_CODE, moodCode);
+
+ Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ id.setAttribute(ROOT, subTreeUUID);
+ id.setAttribute(EXTENSION, ext);
+
+ criteriaReference.appendChild(id);
+ outboundRelElem.appendChild(criteriaReference);
+
+ Element localVarElem =
+ hqmfXmlProcessor.getOriginalDoc().createElement(LOCAL_VARIABLE_NAME);
+ localVarElem.setAttribute(VALUE, ext);
+ entryElem.appendChild(localVarElem);
+
+ grouperElem.appendChild(outboundRelElem);
+ entryElem.appendChild(grouperElem);
+
+ newEntryNode = entryElem;
+ } else {
+ Node entryNodeForSubTree = idNodeQDM.getParentNode().getParentNode();
+ newEntryNode = entryNodeForSubTree.cloneNode(true);
+
+ NodeList idChildNodeList = ((Element) newEntryNode).getElementsByTagName(ID);
+ if (idChildNodeList != null && idChildNodeList.getLength() > 0) {
+ Node idChildNode = idChildNodeList.item(0);
+ idChildNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(newExt);
+ idChildNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
+ }
+ }
+
+ // Element temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode,
+ // measureExport.getHQMFXmlProcessor());
+ Element temporallyRelatedInfoNode = null;
+ if (!FULFILLS.equalsIgnoreCase(
+ relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
+ temporallyRelatedInfoNode =
+ createBaseTemporalNode(relOpNode, measureExport.getHqmfXmlProcessor());
+ } else {
+ temporallyRelatedInfoNode =
+ measureExport
+ .getHqmfXmlProcessor()
+ .getOriginalDoc()
+ .createElement(OUTBOUND_RELATIONSHIP);
+ temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
+ }
+
+ handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
+
+ Node firstNode = newEntryNode.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(firstNode.getNodeName())) {
+ firstNode = firstNode.getNextSibling();
+ }
+ NodeList outBoundList = ((Element) firstNode).getElementsByTagName(OUTBOUND_RELATIONSHIP);
+ if (outBoundList != null && outBoundList.getLength() > 0) {
+ Node outBound = outBoundList.item(0);
+ firstNode.insertBefore(temporallyRelatedInfoNode, outBound);
+ } else {
+ firstNode.appendChild(temporallyRelatedInfoNode);
+ }
+ // Entry for Functional Op.
+ if (FUNCTIONAL_OP.equals(relOpParentNode.getNodeName())) {
+ Element excerptElement =
+ generateExcerptEntryForFunctionalNode(
+ relOpParentNode,
+ lhsNode,
+ measureExport.getHqmfXmlProcessor(),
+ firstNode.getParentNode());
+ if (excerptElement != null) {
+ // Comment comment =
+ // measureExport.getHQMFXmlProcessor().getOriginalDoc().createComment("entry for
+ // "+relOpParentNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ // firstNode.appendChild(comment);
+ firstNode.appendChild(excerptElement);
+ }
+ }
+ // create comment node
+ // Comment comment =
+ // measureExport.getHQMFXmlProcessor().getOriginalDoc().createComment("entry for
+ // "+relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ // dataCriteriaSectionElem.appendChild(comment);
+ dataCriteriaSectionElem.appendChild(newEntryNode);
+ return newEntryNode;
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Gets the rel op lhs set op.
+ *
+ * @param relOpNode the rel op node
+ * @param dataCriteriaSectionElem the data criteria section elem
+ * @param lhsNode the lhs node
+ * @param rhsNode the rhs node
+ * @param clauseName the clause name
+ * @return the rel op lhs set op
+ */
+ private Node getrelOpLHSSetOp(
+ Node relOpNode, Node dataCriteriaSectionElem, Node lhsNode, Node rhsNode, String clauseName) {
+
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+ // Node relOpParentNode = relOpNode.getParentNode();
+
+ try {
+ Node setOpEntryNode = generateSetOpHQMF(lhsNode, dataCriteriaSectionElem, clauseName);
+ // Element temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode,
+ // hqmfXmlProcessor);
+ Node relOpParentNode = checkIfSubTree(relOpNode.getParentNode());
+ if (relOpParentNode != null) {
+ NodeList idChildNodeList = ((Element) setOpEntryNode).getElementsByTagName(ID);
+ if (idChildNodeList != null && idChildNodeList.getLength() > 0) {
+ Node idChildNode = idChildNodeList.item(0);
+ String root = relOpParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ String ext =
+ StringUtils.deleteWhitespace(
+ relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
+ + "_"
+ + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
+ if (relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
+ String isQdmVariable =
+ relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (TRUE.equalsIgnoreCase(isQdmVariable)) {
+ String occText = null;
+ // Handled Occurrence Of QDM Variable.
+ if (relOpParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ occText =
+ "occ"
+ + relOpParentNode.getAttributes().getNamedItem(INSTANCE).getNodeValue()
+ + "of_";
+ }
+ if (occText != null) {
+ ext = occText + "qdm_var_" + ext;
+ } else {
+ ext = "qdm_var_" + ext;
+ }
+ }
+ }
+ idChildNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
+ idChildNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
+ }
+ }
+ Element temporallyRelatedInfoNode = null;
+ if (!FULFILLS.equalsIgnoreCase(relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
+ temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode, hqmfXmlProcessor);
+ } else {
+ temporallyRelatedInfoNode =
+ hqmfXmlProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
+ temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
+ }
+ handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
+
+ Node firstChild = setOpEntryNode.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
+ firstChild = firstChild.getNextSibling();
+ }
+ NodeList outBoundList = ((Element) firstChild).getElementsByTagName(OUTBOUND_RELATIONSHIP);
+ if (outBoundList != null && outBoundList.getLength() > 0) {
+ Node outBound = outBoundList.item(0);
+ firstChild.insertBefore(temporallyRelatedInfoNode, outBound);
+ } else {
+ firstChild.appendChild(temporallyRelatedInfoNode);
+ }
+
+ // create comment node
+ // Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("entry for
+ // "+relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ // dataCriteriaSectionElem.appendChild(comment);
+ dataCriteriaSectionElem.appendChild(setOpEntryNode);
+ return setOpEntryNode;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets the rel op lhs rel op.
+ *
+ * @param relOpNode the rel op node
+ * @param dataCriteriaSectionElem the data criteria section elem
+ * @param lhsNode the lhs node
+ * @param rhsNode the rhs node
+ * @param clauseName the clause name
+ * @return the rel op lhs rel op
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node getrelOpLHSRelOp(
+ Node relOpNode, Node dataCriteriaSectionElem, Node lhsNode, Node rhsNode, String clauseName)
+ throws XPathExpressionException {
+
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+ // Node relOpParentNode = relOpNode.getParentNode();
+
+ try {
+ Node relOpEntryNode = generateRelOpHQMF(lhsNode, dataCriteriaSectionElem, clauseName);
+ /*
+ * Element temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode,
+ * hqmfXmlProcessor);
+ */
+
+ Node relOpParentNode = checkIfSubTree(relOpNode.getParentNode());
+
+ if (relOpParentNode != null) {
+ NodeList idChildNodeList = ((Element) relOpEntryNode).getElementsByTagName(ID);
+
+ if (idChildNodeList != null && idChildNodeList.getLength() > 0) {
+ Node idChildNode = idChildNodeList.item(0);
+ String root = relOpParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ String ext =
+ StringUtils.deleteWhitespace(
+ relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
+ + "_"
+ + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
+ if (relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
+ String isQdmVariable =
+ relOpParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (TRUE.equalsIgnoreCase(isQdmVariable)) {
+ String occText = null;
+ // Handled Occurrence Of QDM Variable.
+ if (relOpParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ occText =
+ "occ"
+ + relOpParentNode.getAttributes().getNamedItem("instance").getNodeValue()
+ + "of_";
+ }
+ if (occText != null) {
+ ext = occText + "qdm_var_" + ext;
+ } else {
+ ext = "qdm_var_" + ext;
+ }
+ }
+ }
+ idChildNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
+ idChildNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
+ }
+ }
+ Element temporallyRelatedInfoNode = null;
+ if (!FULFILLS.equalsIgnoreCase(relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
+ temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode, hqmfXmlProcessor);
+ } else {
+ temporallyRelatedInfoNode =
+ hqmfXmlProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
+ temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
+ }
+
+ handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
+
+ Node firstChild = relOpEntryNode.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
+ firstChild = firstChild.getNextSibling();
+ }
+ NodeList outBoundList = ((Element) firstChild).getElementsByTagName(OUTBOUND_RELATIONSHIP);
+ if (outBoundList != null && outBoundList.getLength() > 0) {
+ Node outBound = outBoundList.item(0);
+ firstChild.insertBefore(temporallyRelatedInfoNode, outBound);
+ } else {
+ firstChild.appendChild(temporallyRelatedInfoNode);
+ }
+ // create comment node
+ // Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("entry for
+ // "+relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ // dataCriteriaSectionElem.appendChild(comment);
+ dataCriteriaSectionElem.appendChild(relOpEntryNode);
+ return relOpEntryNode;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets the rel op lhsqdm.
+ *
+ * @param relOpNode the rel op node
+ * @param dataCriteriaSectionElem the data criteria section elem
+ * @param lhsNode the lhs node
+ * @param rhsNode the rhs node
+ * @param clauseName the clause name
+ * @return the rel op lhsqdm
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node getrelOpLHSQDM(
+ Node relOpNode, Node dataCriteriaSectionElem, Node lhsNode, Node rhsNode, String clauseName)
+ throws XPathExpressionException {
+
+ String ext = getElementRefExt(lhsNode, measureExport.getSimpleXmlProcessor());
+ String root = lhsNode.getAttributes().getNamedItem(ID).getNodeValue();
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+ Node relOpParentNode = relOpNode.getParentNode();
+ Element excerptElement = null;
+ Node idNodeQDM =
+ hqmfXmlProcessor.findNode(
+ hqmfXmlProcessor.getOriginalDoc(),
+ "//entry/*/id[@root='" + root + "'][@extension=\"" + ext + "\"]");
+
+ if (relOpParentNode != null && idNodeQDM != null) {
+ ext =
+ StringUtils.deleteWhitespace(
+ relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
+ + "_"
+ + relOpNode.getAttributes().getNamedItem(UUID).getNodeValue());
+ Node subTreeParentNode = checkIfSubTree(relOpParentNode);
+ if (subTreeParentNode != null) {
+ root = subTreeParentNode.getAttributes().getNamedItem(UUID).getNodeValue();
+ if (subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE) != null) {
+ String isQdmVariable =
+ subTreeParentNode.getAttributes().getNamedItem(QDM_VARIABLE).getNodeValue();
+ if (TRUE.equalsIgnoreCase(isQdmVariable)) {
+ String occText = null;
+ // Handled Occurrence Of QDM Variable.
+ if (relOpParentNode.getAttributes().getNamedItem(INSTANCE_OF) != null) {
+ occText =
+ "occ"
+ + relOpParentNode.getAttributes().getNamedItem("instance").getNodeValue()
+ + "of_";
+ }
+ if (occText != null) {
+ ext = occText + "qdm_var_" + ext;
+ } else {
+ ext = "qdm_var_" + ext;
+ }
+ }
+ }
+ }
+
+ Node entryNodeForElementRef = idNodeQDM.getParentNode().getParentNode();
+ Node clonedEntryNodeForElementRef = entryNodeForElementRef.cloneNode(true);
+ /*
+ * Element localVarName = (Element)
+ * ((Element)clonedEntryNodeForElementRef).getElementsByTagName(
+ * "localVariableName").item(0);
+ * localVarName.setAttribute(VALUE,findSubTreeDisplayName(lhsNode));
+ */
+ NodeList idChildNodeList = ((Element) clonedEntryNodeForElementRef).getElementsByTagName(ID);
+ updateLocalVar(clonedEntryNodeForElementRef, ext);
+ if (idChildNodeList != null && idChildNodeList.getLength() > 0) {
+ Node idChildNode = idChildNodeList.item(0);
+ idChildNode.getAttributes().getNamedItem(EXTENSION).setNodeValue(ext);
+ idChildNode.getAttributes().getNamedItem(ROOT).setNodeValue(root);
+ }
+
+ // Added logic to show qdm_variable in extension if clause is of qdm variable
+ // type.
+ if (FUNCTIONAL_OP.equals(relOpParentNode.getNodeName())) {
+ excerptElement =
+ generateExcerptEntryForFunctionalNode(
+ relOpParentNode, lhsNode, hqmfXmlProcessor, clonedEntryNodeForElementRef);
+ }
+ Element temporallyRelatedInfoNode = null;
+ if (!FULFILLS.equalsIgnoreCase(relOpNode.getAttributes().getNamedItem(TYPE).getNodeValue())) {
+ temporallyRelatedInfoNode = createBaseTemporalNode(relOpNode, hqmfXmlProcessor);
+ generateTemporalAttribute(
+ hqmfXmlProcessor,
+ lhsNode,
+ temporallyRelatedInfoNode,
+ clonedEntryNodeForElementRef,
+ true);
+ } else {
+ temporallyRelatedInfoNode =
+ hqmfXmlProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
+ temporallyRelatedInfoNode.setAttribute(TYPE_CODE, "FLFS");
+ }
+ handleRelOpRHS(rhsNode, temporallyRelatedInfoNode, clauseName);
+ Node firstChild = clonedEntryNodeForElementRef.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
+ firstChild = firstChild.getNextSibling();
+ }
+ NodeList outBoundList = ((Element) firstChild).getElementsByTagName(OUTBOUND_RELATIONSHIP);
+ if (outBoundList != null && outBoundList.getLength() > 0) {
+ Node outBound = outBoundList.item(0);
+ firstChild.insertBefore(temporallyRelatedInfoNode, outBound);
+ } else {
+ firstChild.appendChild(temporallyRelatedInfoNode);
+ }
+
+ if (excerptElement != null) {
+ // Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("excerpt
+ // for
+ // "+relOpParentNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ // firstChild.appendChild(comment);
+ firstChild.appendChild(excerptElement);
+ }
+ // create comment node
+ // Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("entry for
+ // "+relOpNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ // dataCriteriaSectionElem.appendChild(comment);
+ dataCriteriaSectionElem.appendChild(clonedEntryNodeForElementRef);
+ return clonedEntryNodeForElementRef;
+ }
+ return null;
+ }
+
+ /**
+ * Handle rel op rhs.
+ *
+ * @param rhsNode the rhs node
+ * @param temporallyRelatedInfoNode the temporally related info node
+ * @param clauseName the clause name
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void handleRelOpRHS(Node rhsNode, Element temporallyRelatedInfoNode, String clauseName)
+ throws XPathExpressionException {
+
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+ String rhsName = rhsNode.getNodeName();
+ Node dataCritSectionNode =
+ hqmfXmlProcessor.findNode(
+ temporallyRelatedInfoNode.getOwnerDocument(), "//dataCriteriaSection");
+
+ if (ELEMENT_REF.equals(rhsName)) {
+ Node entryNode =
+ generateCritRefElementRef(
+ temporallyRelatedInfoNode, rhsNode, measureExport.getHqmfXmlProcessor());
+ generateTemporalAttribute(
+ hqmfXmlProcessor, rhsNode, temporallyRelatedInfoNode, entryNode, false);
+ } else if (SUB_TREE_REF.equals(rhsName)) {
+ generateCritRefForNode(temporallyRelatedInfoNode, rhsNode);
+ } else {
+ switch (rhsName) {
+ case SET_OP:
+ generateCritRefSetOp(
+ dataCritSectionNode,
+ hqmfXmlProcessor,
+ rhsNode,
+ temporallyRelatedInfoNode,
+ clauseName);
+ break;
+ case RELATIONAL_OP:
+ generateRelOpHQMF(rhsNode, temporallyRelatedInfoNode, clauseName);
+ Node lastChild = temporallyRelatedInfoNode.getLastChild();
+ if (lastChild.getNodeName().equals(ENTRY)) {
+ temporallyRelatedInfoNode.removeChild(lastChild);
+
+ Node fChild = lastChild.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(fChild.getNodeName())) {
+ fChild = fChild.getNextSibling();
+ }
+
+ Node criteriaNode = fChild;
+ // temporallyRelatedInfoNode.appendChild(criteriaNode);
+ dataCritSectionNode.appendChild(lastChild);
+ // create criteriaRef
+ Element criteriaReference =
+ hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ criteriaReference.setAttribute(
+ CLASS_CODE, criteriaNode.getAttributes().getNamedItem(CLASS_CODE).getNodeValue());
+ criteriaReference.setAttribute(
+ MOOD_CODE, criteriaNode.getAttributes().getNamedItem(MOOD_CODE).getNodeValue());
+
+ NodeList childNodeList = criteriaNode.getChildNodes();
+ for (int i = 0; i < childNodeList.getLength(); i++) {
+ Node childNode = childNodeList.item(i);
+ if (childNode.getNodeName().equalsIgnoreCase(ID)) {
+ Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ id.setAttribute(ROOT, childNode.getAttributes().getNamedItem(ROOT).getNodeValue());
+ id.setAttribute(
+ EXTENSION, childNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
+ criteriaReference.appendChild(id);
+ temporallyRelatedInfoNode.appendChild(criteriaReference);
+ break;
+ }
+ }
+
+ NodeList childTemporalNodeList =
+ ((Element) criteriaNode).getElementsByTagName("temporallyRelatedInformation");
+ if (childTemporalNodeList != null && childTemporalNodeList.getLength() > 0) {
+ Node childTemporalNode = childTemporalNodeList.item(0);
+ Node temporalInfoNode = childTemporalNode.getFirstChild();
+ // find sourceAttribute
+ NodeList childs = temporalInfoNode.getChildNodes();
+ for (int c = 0; c < childs.getLength(); c++) {
+ Node child = childs.item(c);
+ String childName = child.getNodeName();
+ if ("qdm:sourceAttribute".equals(childName)) {
+ Node cloneAttNode = child.cloneNode(true);
+ temporallyRelatedInfoNode.getFirstChild().appendChild(cloneAttNode);
+ hqmfXmlProcessor
+ .getOriginalDoc()
+ .renameNode(cloneAttNode, "", "qdm:targetAttribute");
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case FUNCTIONAL_OP:
+ Node entryNode =
+ generateFunctionalOpHQMF(rhsNode, (Element) dataCritSectionNode, clauseName);
+ if (entryNode != null && entryNode.getNodeName().equals(ENTRY)) {
+ Node fChild = entryNode.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(fChild.getNodeName())) {
+ fChild = fChild.getNextSibling();
+ }
+ // create criteriaRef
+ Element criteriaReference =
+ hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ criteriaReference.setAttribute(
+ CLASS_CODE, fChild.getAttributes().getNamedItem(CLASS_CODE).getNodeValue());
+ criteriaReference.setAttribute(
+ MOOD_CODE, fChild.getAttributes().getNamedItem(MOOD_CODE).getNodeValue());
+ NodeList childNodeList = fChild.getChildNodes();
+ for (int i = 0; i < childNodeList.getLength(); i++) {
+ Node childNode = childNodeList.item(i);
+ if (childNode.getNodeName().equalsIgnoreCase(ID)) {
+ Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ id.setAttribute(ROOT, childNode.getAttributes().getNamedItem(ROOT).getNodeValue());
+ id.setAttribute(
+ EXTENSION, childNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
+ criteriaReference.appendChild(id);
+ temporallyRelatedInfoNode.appendChild(criteriaReference);
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ // Dont do anything
+ break;
+ }
+ }
+ }
+
+ /**
+ * Generate temporal attribute.
+ *
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @param rhsNode the rhs node
+ * @param temporallyRelatedInfoNode the temporally related info node
+ * @param entryNode the entry node
+ * @param isSource the is source
+ * @return the node
+ */
+ private Node generateTemporalAttribute(
+ XmlProcessor hqmfXmlProcessor,
+ Node rhsNode,
+ Element temporallyRelatedInfoNode,
+ Node entryNode,
+ boolean isSource) {
+ if (entryNode != null) {
+ Element entryElement = (Element) entryNode;
+
+ if (!rhsNode.hasChildNodes()) {
+ return null;
+ } else {
+ Node child = rhsNode.getFirstChild();
+ if (!"attribute".equals(child.getNodeName())) {
+ return null;
+ }
+
+ String value = child.getAttributes().getNamedItem(NAME).getNodeValue();
+ List validAttribNames = new ArrayList<>();
+ validAttribNames.add("incision datetime");
+ validAttribNames.add("facility location arrival datetime");
+ validAttribNames.add("facility location departure datetime");
+ validAttribNames.add("recorded datetime");
+ validAttribNames.add("signed datetime");
+ validAttribNames.add("start datetime");
+ validAttribNames.add("stop datetime");
+ if (!validAttribNames.contains(value)) {
+ return null;
+ }
+ if ("start datetime".equals(value) || "stop datetime".equals(value)) {
+ String dataType = rhsNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ if (!dataType.endsWith("Order")) {
+ return null;
+ }
+ }
+
+ // create sourceAttribute/targetAttribute
+ String attribName = "qdm:sourceAttribute";
+ if (!isSource) {
+ attribName = "qdm:targetAttribute";
+ }
+ Element attribute = hqmfXmlProcessor.getOriginalDoc().createElement(attribName);
+ attribute.setAttribute(NAME, value);
+ String boundValue = "effectiveTime.low";
+
+ if ("incision datetime".equals(value)) {
+ NodeList nodeList = entryElement.getElementsByTagName(OUTBOUND_RELATIONSHIP);
+ if (nodeList != null && nodeList.getLength() > 0) {
+ // Always get the last outBoundRelationShip tag, because this is the one
+ // which will represent the
+ Node outBoundNode = nodeList.item(nodeList.getLength() - 1);
+ Node criteriaNode = outBoundNode.getFirstChild();
+
+ NodeList idNodeList = ((Element) criteriaNode).getElementsByTagName(ID);
+ if (idNodeList != null && idNodeList.getLength() > 0) {
+ Node idNode = idNodeList.item(0);
+ Element qdmId = hqmfXmlProcessor.getOriginalDoc().createElement("qdm:id");
+ qdmId.setAttribute(ROOT, idNode.getAttributes().getNamedItem(ROOT).getNodeValue());
+ qdmId.setAttribute(
+ EXTENSION, idNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
+ attribute.appendChild(qdmId);
+ }
+ }
+ } else {
+ NodeList nodeList = entryElement.getElementsByTagName(PARTICIPATION);
+ if (nodeList != null && nodeList.getLength() > 0) {
+ // Always get the last outBoundRelationShip tag, because this is the one
+ // which will represent the
+ Node participationNode = nodeList.item(nodeList.getLength() - 1);
+ Node roleNode = ((Element) participationNode).getElementsByTagName(ROLE).item(0);
+ NodeList idNodeList = ((Element) roleNode).getElementsByTagName(ID);
+ if (idNodeList != null && idNodeList.getLength() > 0) {
+ Node idNode = idNodeList.item(0);
+ Node itemNode = idNode.getFirstChild();
+ Element qdmId = hqmfXmlProcessor.getOriginalDoc().createElement("qdm:id");
+ qdmId.setAttribute(ROOT, itemNode.getAttributes().getNamedItem(ROOT).getNodeValue());
+ qdmId.setAttribute(
+ EXTENSION, itemNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
+ attribute.appendChild(qdmId);
+
+ if ("facility location departure datetime".equals(value)
+ || "stop datetime".equals(value)
+ || "signed datetime".equals(value)
+ || "recorded datetime".equals(value)) {
+ boundValue = "effectiveTime.high";
+ }
+ }
+ }
+ }
+ attribute.setAttribute("bound", boundValue);
+ Node temporalInformation = temporallyRelatedInfoNode.getFirstChild();
+ if (temporallyRelatedInfoNode.getElementsByTagName("qdm:delta").item(0) != null) {
+ Node qdmDeltaNode = temporallyRelatedInfoNode.getElementsByTagName("qdm:delta").item(0);
+ temporalInformation.insertBefore(attribute, qdmDeltaNode);
+ } else {
+ temporalInformation.appendChild(attribute);
+ }
+
+ return attribute;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Generate Excerpt for Functional Op used with timing/Relationship.
+ *
+ * @param functionalOpNode the functional op node
+ * @param lhsNode the lhs node
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @param clonedNodeToAppendExcerpt the cloned node to append excerpt
+ * @return the element
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Element generateExcerptEntryForFunctionalNode(
+ Node functionalOpNode,
+ Node lhsNode,
+ XmlProcessor hqmfXmlProcessor,
+ Node clonedNodeToAppendExcerpt)
+ throws XPathExpressionException {
+ Element excerptElement = hqmfXmlProcessor.getOriginalDoc().createElement(EXCERPT);
+ String functionalOpName = functionalOpNode.getAttributes().getNamedItem(TYPE).getNodeValue();
+ Element criteriaElement = null;
+ if (FUNCTIONAL_OPS_NON_SUBSET.containsKey(functionalOpName)) {
+ Element sequenceElement = hqmfXmlProcessor.getOriginalDoc().createElement(SEQUENCE_NUMBER);
+ sequenceElement.setAttribute(
+ VALUE, FUNCTIONAL_OPS_NON_SUBSET.get(functionalOpName.toUpperCase()));
+ excerptElement.appendChild(sequenceElement);
+ if (clonedNodeToAppendExcerpt != null) {
+ if (clonedNodeToAppendExcerpt.getNodeName().contains(GROUPER)) {
+ criteriaElement =
+ generateCriteriaElementForSetOpExcerpt(hqmfXmlProcessor, clonedNodeToAppendExcerpt);
+ excerptElement.appendChild(criteriaElement);
+ } else {
+ NodeList entryChildNodes = clonedNodeToAppendExcerpt.getChildNodes();
+ criteriaElement = generateCriteriaElementForExcerpt(hqmfXmlProcessor, entryChildNodes);
+ excerptElement.appendChild(criteriaElement);
+ }
+ }
+ } else if (FUNCTIONAL_OPS_SUBSET.containsKey(functionalOpName)) {
+ NamedNodeMap attributeMap = functionalOpNode.getAttributes();
+ if (clonedNodeToAppendExcerpt.getNodeName().contains(GROUPER)) {
+ criteriaElement =
+ generateCriteriaElementForSetOpExcerpt(hqmfXmlProcessor, clonedNodeToAppendExcerpt);
+ excerptElement.appendChild(criteriaElement);
+ } else {
+ NodeList entryChildNodes = clonedNodeToAppendExcerpt.getChildNodes();
+ criteriaElement = generateCriteriaElementForExcerpt(hqmfXmlProcessor, entryChildNodes);
+ excerptElement.appendChild(criteriaElement);
+ }
+ if (clonedNodeToAppendExcerpt != null) {
+
+ if ("count".equalsIgnoreCase(functionalOpName)) {
+
+ createRepeatNumberTagForCountFuncttion(hqmfXmlProcessor, attributeMap, criteriaElement);
+ Element qdmSubSetElement =
+ hqmfXmlProcessor.getOriginalDoc().createElement("qdm:subsetCode");
+ qdmSubSetElement.setAttribute(
+ CODE, FUNCTIONAL_OPS_SUBSET.get(functionalOpName.toUpperCase()));
+ Element subSetCodeElement = hqmfXmlProcessor.getOriginalDoc().createElement("subsetCode");
+ subSetCodeElement.setAttribute(CODE, "SUM");
+
+ excerptElement.appendChild(subSetCodeElement);
+ excerptElement.appendChild(qdmSubSetElement);
+ excerptElement.appendChild(criteriaElement);
+ } else {
+ if (attributeMap.getNamedItem(OPERATOR_TYPE) != null && lhsNode != null) {
+ String lhsNodeType = lhsNode.getNodeName();
+ if (ELEMENT_REF.equalsIgnoreCase(lhsNodeType)) {
+ String qdmUUID = lhsNode.getAttributes().getNamedItem(ID).getNodeValue();
+ String xPath = "/measure/elementLookUp/qdm[@uuid ='" + qdmUUID + "']";
+ Node node =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xPath);
+ if (node != null && lhsNode.hasChildNodes()) {
+ Node qdmNode = node.cloneNode(true);
+ Node attributeNode = lhsNode.getFirstChild().cloneNode(true);
+ attributeNode.setUserData(
+ ATTRIBUTE_NAME,
+ attributeNode.getAttributes().getNamedItem(NAME).getNodeValue(),
+ null);
+ attributeNode.setUserData(
+ ATTRIBUTE_MODE, attributeMap.getNamedItem(OPERATOR_TYPE).getNodeValue(), null);
+ attributeNode.setUserData(
+ ATTRIBUTE_UUID,
+ attributeNode.getAttributes().getNamedItem(ATTR_UUID).getNodeValue(),
+ null);
+ Element attributeElement = (Element) attributeNode;
+
+ attributeElement.setAttribute(
+ MODE, attributeMap.getNamedItem(OPERATOR_TYPE).getNodeValue());
+ if (attributeElement.getAttributes().getNamedItem(ATTR_DATE) != null) {
+ attributeNode.setUserData(
+ ATTRIBUTE_DATE, attributeMap.getNamedItem(QUANTITY).getNodeValue(), null);
+ } else {
+ attributeElement.setAttribute(
+ COMPARISON_VALUE, attributeMap.getNamedItem(QUANTITY).getNodeValue());
+ }
+ if (attributeMap.getNamedItem(UNIT) != null) {
+ attributeElement.setAttribute(
+ UNIT, attributeMap.getNamedItem(UNIT).getNodeValue());
+ } else {
+ if (attributeElement.getAttributes().getNamedItem(UNIT) != null) {
+ attributeElement.removeAttribute(UNIT);
+ }
+ }
+ attributeNode = attributeElement;
+
+ // HQMFDataCriteriaElementGenerator hqmfDataCriteriaElementGenerator = new
+ // HQMFDataCriteriaElementGenerator();
+ // hqmfDataCriteriaElementGenerator.generateAttributeTagForFunctionalOp(measureExport,qdmNode,
+ // criteriaElement, attributeNode);
+ HQMFAttributeGenerator attributeGenerator = new HQMFAttributeGenerator();
+ attributeGenerator.generateAttributeTagForFunctionalOp(
+ measureExport, qdmNode, criteriaElement, attributeNode);
+ }
+ }
+ }
+ Element qdmSubSetElement =
+ hqmfXmlProcessor.getOriginalDoc().createElement("qdm:subsetCode");
+ qdmSubSetElement.setAttribute(
+ CODE, FUNCTIONAL_OPS_SUBSET.get(functionalOpName.toUpperCase()));
+
+ if ("sum".equalsIgnoreCase(functionalOpName)) {
+ Element subSetCodeElement =
+ hqmfXmlProcessor.getOriginalDoc().createElement("subsetCode");
+ subSetCodeElement.setAttribute(CODE, "SUM");
+ excerptElement.appendChild(subSetCodeElement);
+ }
+ excerptElement.appendChild(qdmSubSetElement);
+ excerptElement.appendChild(criteriaElement);
+ }
+ }
+ }
+
+ return excerptElement;
+ }
+
+ /**
+ * Check if parent sub tree.
+ *
+ * @param parentNode the parent node
+ * @return the node
+ */
+ protected Node checkIfParentSubTree(Node parentNode) {
+ Node returnNode = null;
+ if (parentNode != null) {
+ String parentName = parentNode.getNodeName();
+ if (SUB_TREE.equals(parentName)) {
+ returnNode = parentNode;
+ } else {
+ returnNode = checkIfParentSubTree(parentNode.getParentNode());
+ }
+ }
+
+ return returnNode;
+ }
+
+ /**
+ * Generates RepeatNumber tags for Count Function.
+ *
+ * @param hqmfXmlProcessor - XmlProcessor.
+ * @param attributeMap - NamedNodeMap.
+ * @param criteriaElement - Element.
+ */
+ private void createRepeatNumberTagForCountFuncttion(
+ XmlProcessor hqmfXmlProcessor, NamedNodeMap attributeMap, Element criteriaElement) {
+ Element repeatNumberElement = hqmfXmlProcessor.getOriginalDoc().createElement("repeatNumber");
+ Element lowNode = hqmfXmlProcessor.getOriginalDoc().createElement("low");
+ Element highNode = hqmfXmlProcessor.getOriginalDoc().createElement("high");
+ if (attributeMap.getNamedItem(OPERATOR_TYPE) != null) {
+ String operatorType = attributeMap.getNamedItem(OPERATOR_TYPE).getNodeValue();
+ String quantity = attributeMap.getNamedItem(QUANTITY).getNodeValue();
+ if (operatorType.startsWith("Greater Than")) {
+ lowNode.setAttribute(VALUE, quantity);
+ highNode.setAttribute(NULL_FLAVOR, "PINF");
+ if ("Greater Than or Equal To".equals(operatorType)) {
+ repeatNumberElement.setAttribute("lowClosed", TRUE);
+ }
+ } else if ("Equal To".equals(operatorType)) {
+ repeatNumberElement.setAttribute("lowClosed", TRUE);
+ repeatNumberElement.setAttribute("highClosed", TRUE);
+ lowNode.setAttribute(VALUE, quantity);
+ highNode.setAttribute(VALUE, quantity);
+ } else if (operatorType.startsWith("Less Than")) {
+ repeatNumberElement.setAttribute("lowClosed", TRUE);
+ lowNode.setAttribute(VALUE, "0");
+ highNode.setAttribute(VALUE, quantity);
+ if ("Less Than or Equal To".equals(operatorType)) {
+ repeatNumberElement.setAttribute("highClosed", TRUE);
+ }
+ }
+ repeatNumberElement.appendChild(lowNode);
+ repeatNumberElement.appendChild(highNode);
+ criteriaElement.appendChild(repeatNumberElement);
+ }
+ }
+
+ /**
+ * Generate criteria element for excerpt.
+ *
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @param entryChildNodes the entry child nodes
+ * @return the element
+ */
+ private Element generateCriteriaElementForExcerpt(
+ XmlProcessor hqmfXmlProcessor, NodeList entryChildNodes) {
+ Element criteriaElement = null;
+ for (int i = 0; i < entryChildNodes.getLength(); i++) {
+ Node childNode = entryChildNodes.item(i);
+ String childNodeName = childNode.getNodeName();
+ if (childNodeName.contains("Criteria")) {
+ criteriaElement = hqmfXmlProcessor.getOriginalDoc().createElement(childNodeName);
+ criteriaElement.setAttribute(
+ CLASS_CODE, childNode.getAttributes().getNamedItem(CLASS_CODE).getNodeValue());
+ criteriaElement.setAttribute(
+ MOOD_CODE, childNode.getAttributes().getNamedItem(MOOD_CODE).getNodeValue());
+ NodeList criteriaChildNodes = childNode.getChildNodes();
+ for (int j = 0; j < criteriaChildNodes.getLength(); j++) {
+ Node criteriaChildNode = criteriaChildNodes.item(j);
+ if (ID.equalsIgnoreCase(criteriaChildNode.getNodeName())) {
+ Element idElement = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ idElement.setAttribute(
+ ROOT, criteriaChildNode.getAttributes().getNamedItem(ROOT).getNodeValue());
+ idElement.setAttribute(
+ EXTENSION,
+ criteriaChildNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
+ criteriaElement.appendChild(idElement);
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+ return criteriaElement;
+ }
+
+ /**
+ * Generate criteria element for set op excerpt.
+ *
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @param clonedNodeToAppendExcerpt the cloned node to append excerpt
+ * @return the element
+ */
+ private Element generateCriteriaElementForSetOpExcerpt(
+ XmlProcessor hqmfXmlProcessor, Node clonedNodeToAppendExcerpt) {
+ Element criteriaElement = null;
+ for (int i = 0; i < clonedNodeToAppendExcerpt.getChildNodes().getLength(); i++) {
+ Node childNode = clonedNodeToAppendExcerpt.getChildNodes().item(i);
+ if (ID.equalsIgnoreCase(childNode.getNodeName())) {
+ Node criteriaNode =
+ generateEmptyGrouper(
+ hqmfXmlProcessor,
+ childNode.getAttributes().getNamedItem(ROOT).getNodeValue(),
+ childNode.getAttributes().getNamedItem(EXTENSION).getNodeValue());
+ criteriaElement = (Element) criteriaNode;
+ break;
+ }
+ }
+ return criteriaElement;
+ }
+
+ /**
+ * Creates the base temporal node.
+ *
+ * @param relOpNode the rel op node
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @return the element
+ */
+ private Element createBaseTemporalNode(Node relOpNode, XmlProcessor hqmfXmlProcessor) {
+
+ NamedNodeMap attribMap = relOpNode.getAttributes();
+ Element temporallyRelatedInfoNode =
+ hqmfXmlProcessor.getOriginalDoc().createElement("temporallyRelatedInformation");
+ temporallyRelatedInfoNode.setAttribute(
+ TYPE_CODE, attribMap.getNamedItem(TYPE).getNodeValue().toUpperCase());
+
+ Element temporalInfoNode =
+ hqmfXmlProcessor.getOriginalDoc().createElement("qdm:temporalInformation");
+ String precisionUnit = "min"; // use min by default
+
+ if (attribMap.getNamedItem(OPERATOR_TYPE) != null) {
+ String operatorType = attribMap.getNamedItem(OPERATOR_TYPE).getNodeValue();
+ String quantity = attribMap.getNamedItem(QUANTITY).getNodeValue();
+ String unit = attribMap.getNamedItem(UNIT).getNodeValue();
+
+ if ("seconds".equals(unit)) {
+ precisionUnit = "s";
+ unit = "s";
+ } else if ("hours".equals(unit)) {
+ unit = "h";
+ } else if ("minutes".equals(unit)) {
+ unit = "min";
+ } else {
+ precisionUnit = "d";
+ if ("days".equals(unit)) {
+ unit = "d";
+ } else if ("weeks".equals(unit)) {
+ unit = "wk";
+ } else if ("months".equals(unit)) {
+ unit = "mo";
+ } else if ("years".equals(unit)) {
+ unit = "a";
+ }
+ }
+
+ Element deltaNode = hqmfXmlProcessor.getOriginalDoc().createElement("qdm:delta");
+ Element lowNode = hqmfXmlProcessor.getOriginalDoc().createElement("low");
+ lowNode.setAttribute(UNIT, unit);
+
+ Element highNode = hqmfXmlProcessor.getOriginalDoc().createElement("high");
+ highNode.setAttribute(UNIT, unit);
+
+ if (operatorType.startsWith("Greater Than")) {
+ lowNode.setAttribute(VALUE, quantity);
+ highNode.removeAttribute(UNIT);
+ highNode.setAttribute(NULL_FLAVOR, "PINF");
+ if ("Greater Than or Equal To".equals(operatorType)) {
+ deltaNode.setAttribute("lowClosed", TRUE);
+ }
+ } else if ("Equal To".equals(operatorType)) {
+ deltaNode.setAttribute("lowClosed", TRUE);
+ deltaNode.setAttribute("highClosed", TRUE);
+ lowNode.setAttribute(VALUE, quantity);
+ highNode.setAttribute(VALUE, quantity);
+ } else if (operatorType.startsWith("Less Than")) {
+ deltaNode.setAttribute("lowClosed", TRUE);
+ lowNode.setAttribute(VALUE, "0");
+ highNode.setAttribute(VALUE, quantity);
+ if ("Less Than or Equal To".equals(operatorType)) {
+ deltaNode.setAttribute("highClosed", TRUE);
+ }
+ }
+ deltaNode.appendChild(lowNode);
+ deltaNode.appendChild(highNode);
+ temporalInfoNode.appendChild(deltaNode);
+ }
+ temporalInfoNode.setAttribute("precisionUnit", precisionUnit);
+ temporallyRelatedInfoNode.appendChild(temporalInfoNode);
+ return temporallyRelatedInfoNode;
+ }
+
+ /**
+ * Generate crit ref rel op.
+ *
+ * @param parentNode the parent node
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @param childNode the child node
+ * @param outboundRelElem the outbound rel elem
+ * @param clauseName the clause name
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void generateCritRefRelOp(
+ Node parentNode,
+ XmlProcessor hqmfXmlProcessor,
+ Node childNode,
+ Node outboundRelElem,
+ String clauseName)
+ throws XPathExpressionException {
+ Node relOpEntryNode = generateRelOpHQMF(childNode, parentNode, clauseName);
+
+ if (relOpEntryNode != null) {
+ Node idNode = getTagFromEntry(relOpEntryNode, ID);
+ // Node critNode = relOpEntryNode.getFirstChild();
+ // NodeList nodeList = ((Element)critNode).getElementsByTagName(ID);
+ // if(nodeList != null && nodeList.getLength() > 0){
+ if (idNode != null) {
+ // Node idNode = nodeList.item(0);
+ NamedNodeMap idAttribMap = idNode.getAttributes();
+ String idRoot = idAttribMap.getNamedItem(ROOT).getNodeValue();
+ String idExt = idAttribMap.getNamedItem(EXTENSION).getNodeValue();
+
+ Node parent = idNode.getParentNode();
+
+ NamedNodeMap attribMap = parent.getAttributes();
+ String classCode = attribMap.getNamedItem(CLASS_CODE).getNodeValue();
+ String moodCode = attribMap.getNamedItem(MOOD_CODE).getNodeValue();
+
+ // create criteriaRef
+ Element criteriaReference =
+ hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ criteriaReference.setAttribute(CLASS_CODE, classCode);
+ criteriaReference.setAttribute(MOOD_CODE, moodCode);
+
+ Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ id.setAttribute(ROOT, idRoot);
+ id.setAttribute(EXTENSION, idExt);
+
+ criteriaReference.appendChild(id);
+ outboundRelElem.appendChild(criteriaReference);
+ }
+ }
+ }
+
+ /**
+ * Generate crit ref set op.
+ *
+ * @param parentNode the parent node
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @param childNode the child node
+ * @param outboundRelElem the outbound rel elem
+ * @param clauseName the clause name
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void generateCritRefSetOp(
+ Node parentNode,
+ XmlProcessor hqmfXmlProcessor,
+ Node childNode,
+ Node outboundRelElem,
+ String clauseName)
+ throws XPathExpressionException {
+
+ Node setOpEntry = generateSetOpHQMF(childNode, parentNode, clauseName);
+ NodeList childList = setOpEntry.getChildNodes();
+ for (int j = 0; j < childList.getLength(); j++) {
+ Node child = childList.item(j);
+ if (GROUPER_CRITERIA.equals(child.getNodeName())) {
+ NodeList idChildList = ((Element) child).getElementsByTagName(ID);
+ if (idChildList.getLength() > 0) {
+ Node idChild = idChildList.item(0);
+ NamedNodeMap attribMap = idChild.getAttributes();
+ String idRoot = attribMap.getNamedItem(ROOT).getNodeValue();
+ String idExt = attribMap.getNamedItem(EXTENSION).getNodeValue();
+
+ // create criteriaRef
+ Element criteriaReference =
+ hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ criteriaReference.setAttribute(CLASS_CODE, "GROUPER");
+ criteriaReference.setAttribute(MOOD_CODE, "EVN");
+
+ Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ id.setAttribute(ROOT, idRoot);
+ id.setAttribute(EXTENSION, idExt);
+
+ criteriaReference.appendChild(id);
+ outboundRelElem.appendChild(criteriaReference);
+ }
+ }
+ }
+ }
+
+ /**
+ * Generate crit ref for node.
+ *
+ * @param outboundRelElem the outbound rel elem
+ * @param childNode the child node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void generateCritRefForNode(Node outboundRelElem, Node childNode)
+ throws XPathExpressionException {
+ XmlProcessor hqmfXmlProcessor = measureExport.getHqmfXmlProcessor();
+ String childName = childNode.getNodeName();
+
+ switch (childName) {
+ case ELEMENT_REF:
+ generateCritRefElementRef(outboundRelElem, childNode, hqmfXmlProcessor);
+ break;
+ case SUB_TREE_REF:
+ generateCritRefCQLDefine(outboundRelElem, childNode, hqmfXmlProcessor, true);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /**
+ * This method will basically create a with classCode='GROUPER' and
+ * moodCode='EVN' and have the tag pointing to the for the referenced
+ * subTree/clause.
+ *
+ * @param outboundRelElem the outbound rel elem
+ * @param subTreeRefNode the sub tree ref node
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @throws XPathExpressionException the x path expression exception
+ */
+ protected void generateCritRefCQLDefine(
+ Node outboundRelElem, Node subTreeRefNode, XmlProcessor hqmfXmlProcessor)
+ throws XPathExpressionException {
+ generateCritRefCQLDefine(outboundRelElem, subTreeRefNode, hqmfXmlProcessor, false);
+ }
+
+ /**
+ * This method will basically create a with classCode='GROUPER' and
+ * moodCode='EVN' and have the tag pointing to the for the referenced
+ * subTree/clause.
+ *
+ * @param outboundRelElem the outbound rel elem
+ * @param cqlDefineNode the sub tree ref node
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @param checkExisting check in the map if already existing
+ * @throws XPathExpressionException the x path expression exception
+ */
+ protected void generateCritRefCQLDefine(
+ Node outboundRelElem,
+ Node cqlDefineNode,
+ XmlProcessor hqmfXmlProcessor,
+ boolean checkExisting)
+ throws XPathExpressionException {
+
+ String cqlDefUUID = cqlDefineNode.getAttributes().getNamedItem(UUID).getNodeValue();
+
+ String xpath = "/measure/cqlLookUp//definition[@id='" + cqlDefUUID + "']";
+ Node definitionNode =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNode(measureExport.getSimpleXmlProcessor().getOriginalDoc(), xpath);
+ if (definitionNode != null) {
+ String defineName = definitionNode.getAttributes().getNamedItem("name").getNodeValue();
+ Node cqlUUIDNode =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNode(
+ measureExport.getSimpleXmlProcessor().getOriginalDoc(),
+ "/measure/measureDetails/cqlUUID");
+ Node cqlLibraryNode =
+ measureExport
+ .getSimpleXmlProcessor()
+ .findNode(
+ measureExport.getSimpleXmlProcessor().getOriginalDoc(),
+ "/measure/cqlLookUp/library");
+ if (cqlUUIDNode != null && cqlLibraryNode != null) {
+ String uuid = cqlUUIDNode.getTextContent();
+ String libraryName = cqlLibraryNode.getTextContent();
+ String ext = libraryName + ".\"" + defineName + "\"";
+ // create criteriaRef
+ Element criteriaReference =
+ hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ criteriaReference.setAttribute(CLASS_CODE, "OBS");
+ criteriaReference.setAttribute(MOOD_CODE, "EVN");
+
+ Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ id.setAttribute(ROOT, uuid);
+ id.setAttribute(EXTENSION, ext);
+
+ criteriaReference.appendChild(id);
+ outboundRelElem.appendChild(criteriaReference);
+ }
+ }
+ }
+
+ /**
+ * Generate crit ref element ref.
+ *
+ * @param outboundRelElem the outbound rel elem
+ * @param elementRefNode the element ref node
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @return the node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private Node generateCritRefElementRef(
+ Node outboundRelElem, Node elementRefNode, XmlProcessor hqmfXmlProcessor)
+ throws XPathExpressionException {
+ String ext = getElementRefExt(elementRefNode, measureExport.getSimpleXmlProcessor());
+ String root = elementRefNode.getAttributes().getNamedItem(ID).getNodeValue();
+ Node idNodeQDM =
+ hqmfXmlProcessor.findNode(
+ hqmfXmlProcessor.getOriginalDoc(),
+ "//entry/*/id[@root=\"" + root + "\"][@extension=\"" + ext + "\"]");
+ if (idNodeQDM != null) {
+ Node parent = idNodeQDM.getParentNode();
+ if (parent != null) {
+ NamedNodeMap attribMap = parent.getAttributes();
+ String classCode = attribMap.getNamedItem(CLASS_CODE).getNodeValue();
+ String moodCode = attribMap.getNamedItem(MOOD_CODE).getNodeValue();
+
+ // create criteriaRef
+ Element criteriaReference =
+ hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ criteriaReference.setAttribute(CLASS_CODE, classCode);
+ criteriaReference.setAttribute(MOOD_CODE, moodCode);
+
+ Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ id.setAttribute(ROOT, root);
+ id.setAttribute(EXTENSION, ext);
+
+ criteriaReference.appendChild(id);
+ outboundRelElem.appendChild(criteriaReference);
+ // return element
+ return parent.getParentNode();
+ }
+ } else {
+ // check if this is a measurement period
+ String displayName = elementRefNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ if ("Measurement Period : Timing Element".equals(displayName)) {
+ // create criteriaRef
+ Element criteriaReference =
+ hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ criteriaReference.setAttribute(CLASS_CODE, "OBS");
+ criteriaReference.setAttribute(MOOD_CODE, "EVN");
+
+ Element id = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ id.setAttribute(ROOT, elementRefNode.getAttributes().getNamedItem(ID).getNodeValue());
+ id.setAttribute(EXTENSION, "measureperiod");
+
+ criteriaReference.appendChild(id);
+ outboundRelElem.appendChild(criteriaReference);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Generate item count element ref.
+ *
+ * @param me the me
+ * @param populationTypeCriteriaElement the population type criteria element
+ * @param elementRefNode the element ref node
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @throws XPathExpressionException the x path expression exception
+ */
+ public void generateItemCountElementRef(
+ MeasureExport me,
+ Element populationTypeCriteriaElement,
+ Node elementRefNode,
+ XmlProcessor hqmfXmlProcessor)
+ throws XPathExpressionException {
+ String ext = getElementRefExt(elementRefNode, me.getSimpleXmlProcessor());
+ String root = elementRefNode.getAttributes().getNamedItem(ID).getNodeValue();
+ Node idNodeQDM =
+ hqmfXmlProcessor.findNode(
+ hqmfXmlProcessor.getOriginalDoc(),
+ "//entry/*/id[@root='" + root + "'][@extension=\"" + ext + "\"]");
+ if (idNodeQDM != null) {
+ Node parent = idNodeQDM.getParentNode();
+ if (parent != null) {
+ String classCode = parent.getAttributes().getNamedItem("classCode").getNodeValue();
+ String moodCode = parent.getAttributes().getNamedItem("moodCode").getNodeValue();
+ // item count Criteria Ref for Measure Observations
+ if ("measureObservationDefinition".equals(populationTypeCriteriaElement.getNodeName())) {
+ Element componentOfElem = hqmfXmlProcessor.getOriginalDoc().createElement("componentOf");
+ componentOfElem.setAttribute(TYPE_CODE, "COMP");
+ Element criteriaRef = hqmfXmlProcessor.getOriginalDoc().createElement(CRITERIA_REFERENCE);
+ criteriaRef.setAttribute(CLASS_CODE, classCode);
+ criteriaRef.setAttribute(MOOD_CODE, moodCode);
+ Element idElement = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ idElement.setAttribute(ROOT, root);
+ idElement.setAttribute(EXTENSION, ext);
+ criteriaRef.appendChild(idElement);
+ componentOfElem.appendChild(criteriaRef);
+ Comment comment = hqmfXmlProcessor.getOriginalDoc().createComment("Item Count ");
+ populationTypeCriteriaElement.appendChild(comment);
+ populationTypeCriteriaElement.appendChild(componentOfElem);
+ } else { // item count Criteria Ref for Populations
+ // create component for ItemCount ElmentRef
+ Element componentElem = hqmfXmlProcessor.getOriginalDoc().createElement("component");
+ componentElem.setAttribute(TYPE_CODE, "COMP");
+ Element measureAttrElem =
+ hqmfXmlProcessor.getOriginalDoc().createElement("measureAttribute");
+ componentElem.appendChild(measureAttrElem);
+ Element codeElem = hqmfXmlProcessor.getOriginalDoc().createElement("code");
+ codeElem.setAttribute(CODE, "ITMCNT");
+ codeElem.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.5.4");
+ codeElem.setAttribute(CODE_SYSTEM_NAME, "HL7 Observation Value");
+ Element displayNameElem = hqmfXmlProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ displayNameElem.setAttribute(VALUE, "Items to count");
+ codeElem.appendChild(displayNameElem);
+ Element valueElem = hqmfXmlProcessor.getOriginalDoc().createElement(VALUE);
+ valueElem.setAttribute("xsi:type", "II");
+ valueElem.setAttribute(ROOT, root);
+ valueElem.setAttribute(EXTENSION, ext);
+ measureAttrElem.appendChild(codeElem);
+ measureAttrElem.appendChild(valueElem);
+ populationTypeCriteriaElement.appendChild(componentElem);
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets the element ref ext.
+ *
+ * @param elementRefNode the element ref node
+ * @param simpleXmlProcessor the simple xml processor
+ * @return the element ref ext
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private String getElementRefExt(Node elementRefNode, XmlProcessor simpleXmlProcessor)
+ throws XPathExpressionException {
+ String extension = "";
+ if (elementRefNode.hasChildNodes()) {
+ Node childNode = elementRefNode.getFirstChild();
+ if ("attribute".equals(childNode.getNodeName())) {
+ extension = childNode.getAttributes().getNamedItem(ATTR_UUID).getNodeValue();
+ }
+ } else {
+ String id = elementRefNode.getAttributes().getNamedItem(ID).getNodeValue();
+ Node qdmNode =
+ simpleXmlProcessor.findNode(
+ simpleXmlProcessor.getOriginalDoc(),
+ "/measure/elementLookUp/qdm[@uuid='" + id + "']");
+ if (qdmNode != null) {
+ String dataType = qdmNode.getAttributes().getNamedItem(DATATYPE).getNodeValue();
+ String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ extension = qdmName + "_" + dataType;
+ if (qdmNode.getAttributes().getNamedItem(INSTANCE) != null) {
+ extension =
+ qdmNode.getAttributes().getNamedItem(INSTANCE).getNodeValue() + "_" + extension;
+ }
+ }
+ }
+ return StringUtils.deleteWhitespace(extension);
+ }
+
+ /**
+ * Generate empty grouper.
+ *
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @param root the root
+ * @param ext the ext
+ * @return the node
+ */
+ private Node generateEmptyGrouper(XmlProcessor hqmfXmlProcessor, String root, String ext) {
+ Element grouperElem = hqmfXmlProcessor.getOriginalDoc().createElement(GROUPER_CRITERIA);
+ grouperElem.setAttribute(CLASS_CODE, "GROUPER");
+ grouperElem.setAttribute(MOOD_CODE, "EVN");
+
+ Element idElem = hqmfXmlProcessor.getOriginalDoc().createElement(ID);
+ idElem.setAttribute(ROOT, root);
+ idElem.setAttribute(EXTENSION, StringUtils.deleteWhitespace(ext));
+
+ grouperElem.appendChild(idElem);
+
+ return grouperElem;
+ }
+
+ /**
+ * Generate empty outbound elem.
+ *
+ * @param hqmfXmlProcessor the hqmf xml processor
+ * @return the element
+ */
+ private Element generateEmptyOutboundElem(XmlProcessor hqmfXmlProcessor) {
+ Element outboundRelElem =
+ hqmfXmlProcessor.getOriginalDoc().createElement(OUTBOUND_RELATIONSHIP);
+ outboundRelElem.setAttribute(TYPE_CODE, "COMP");
+ return outboundRelElem;
+ }
+
+ /**
+ * Gets the tag from entry.
+ *
+ * @param entryElem the entry elem
+ * @param tagName the tag name
+ * @return the tag from entry
+ */
+ private Node getTagFromEntry(Node entryElem, String tagName) {
+
+ String entryElemName = entryElem.getNodeName();
+ if (ENTRY.equals(entryElemName)) {
+ Node firstChild = entryElem.getFirstChild();
+ if (LOCAL_VARIABLE_NAME.equals(firstChild.getNodeName())) {
+ NodeList nodeList = ((Element) firstChild.getNextSibling()).getElementsByTagName(tagName);
+ if (nodeList != null && nodeList.getLength() > 0) {
+ return nodeList.item(0);
+ }
+ } else {
+ NodeList nodeList = ((Element) firstChild).getElementsByTagName(tagName);
+ if (nodeList != null && nodeList.getLength() > 0) {
+ return nodeList.item(0);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Check If the parentNode is a SUB_TREE node. Or else, if parent is a 'functionalOp' then
+ * recursively check if the parentNode's parent is a 'subTree'. If yes, then return true.
+ *
+ * @param parentNode the parent node
+ * @return boolean
+ */
+ private Node checkIfSubTree(Node parentNode) {
+ Node returnNode = null;
+ if (parentNode != null) {
+ String parentName = parentNode.getNodeName();
+ if (SUB_TREE.equals(parentName)) {
+ returnNode = parentNode;
+ } else if (FUNCTIONAL_OP.equals(parentName)) {
+ returnNode = checkIfSubTree(parentNode.getParentNode());
+ }
+ }
+ return returnNode;
+ }
+
+ /**
+ * Gets the firt child list.
+ *
+ * @param function the function
+ * @return the firt child list
+ */
+ public static List getFunctionalOpFirstChild(String function) {
+ List childList = new ArrayList<>();
+ if (AGE_AT.equalsIgnoreCase(function)) {
+ childList.add(SUB_TREE_REF);
+ childList.add(RELATIONAL_OP);
+ childList.add(FUNCTIONAL_OP);
+ childList.add(ELEMENT_REF);
+ } else {
+ childList.add(ELEMENT_REF);
+ childList.add(SET_OP);
+ childList.add(SUB_TREE_REF);
+ childList.add(RELATIONAL_OP);
+ }
+ return childList;
+ }
+
+ /**
+ * Gets the aggregate and instance function childs.
+ *
+ * @param typeChild the type child
+ * @return the aggregate and instance function childs
+ */
+ public static List getAggregateAndInstanceFunctionChilds(String typeChild) {
+ List aggregateList = new ArrayList<>();
+ aggregateList.add("FIRST");
+ aggregateList.add("SECOND");
+ aggregateList.add("THIRD");
+ aggregateList.add("FOURTH");
+ aggregateList.add("FIFTH");
+ aggregateList.add("MOST RECENT");
+ if ("AGGREGATE".equals(typeChild)) {
+ aggregateList.add("DATETIMEDIFF");
+ }
+ return aggregateList;
+ }
+
+ /**
+ * Gets the functional op first child in mo.
+ *
+ * @param function the function
+ * @return the functional op first child in mo
+ */
+ public static List getFunctionalOpFirstChildInMO(String function) {
+ List childList = new ArrayList<>();
+ if ("DATETIMEDIFF".equalsIgnoreCase(function)) {
+ childList.add(ELEMENT_REF);
+ childList.add(SUB_TREE_REF);
+ childList.add(RELATIONAL_OP);
+ childList.addAll(getAggregateAndInstanceFunctionChilds("INSTANCE"));
+ } else {
+ childList.addAll(getFunctionalOpFirstChild(function));
+ childList.addAll(getAggregateAndInstanceFunctionChilds("AGGREGATE"));
+ }
+ return childList;
+ }
+
+ /** Check for used Used sub tree ref Node map in Populations and Meausre Observations. */
+ private void createUsedSubTreeRefMap() {
+
+ XmlProcessor simpleXmlProcessor = measureExport.getSimpleXmlProcessor();
+ String typeXpathString = "";
+ List usedSubTreeRefIdsPop = new ArrayList<>();
+ List usedSubTreeRefIdsMO = new ArrayList<>();
+ List usedSubTreeRefIDsRA = new ArrayList<>();
+ for (String typeString : POPULATION_NAME_LIST) {
+ typeXpathString += "@type = '" + typeString + "' or";
+ }
+ typeXpathString = typeXpathString.substring(0, typeXpathString.lastIndexOf(" or"));
+ String xpathForSubTreeInPOPClause =
+ "/measure/measureGrouping//clause[" + typeXpathString + "]//subTreeRef/@id";
+ String xpathForSubTreeInMOClause =
+ "/measure/measureGrouping//clause[@type='measureObservation']//subTreeRef/@id";
+ String xpathForSubTreeInRAClause = "/measure//riskAdjustmentVariables/subTreeRef/@id";
+ try {
+
+ // creating used Subtree Red Map in Populations
+ NodeList populationsSubTreeNode =
+ simpleXmlProcessor.findNodeList(
+ simpleXmlProcessor.getOriginalDoc(), xpathForSubTreeInPOPClause);
+ for (int i = 0; i < populationsSubTreeNode.getLength(); i++) {
+ String uuid = populationsSubTreeNode.item(i).getNodeValue();
+ uuid = checkIfQDMVarInstanceIsPresent(uuid, simpleXmlProcessor);
+ if (!usedSubTreeRefIdsPop.contains(uuid)) {
+ usedSubTreeRefIdsPop.add(uuid);
+ }
+ }
+ usedSubTreeRefIdsPop = checkUnUsedSubTreeRef(simpleXmlProcessor, usedSubTreeRefIdsPop);
+ for (String uuid : usedSubTreeRefIdsPop) {
+ Node subTreeNode = createUsedSubTreeRefMap(simpleXmlProcessor, uuid);
+ subTreeNodeInPOPMap.put(uuid, subTreeNode);
+ }
+
+ // creating used Subtree Red Map in Measure Observations
+ NodeList measureObsSubTreeNode =
+ simpleXmlProcessor.findNodeList(
+ simpleXmlProcessor.getOriginalDoc(), xpathForSubTreeInMOClause);
+ for (int i = 0; i < measureObsSubTreeNode.getLength(); i++) {
+ String uuid = measureObsSubTreeNode.item(i).getNodeValue();
+ uuid = checkIfQDMVarInstanceIsPresent(uuid, simpleXmlProcessor);
+ if (!usedSubTreeRefIdsMO.contains(uuid)) {
+ usedSubTreeRefIdsMO.add(uuid);
+ }
+ }
+ usedSubTreeRefIdsMO = checkUnUsedSubTreeRef(simpleXmlProcessor, usedSubTreeRefIdsMO);
+ for (String uuid : usedSubTreeRefIdsMO) {
+ Node subTreeNode = createUsedSubTreeRefMap(simpleXmlProcessor, uuid);
+ subTreeNodeInMOMap.put(uuid, subTreeNode);
+ }
+ // creating used Subtree Red in Risk Adjustment
+ NodeList riskAdjSubTreeNode =
+ simpleXmlProcessor.findNodeList(
+ simpleXmlProcessor.getOriginalDoc(), xpathForSubTreeInRAClause);
+ for (int i = 0; i < riskAdjSubTreeNode.getLength(); i++) {
+ String uuid = riskAdjSubTreeNode.item(i).getNodeValue();
+ uuid = checkIfQDMVarInstanceIsPresent(uuid, simpleXmlProcessor);
+ if (!usedSubTreeRefIDsRA.contains(uuid)) {
+ usedSubTreeRefIDsRA.add(uuid);
+ }
+ }
+ usedSubTreeRefIDsRA = checkUnUsedSubTreeRef(simpleXmlProcessor, usedSubTreeRefIDsRA);
+ for (String uuid : usedSubTreeRefIDsRA) {
+ Node subTreeNode = createUsedSubTreeRefMap(simpleXmlProcessor, uuid);
+ subTreeNodeInRAMap.put(uuid, subTreeNode);
+ }
+
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Creates the used sub tree ref map.
+ *
+ * @param simpleXmlProcessor the simple xml processor
+ * @param uuid the uuid
+ * @return the node
+ */
+ private Node createUsedSubTreeRefMap(XmlProcessor simpleXmlProcessor, String uuid) {
+ String xpathforUsedSubTreeMap = "/measure/subTreeLookUp/subTree[@uuid='" + uuid + "']";
+ Node subTreeNode = null;
+ try {
+ subTreeNode =
+ simpleXmlProcessor.findNode(simpleXmlProcessor.getOriginalDoc(), xpathforUsedSubTreeMap);
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ return subTreeNode;
+ }
+
+ /**
+ * Check un used sub tree ref.
+ *
+ * @param xmlProcessor the xml processor
+ * @param usedSubTreeRefIds the used sub tree ref ids
+ * @return the list
+ */
+ private List checkUnUsedSubTreeRef(
+ XmlProcessor xmlProcessor, List usedSubTreeRefIds) {
+
+ List allSubTreeRefIds = new ArrayList<>();
+ NodeList subTreeRefIdsNodeList;
+ javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
+ try {
+ subTreeRefIdsNodeList =
+ xmlProcessor.findNodeList(xmlProcessor.getOriginalDoc(), "/measure//subTreeRef/@id");
+
+ for (int i = 0; i < subTreeRefIdsNodeList.getLength(); i++) {
+ Node SubTreeRefIdAttributeNode = subTreeRefIdsNodeList.item(i);
+ if (!allSubTreeRefIds.contains(SubTreeRefIdAttributeNode.getNodeValue())) {
+ allSubTreeRefIds.add(SubTreeRefIdAttributeNode.getNodeValue());
+ }
+ }
+ allSubTreeRefIds.removeAll(usedSubTreeRefIds);
+
+ for (int i = 0; i < usedSubTreeRefIds.size(); i++) {
+ for (int j = 0; j < allSubTreeRefIds.size(); j++) {
+ Node usedSubTreeRefNode =
+ xmlProcessor.findNode(
+ xmlProcessor.getOriginalDoc(),
+ "/measure/subTreeLookUp/subTree[@uuid='"
+ + usedSubTreeRefIds.get(i)
+ + "']//subTreeRef[@id='"
+ + allSubTreeRefIds.get(j)
+ + "']");
+ if (usedSubTreeRefNode != null) {
+
+ String subTreeUUID = usedSubTreeRefNode.getAttributes().getNamedItem(ID).getNodeValue();
+ String XPATH_IS_INSTANCE_OF =
+ "//subTree [boolean(@instanceOf)]/@uuid ='" + subTreeUUID + "'";
+ boolean isOccurrenceNode =
+ (Boolean)
+ xPath.evaluate(
+ XPATH_IS_INSTANCE_OF,
+ xmlProcessor.getOriginalDoc(),
+ XPathConstants.BOOLEAN);
+ if (isOccurrenceNode) {
+ String XPATH_PARENT_UUID = "//subTree [@uuid ='" + subTreeUUID + "']/@instanceOf";
+ String parentUUID =
+ (String)
+ xPath.evaluate(
+ XPATH_PARENT_UUID, xmlProcessor.getOriginalDoc(), XPathConstants.STRING);
+ if (!usedSubTreeRefIds.contains(parentUUID)) {
+ usedSubTreeRefIds.add(parentUUID);
+ }
+ }
+ if (!usedSubTreeRefIds.contains(allSubTreeRefIds.get(j))) {
+
+ usedSubTreeRefIds.add(allSubTreeRefIds.get(j));
+ }
+ }
+ }
+ }
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ return usedSubTreeRefIds;
+ }
+
+ /**
+ * Validate sub tree ref in pop.
+ *
+ * @param subTreeNode the sub tree node
+ * @param functionalOpNode the functional op node
+ * @return true, if successful
+ */
+ public boolean validateSubTreeRefInPOP(Node subTreeNode, Node functionalOpNode) {
+ if (subTreeNodeInPOPMap.get(subTreeNode.getAttributes().getNamedItem(UUID).getNodeValue())
+ != null) {
+ String firstChildName = functionalOpNode.getFirstChild().getNodeName();
+ String functionalOpType = functionalOpNode.getAttributes().getNamedItem(TYPE).getNodeValue();
+ List childsList = FUNCTIONAL_OP_RULES_IN_POP.get(functionalOpType);
+ if (childsList.contains(firstChildName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Utility method which will try to find the tag "localVariableName" and set the given string
+ * value to its VALUE attribute.
+ *
+ * @param node the node
+ * @param localVarName the local var name
+ */
+ private void updateLocalVar(Node node, String localVarName) {
+ if (node == null) {
+ return;
+ }
+ NodeList localVarNodeList = ((Element) node).getElementsByTagName(LOCAL_VARIABLE_NAME);
+ if (localVarNodeList != null && localVarNodeList.getLength() > 0) {
+ Element localVar = (Element) localVarNodeList.item(0);
+ localVar.setAttribute(VALUE, localVarName);
+ }
+ }
+
+ /**
+ * Check if qdm var instance is present.
+ *
+ * @param usedSubtreeRefId the used subtree ref id
+ * @param xmlProcessor the xml processor
+ * @return the string
+ */
+ private String checkIfQDMVarInstanceIsPresent(
+ String usedSubtreeRefId, XmlProcessor xmlProcessor) {
+
+ String XPATH_INSTANCE_QDM_VAR =
+ "/measure/subTreeLookUp/subTree[@uuid='" + usedSubtreeRefId + "']/@instance";
+ String XPATH_INSTANCE_OF_QDM_VAR =
+ "/measure/subTreeLookUp/subTree[@uuid='" + usedSubtreeRefId + "']/@instanceOf";
+ try {
+ Node nodesSDE_SubTree =
+ xmlProcessor.findNode(xmlProcessor.getOriginalDoc(), XPATH_INSTANCE_QDM_VAR);
+ if (nodesSDE_SubTree != null) {
+ Node nodesSDE_SubTreeInstance =
+ xmlProcessor.findNode(xmlProcessor.getOriginalDoc(), XPATH_INSTANCE_OF_QDM_VAR);
+ usedSubtreeRefId = nodesSDE_SubTreeInstance.getNodeValue();
+ }
+
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+
+ return usedSubtreeRefId;
+ }
+
+ /**
+ * Gets the sub tree node map.
+ *
+ * @return the subTreeNodeMap
+ */
+ public Map getSubTreeNodeMap() {
+ return subTreeNodeMap;
+ }
+
+ /**
+ * Sets the sub tree node map.
+ *
+ * @param subTreeNodeMap the subTreeNodeMap to set
+ */
+ public void setSubTreeNodeMap(Map subTreeNodeMap) {
+ this.subTreeNodeMap = subTreeNodeMap;
+ }
+
+ /**
+ * Gets the measure export.
+ *
+ * @return the measureExport
+ */
+ public MeasureExport getMeasureExport() {
+ return measureExport;
+ }
+
+ /**
+ * Sets the measure export.
+ *
+ * @param measureExport the measureExport to set
+ */
+ public void setMeasureExport(MeasureExport measureExport) {
+ this.measureExport = measureExport;
+ }
+
+ /**
+ * Gets the sub tree node in mo map.
+ *
+ * @return the subTreeNodeInMOMap
+ */
+ public Map getSubTreeNodeInMOMap() {
+ return subTreeNodeInMOMap;
+ }
+
+ /**
+ * Sets the sub tree node in mo map.
+ *
+ * @param subTreeNodeInMOMap the subTreeNodeInMOMap to set
+ */
+ public void setSubTreeNodeInMOMap(Map subTreeNodeInMOMap) {
+ this.subTreeNodeInMOMap = subTreeNodeInMOMap;
+ }
+
+ /**
+ * Gets the sub tree node in ra map.
+ *
+ * @return the subTreeNodeInMOMap
+ */
+ public Map getSubTreeNodeInRAMap() {
+ return subTreeNodeInRAMap;
+ }
+
+ /**
+ * Sets the sub tree node in ra map.
+ *
+ * @param subTreeNodeInRAMap the sub tree node in ra map
+ */
+ public void setSubTreeNodeInRAMap(Map subTreeNodeInRAMap) {
+ this.subTreeNodeInRAMap = subTreeNodeInRAMap;
+ }
+
+ /**
+ * Gets the sub tree node in pop map.
+ *
+ * @return the subTreeNodeInPOPMap
+ */
+ public Map getSubTreeNodeInPOPMap() {
+ return subTreeNodeInPOPMap;
+ }
+
+ /**
+ * Sets the sub tree node in pop map.
+ *
+ * @param subTreeNodeInPOPMap the subTreeNodeInPOPMap to set
+ */
+ public void setSubTreeNodeInPOPMap(Map subTreeNodeInPOPMap) {
+ this.subTreeNodeInPOPMap = subTreeNodeInPOPMap;
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaElementGenerator.java b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaElementGenerator.java
index 5a1854f..055309b 100644
--- a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaElementGenerator.java
+++ b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaElementGenerator.java
@@ -21,744 +21,873 @@
import java.util.Map;
public class HQMFDataCriteriaElementGenerator implements Generator {
-
- private static final String DATA_CRITERIA_EXTENSION = "2021-02-01";
-
- /** The occurrence map. */
- private Map occurrenceMap = new HashMap<>();
-
- protected String extensionValue = null;
-
- /** The Constant logger. */
- private static final Logger logger = LoggerFactory.getLogger(HQMFDataCriteriaElementGenerator.class);
-
- /**
- * Generate hqm for measure.
- *
- * @param me the me
- * @return the string
- */
- @Override
- public String generate(MeasureExport me) {
- getExtensionValueBasedOnVersion(me);
- XmlProcessor dataCriteriaXMLProcessor = createDateCriteriaTemplate();
- me.setHqmfXmlProcessor(dataCriteriaXMLProcessor);
-
- String simpleXMLStr = me.getSimpleXml();
- XmlProcessor simpleXmlprocessor = new XmlProcessor(simpleXMLStr);
- me.setSimpleXmlProcessor(simpleXmlprocessor);
-
- createDataCriteriaForQDMELements(me, dataCriteriaXMLProcessor, simpleXmlprocessor);
- addDataCriteriaComment(dataCriteriaXMLProcessor);
- return dataCriteriaXMLProcessor.transform(dataCriteriaXMLProcessor.getOriginalDoc(), true);
- }
-
- /**
- * Creates the date criteria template.
- *
- * @return the string
- */
- private XmlProcessor createDateCriteriaTemplate() {
- XmlProcessor outputProcessor = new XmlProcessor(
- "");
-
- Node dataCriteriaElem = outputProcessor.getOriginalDoc()
- .getElementsByTagName("dataCriteriaSection").item(0);
- Element templateId = outputProcessor.getOriginalDoc()
- .createElement(TEMPLATE_ID);
- dataCriteriaElem.appendChild(templateId);
- Element itemChild = outputProcessor.getOriginalDoc()
- .createElement(ITEM);
- itemChild.setAttribute(ROOT, "2.16.840.1.113883.10.20.28.2.6");
- //itemChild.setAttribute("extension", getDataCriteriaExtValueBasedOnVersion(me));
- itemChild.setAttribute("extension", DATA_CRITERIA_EXTENSION);
- templateId.appendChild(itemChild);
- // creating Code Element for DataCriteria
- Element codeElem = outputProcessor.getOriginalDoc()
- .createElement(CODE);
- codeElem.setAttribute(CODE, "57025-9");
- codeElem.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.6.1");
- dataCriteriaElem.appendChild(codeElem);
- // creating title for DataCriteria
- Element titleElem = outputProcessor.getOriginalDoc()
- .createElement(TITLE);
- titleElem.setAttribute(VALUE, "Data Criteria Section");
- dataCriteriaElem.appendChild(titleElem);
- // creating text for DataCriteria
- Element textElem = outputProcessor.getOriginalDoc()
- .createElement("text");
- dataCriteriaElem.appendChild(textElem);
-
- return outputProcessor;
- }
-
- private String getDataCriteriaExtValueBasedOnVersion() {
- return VERSION_5_0_ID;
- }
- /**
- * Creates the data criteria for qdm elements.
- *
- * @param me the me
- * @param dataCriteriaXMLProcessor the data criteria xml processor
- * @param simpleXmlprocessor the simple xmlprocessor
- */
- private void createDataCriteriaForQDMELements(MeasureExport me, XmlProcessor dataCriteriaXMLProcessor, XmlProcessor simpleXmlprocessor) {
- String xPathForQDMNoAttribs = "/measure/elementLookUp/qdm[@datatype and @code ='false']";
- String xpathForOtherSupplementalQDMs = "/measure/supplementalDataElements/elementRef/@id";
- String xpathForMeasureGroupingItemCount = "/measure//itemCount/elementRef/@id";
-
-
- try {
- NodeList qdmNoAttributeNodeList = simpleXmlprocessor.findNodeList(simpleXmlprocessor.getOriginalDoc(), xPathForQDMNoAttribs);
- generateCQLQDMNodeEntries(dataCriteriaXMLProcessor, simpleXmlprocessor,
- qdmNoAttributeNodeList);
-
- HQMFDataCriteriaElementGeneratorForCodes cqlBasedHQMFDataCriteriaElementGeneratorForCodes = new HQMFDataCriteriaElementGeneratorForCodes();
- cqlBasedHQMFDataCriteriaElementGeneratorForCodes.generate(me);
-
- //generating QDM Entries for other Supplemental Data Elements
- NodeList supplementalDataElements = me.getSimpleXmlProcessor().findNodeList(me.getSimpleXmlProcessor().getOriginalDoc(),
- xpathForOtherSupplementalQDMs);
- generateOtherSupplementalDataQDMEntries(me, dataCriteriaXMLProcessor, supplementalDataElements);
-
- //generating QDM entries for measureGrouping ItemCountlist
- NodeList measureGroupingItemCountList = simpleXmlprocessor.findNodeList(simpleXmlprocessor.getOriginalDoc(), xpathForMeasureGroupingItemCount);
- generateMeasureGrpnItemCountQDMEntries(me, dataCriteriaXMLProcessor, measureGroupingItemCountList);
-
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- }
-
-
- protected void getExtensionValueBasedOnVersion(MeasureExport me) {
- if(me!=null){
- extensionValue = getDataCriteriaExtValueBasedOnVersion();
- }
- }
-
- /**
- * Generate measure grp item count qdm entries.
- *
- * @param me the me
- * @param dataCriteriaXMLProcessor the data criteria xml processor
- * @param measureGroupingItemCountList the measure grouping item count list
- * @throws XPathExpressionException the x path expression exception
- */
- private void generateMeasureGrpnItemCountQDMEntries(MeasureExport me,
- XmlProcessor dataCriteriaXMLProcessor,
- NodeList measureGroupingItemCountList) throws XPathExpressionException {
-
- if(measureGroupingItemCountList==null ||
- measureGroupingItemCountList.getLength()<1){
- return;
- }
- List itemCountIDList = new ArrayList();
- for(int i=0; i supplementalElemenRefIds = new ArrayList();
- for(int i=0; i uuidList){
- String uuidXPathString = "";
- for (String uuidString: uuidList) {
- uuidXPathString += "@uuid = '" + uuidString + "' or";
- }
-
- uuidXPathString = uuidXPathString.substring(0, uuidXPathString.lastIndexOf(" or"));
- return uuidXPathString;
- }
-
- private void generateCQLQDMNodeEntries(XmlProcessor dataCriteriaXMLProcessor,
- XmlProcessor simpleXmlprocessor, NodeList qdmNoAttributeNodeList)
- throws XPathExpressionException {
-
- if (qdmNoAttributeNodeList == null) {
- return;
- }
-
- for (int i = 0; i < qdmNoAttributeNodeList.getLength(); i++) {
- Node qdmNode = qdmNoAttributeNodeList.item(i);
- createXmlForDataCriteria(qdmNode, dataCriteriaXMLProcessor, simpleXmlprocessor);
- }
- }
-
- /**
- * Generate qdm entry.
- *
- * @param dataCriteriaXMLProcessor the data criteria xml processor
- * @param simpleXmlprocessor the simple xmlprocessor
- * @param qdmNode the qdm node
- * @param forceGenerate the force generate
- * @throws XPathExpressionException the x path expression exception
- */
- private void generateQDMEntry(XmlProcessor dataCriteriaXMLProcessor,
- XmlProcessor simpleXmlprocessor, Node qdmNode, boolean forceGenerate)
- throws XPathExpressionException {
- String qdmUUID = qdmNode.getAttributes().getNamedItem(UUID).getNodeValue();
-
- String xPathForIndividualElementRefs = "/measure/subTreeLookUp//elementRef[@id='"+qdmUUID+"'][not(attribute)]";
- NodeList elementRefList = simpleXmlprocessor.findNodeList(simpleXmlprocessor.getOriginalDoc(), xPathForIndividualElementRefs);
- if(forceGenerate || elementRefList.getLength() > 0){
- createXmlForDataCriteria(qdmNode, dataCriteriaXMLProcessor, simpleXmlprocessor);
- }
- }
-
- /**
- * Create xml for data criteria.
- *
- * @param qdmNode the qdm node
- * @param dataCriteriaXMLProcessor the data criteria xml processor
- * @param simpleXmlprocessor the simple xmlprocessor
- * @return void
- */
- private void createXmlForDataCriteria(Node qdmNode, XmlProcessor dataCriteriaXMLProcessor, XmlProcessor simpleXmlprocessor) {
- String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
-
- XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(5.6);
- String xPathForTemplate = "/templates/template[text()='" + dataType.toLowerCase() + "']";
- String actNodeStr = "";
- try {
-
- Node templateNode = templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xPathForTemplate);
- if (templateNode != null) {
- String attrClass = templateNode.getAttributes()
- .getNamedItem(CLASS).getNodeValue();
- String xpathForAct = "/templates/acts/act[@a_id='" + attrClass
- + "']";
- Node actNode = templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xpathForAct);
- if (actNode != null) {
- actNodeStr = actNode.getTextContent();
- }
-
- createDataCriteriaElementTag(actNodeStr, templateNode, qdmNode, dataCriteriaXMLProcessor, simpleXmlprocessor,templateXMLProcessor);
- }
-
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Gets the creates the data create element tag.
- *
- * @param actNodeStr the act node str
- * @param templateNode the template node
- * @param qdmNode the qdm node
- * @param dataCriteriaXMLProcessor the data criteria xml processor
- * @param simpleXmlprocessor the simple xmlprocessor
- * @param templateXMLProcessor - templateXmlProcessor
- * @throws XPathExpressionException the x path expression exception
- */
- private void createDataCriteriaElementTag(String actNodeStr, Node templateNode,
- Node qdmNode, XmlProcessor dataCriteriaXMLProcessor, XmlProcessor
- simpleXmlprocessor, XmlProcessor templateXMLProcessor) throws XPathExpressionException {
- String oidValue = templateNode.getAttributes().getNamedItem(OID).getNodeValue();
- String classCodeValue = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
- String moodValue = templateNode.getAttributes().getNamedItem(MOOD).getNodeValue();
-
- Node statusNode= templateNode.getAttributes().getNamedItem("status");
- String statusValue = statusNode != null ? statusNode.getNodeValue() : "";
- String rootValue = qdmNode.getAttributes().getNamedItem(ID).getNodeValue();
- String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
- String qdmOidValue = qdmNode.getAttributes().getNamedItem(OID).getNodeValue();
-
- String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
- Node actionNegInd = templateNode.getAttributes().getNamedItem("actionNegationInd");
- String entryCommentText = dataType;
- // Local variable changes.
- String qdmLocalVariableName = qdmName + "_" + dataType;
- String localVariableName = qdmLocalVariableName;
-
- qdmLocalVariableName = StringUtils.deleteWhitespace(qdmLocalVariableName);
- localVariableName = StringUtils.deleteWhitespace(localVariableName);
-
- Element dataCriteriaSectionElem = (Element) dataCriteriaXMLProcessor.getOriginalDoc().getElementsByTagName("dataCriteriaSection").item(0);
- Element componentElem = (Element) dataCriteriaXMLProcessor.getOriginalDoc().getElementsByTagName("component").item(0);
- Attr nameSpaceAttr = dataCriteriaXMLProcessor.getOriginalDoc().createAttribute("xmlns:xsi");
- nameSpaceAttr.setNodeValue(nameSpace);
- componentElem.setAttributeNodeNS(nameSpaceAttr);
- Attr qdmNameSpaceAttr = dataCriteriaXMLProcessor.getOriginalDoc().createAttribute("xmlns:cql-ext");
- qdmNameSpaceAttr.setNodeValue("urn:hhs-cql:hqmf-n1-extensions:v1");
- componentElem.setAttributeNodeNS(qdmNameSpaceAttr);
- // creating Entry Tag
- Element entryElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement("entry");
- entryElem.setAttribute(TYPE_CODE, "DRIV");
- // Local Variable Name Tag - Inside Entry tag.
- Element localVarElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement("localVariableName");
- localVarElem.setAttribute(VALUE, localVariableName + "_" + UUIDUtilClient.uuid(5));
- entryElem.appendChild(localVarElem);
- Element dataCriteriaElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(actNodeStr);
- entryElem.appendChild(dataCriteriaElem);
- dataCriteriaElem.setAttribute(CLASS_CODE, classCodeValue);
- dataCriteriaElem.setAttribute(MOOD_CODE, moodValue);
- // adding actionNegationInd for Negative Datatypes
- if (actionNegInd != null) {
- dataCriteriaElem.setAttribute(ACTION_NEGATION_IND, actionNegInd.getNodeValue());
- }
- Element templateId = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
- dataCriteriaElem.appendChild(templateId);
- Element itemChild = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ITEM);
- itemChild.setAttribute(ROOT, oidValue);
- if (templateNode.getAttributes().getNamedItem("specificExtensionValue") != null) {
- String specificExtensionValue = templateNode.getAttributes().getNamedItem("specificExtensionValue")
- .getNodeValue();
- itemChild.setAttribute("extension", specificExtensionValue);
- } else if (templateNode.getAttributes().getNamedItem("addExtensionInTemplate") == null) {
- itemChild.setAttribute("extension", extensionValue);
- }
- templateId.appendChild(itemChild);
- Element idElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ID);
- idElem.setAttribute(ROOT, rootValue);
- idElem.setAttribute("extension", qdmLocalVariableName);
- dataCriteriaElem.appendChild(idElem);
-
- boolean appendEntryElem = false;
- String occurString = dataType + "-" + qdmOidValue;
-
- if (qdmNode.getAttributes().getNamedItem("instance") != null) {
- generateOutboundForOccur(templateNode, qdmNode, dataCriteriaElem, occurString, dataCriteriaXMLProcessor,
- simpleXmlprocessor);
- entryCommentText = qdmNode.getAttributes().getNamedItem("instance").getNodeValue() + " " + entryCommentText;
- appendEntryElem = true;
- } else if (!occurrenceMap.containsKey(occurString) /* || (attributeQDMNode != null) */) {
-
- String isAddCodeTag = templateNode.getAttributes().getNamedItem("addCodeTag").getNodeValue();
- if ("true".equalsIgnoreCase(isAddCodeTag)) { // Add Code Element to DataCriteria Element.
- addCodeElementToDataCriteriaElement(templateNode, dataCriteriaXMLProcessor, qdmNode, dataCriteriaElem);
- }
- Element titleElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TITLE);
- titleElem.setAttribute(VALUE, dataType);
- dataCriteriaElem.appendChild(titleElem);
-
- if(StringUtils.isNotEmpty(statusValue)) {
- Element statusCodeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement("statusCode");
- statusCodeElem.setAttribute(CODE, statusValue);
- dataCriteriaElem.appendChild(statusCodeElem);
- }
-
- // Add value tag in entry element.
- String addValueSetElement = templateNode.getAttributes().getNamedItem("addValueTag").getNodeValue();
- if ("true".equalsIgnoreCase(addValueSetElement)) {
- Element valueElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(VALUE);
- Node valueTypeAttr = templateNode.getAttributes().getNamedItem("valueType");
- if (valueTypeAttr != null) {
- valueElem.setAttribute(XSI_TYPE, valueTypeAttr.getNodeValue());
- }
-
- Node valueCodeSystem = templateNode.getAttributes().getNamedItem("valueCodeSystem");
- Node valueCode = templateNode.getAttributes().getNamedItem("valueCode");
- Node valueDisplayName = templateNode.getAttributes().getNamedItem("valueDisplayName");
- Node valueCodeSystemName = templateNode.getAttributes().getNamedItem("valueCodeSystemName");
- if (valueCode != null && valueCodeSystem != null) {
- valueElem.setAttribute("code", valueCode.getNodeValue());
- valueElem.setAttribute("codeSystem", valueCodeSystem.getNodeValue());
- if (valueCodeSystemName != null) {
- valueElem.setAttribute("codeSystemName", valueCodeSystemName.getNodeValue());
- }
- } else {
- valueElem.setAttribute("valueSet", qdmOidValue);
- addValueSetVersion(qdmNode, valueElem);
- }
-
- dataCriteriaElem.appendChild(valueElem);
- }
- if (templateNode.getAttributes().getNamedItem("includeSubTemplate") != null) {
- appendSubTemplateNode(templateNode, dataCriteriaXMLProcessor, templateXMLProcessor, dataCriteriaElem,
- qdmNode);
- }
- // checkForAttributes
-
- appendEntryElem = true;
- }
- if (appendEntryElem) {
- dataCriteriaSectionElem.appendChild(entryElem);
- }
-
- }
-
- /**
- * Method to add valueSetVersion attribute in value element tag.
- *
- * @param qdmNode the qdm node
- * @param valueElem the value elem
- */
- protected void addValueSetVersion(Node qdmNode, Element valueElem) {
- // This is to be commented until we start getting value set versions from VSAC.
- boolean addVersionToValueTag = false;
- String valueSetVersion = qdmNode.getAttributes().getNamedItem("version").getNodeValue();
-
- if ("1.0".equals(valueSetVersion) || "1".equals(valueSetVersion) || StringUtils.isBlank(valueSetVersion)) {
- addVersionToValueTag = false;
- } else {
- valueSetVersion = qdmNode.getAttributes().getNamedItem("version").getNodeValue();
- addVersionToValueTag = true;
- }
- if (addVersionToValueTag) {
- valueElem.setAttribute("valueSetVersion", valueSetVersion);
- }
- }
-
- /**
- * Generate outbound for occur.
- *
- * @param templateNode the template node
- * @param qdmNode the qdm node
- * @param dataCriteriaElem the data criteria elem
- * @param occurString the occur string
- */
- private void generateOutboundForOccur(Node templateNode, Node qdmNode,
- Element dataCriteriaElem, String occurString,XmlProcessor dataCriteriaXMLProcessor, XmlProcessor
- simpleXmlprocessor) {
- Node refNode = occurrenceMap.get(occurString);
-
- logger.debug("In generateOutboundForOccur()..refNode:"+refNode);
- logger.debug("----------Occurance map:"+occurrenceMap);
-
- if(refNode != null){
-
- try {
- Node cloneRefNode = refNode.cloneNode(true);
- String name = cloneRefNode.getAttributes().getNamedItem("name").getNodeValue();
- String occName = qdmNode.getAttributes().getNamedItem("instance").getNodeValue();
- cloneRefNode.getAttributes().getNamedItem("name").setNodeValue(occName + "_" + name);
-
- if (!occurrenceMap.containsKey(occName + occurString)) {
- occurrenceMap.remove(occurString);
- generateQDMEntry(dataCriteriaXMLProcessor, simpleXmlprocessor, cloneRefNode, true);
- occurrenceMap.put(occurString, refNode);
- occurrenceMap.put(occName + occurString, cloneRefNode);
- }
-
- String refRootValue = cloneRefNode.getAttributes().getNamedItem(ID).getNodeValue();
-
- String refDatatype = cloneRefNode.getAttributes().getNamedItem("datatype").getNodeValue();
- String refQdmName = cloneRefNode.getAttributes().getNamedItem("name").getNodeValue();
- String reExt = StringUtils.deleteWhitespace(refQdmName + "_" + refDatatype);
-
- Element outboundRelElem = dataCriteriaElem.getOwnerDocument().createElement("outboundRelationship");
- outboundRelElem.setAttribute("typeCode", "OCCR");
-
- Element criteriaRefElem = dataCriteriaElem.getOwnerDocument().createElement("criteriaReference");
- String refClassCodeValue = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
- String refMoodValue = templateNode.getAttributes().getNamedItem(MOOD).getNodeValue();
- criteriaRefElem.setAttribute(CLASS_CODE, refClassCodeValue);
- criteriaRefElem.setAttribute(MOOD_CODE, refMoodValue);
-
- Element idRelElem = dataCriteriaElem.getOwnerDocument().createElement(ID);
- idRelElem.setAttribute(ROOT, refRootValue);
- idRelElem.setAttribute("extension", reExt);
-
- criteriaRefElem.appendChild(idRelElem);
- outboundRelElem.appendChild(criteriaRefElem);
- dataCriteriaElem.appendChild(outboundRelElem);
- Node templateIdNode = dataCriteriaElem.getElementsByTagName("templateId").item(0);
- dataCriteriaElem.removeChild(templateIdNode);
- }
- catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- }
- }
-
- /**
- * Add Code Element To data Criteria Element based on condition.
- *
- * @param templateNode - Node
- * @param dataCriteriaXMLProcessor - XmlProcessor
- * @param qdmNode the qdm node
- * @param dataCriteriaElem - Element
- */
- private void addCodeElementToDataCriteriaElement(Node templateNode, XmlProcessor dataCriteriaXMLProcessor, Node qdmNode, Element dataCriteriaElem) {
- String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
- String qdmOidValue = qdmNode.getAttributes().getNamedItem(OID).getNodeValue();
-
- // Patient Characteristic data type - contains code tag with valueSetId
- // attribute and no title and value set tag.
- boolean isPatientChar = templateNode.getAttributes().getNamedItem("valueSetId") != null;
- boolean isAddValueSetInCodeTrue = templateNode.getAttributes().getNamedItem("addValueSetInCode") != null;
- boolean isIntervention = "Intervention, Order".equalsIgnoreCase(dataType)
- || "Intervention, Performed".equalsIgnoreCase(dataType)
- || "Intervention, Recommended".equalsIgnoreCase(dataType)
- || "Intervention, Not Ordered".equalsIgnoreCase(dataType)
- || "Intervention, Not Performed".equalsIgnoreCase(dataType)
- || "Intervention, Not Recommended".equalsIgnoreCase(dataType);
- if (isAddValueSetInCodeTrue) {
- Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
- Node valueTypeAttr = templateNode.getAttributes().getNamedItem("valueType");
- if (valueTypeAttr != null) {
- codeElem.setAttribute(XSI_TYPE, valueTypeAttr.getNodeValue());
- }
- codeElem.setAttribute("valueSet", qdmOidValue);
- addValueSetVersion(qdmNode, codeElem);
- dataCriteriaElem.appendChild(codeElem);
-
- } else if (isPatientChar) {
- Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
- codeElem.setAttribute(templateNode.getAttributes().getNamedItem("valueSetId").getNodeValue(), qdmOidValue);
- addValueSetVersion(qdmNode, codeElem);
- dataCriteriaElem.appendChild(codeElem);
- } else if (isIntervention) {
- Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
- codeElem.setAttribute("valueSet", qdmOidValue);
- addValueSetVersion(qdmNode, codeElem);
- dataCriteriaElem.appendChild(codeElem);
- } else {
- Element codeElement = createCodeForDatatype(templateNode, dataCriteriaXMLProcessor);
- if (codeElement != null) {
- dataCriteriaElem.appendChild(codeElement);
- }
- }
- }
-
- /**
- * This method is called for populating version/expansion Identifier of value set when value set attribute
- * mode is applied. If version is most recent, 1.0 or 1 is returned.
- * @param qdmNode
- * @return version
- */
- private String valueSetVersionStringValue(Node qdmNode){
- String version = qdmNode.getAttributes().getNamedItem("version").getNodeValue();
- if (!"1.0".equals(version) && !"1".equals(version) && StringUtils.isNotBlank(version)) {
- version = qdmNode.getAttributes().getNamedItem("version").getNodeValue();
- } else {
- version = null;
- }
- return version;
- }
- /**
- * Add SubTemplate defined in Template.xml to data criteria Element.
- *
- * @param templateNode - Node
- * @param dataCriteriaXMLProcessor - XmlProcessor for Data Criteria
- * @param templateXMLProcessor -XmlProcessor for Template Xml.
- * @param dataCriteriaElem - Element
- * @param qdmNode the qdm node
- * @throws XPathExpressionException the x path expression exception
- */
- private void appendSubTemplateNode(Node templateNode, XmlProcessor dataCriteriaXMLProcessor, XmlProcessor templateXMLProcessor,
- Element dataCriteriaElem, Node qdmNode) throws XPathExpressionException {
- String subTemplateName = templateNode.getAttributes().getNamedItem("includeSubTemplate").getNodeValue();
- Node subTemplateNode = templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), "/templates/subtemplates/" + subTemplateName);
- NodeList subTemplateNodeChilds = templateXMLProcessor.findNodeList(templateXMLProcessor.getOriginalDoc(), "/templates/subtemplates/" + subTemplateName + "/child::node()");
- String qdmOidValue = qdmNode.getAttributes().getNamedItem(OID).getNodeValue();
- String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
- String qdmNameDataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
- String qdmTaxonomy = qdmNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
-
- if (subTemplateNode.getAttributes().getNamedItem("changeAttribute") != null) {
- String[] attributeToBeModified = subTemplateNode.getAttributes().getNamedItem("changeAttribute").getNodeValue().split(",");
- for (String changeAttribute : attributeToBeModified) {
- NodeList attributedToBeChangedInNode = null;
- attributedToBeChangedInNode = templateXMLProcessor.findNodeList(templateXMLProcessor.getOriginalDoc(),
- "/templates/subtemplates/" + subTemplateName + "//" + changeAttribute);
- if (changeAttribute.equalsIgnoreCase(ID)) {
- String rootId = qdmNode.getAttributes().getNamedItem("uuid").getNodeValue();
- attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("root").setNodeValue(rootId);
- attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("extension").setNodeValue(java.util.UUID.randomUUID().toString());
- } else if (changeAttribute.equalsIgnoreCase(CODE)) {
- if (attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("code") != null) {
- attributedToBeChangedInNode.item(0).getAttributes().removeNamedItem("code");
- }
-
- if (attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("codeSystem") != null) {
- attributedToBeChangedInNode.item(0).getAttributes().removeNamedItem("codeSystem");
- }
-
- if (attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("codeSystemName") != null) {
- attributedToBeChangedInNode.item(0).getAttributes().removeNamedItem("codeSystemName");
- }
-
- if (attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("codeSystemVersion") != null) {
- attributedToBeChangedInNode.item(0).getAttributes().removeNamedItem("codeSystemVersion");
- }
-
- if (attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("valueSetVersion") != null) {
- attributedToBeChangedInNode.item(0).getAttributes().removeNamedItem("valueSetVersion");
- }
-
- Attr attrNodeValueSet = attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("valueSet");
- attrNodeValueSet.setNodeValue(qdmOidValue);
- attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attrNodeValueSet);
- String valueSetVersion = valueSetVersionStringValue(qdmNode);
-
- if (valueSetVersion != null) {
- Attr attrNode = attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("valueSetVersion");
- attrNode.setNodeValue(valueSetVersion);
- attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attrNode);
- }
-
- } else if (changeAttribute.equalsIgnoreCase(DISPLAY_NAME)) {
- attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("value").setNodeValue(HQMFDataCriteriaGenerator.removeOccurrenceFromName(qdmName) + " " + qdmTaxonomy + " value set");
- } else if (changeAttribute.equalsIgnoreCase(TITLE)) {
- attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("value").setNodeValue(qdmNameDataType);
- } else if (changeAttribute.equalsIgnoreCase(ITEM)) {
- for (int count = 0; count < attributedToBeChangedInNode.getLength(); count++) {
- Node itemNode = attributedToBeChangedInNode.item(count);
- itemNode.getAttributes().getNamedItem("extension").setNodeValue(extensionValue);
- }
-
- } else if (changeAttribute.equalsIgnoreCase("value")) {
- Attr attrNode = attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("valueSet");
- attrNode.setNodeValue(qdmOidValue);
- attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attrNode);
-
- }
-
- }
- }
-
- for (int i = 0; i < subTemplateNodeChilds.getLength(); i++) {
- Node childNode = subTemplateNodeChilds.item(i);
- Node nodeToAttach = dataCriteriaXMLProcessor.getOriginalDoc().importNode(childNode, true);
- XmlProcessor.clean(nodeToAttach);
- dataCriteriaElem.appendChild(nodeToAttach);
- }
- }
-
-
- /**
- * Adds the data criteria comment.
- *
- * @param dataCriteriaXMLProcessor the data criteria xml processor
- */
- private void addDataCriteriaComment(XmlProcessor dataCriteriaXMLProcessor) {
- Element element = dataCriteriaXMLProcessor.getOriginalDoc().getDocumentElement();
- Comment comment = dataCriteriaXMLProcessor.getOriginalDoc().createComment(
- "Data Criteria Section");
- element.getParentNode().insertBefore(comment, element);
- }
-
- /**
- * Creates the code for datatype.
- *
- * @param templateNode the template node
- * @param dataCriteriaXMLProcessor the data criteria xml processor
- * @return the element
- */
- protected Element createCodeForDatatype(Node templateNode, XmlProcessor dataCriteriaXMLProcessor) {
- Node codeAttr = templateNode.getAttributes().getNamedItem(CODE);
- Node codeSystemAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM);
- Node codeSystemNameAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM_NAME);
- Node codeDisplayNameAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM_DISPLAY_NAME);
- Element codeElement = null;
- if (codeAttr != null || codeSystemAttr != null || codeSystemNameAttr != null
- || codeDisplayNameAttr != null) {
- codeElement = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
- if (codeAttr != null) {
- codeElement.setAttribute(CODE, codeAttr.getNodeValue());
- }
- if (codeSystemAttr != null) {
- codeElement.setAttribute(CODE_SYSTEM, codeSystemAttr.getNodeValue());
- }
- if (codeSystemNameAttr != null) {
- codeElement.setAttribute(CODE_SYSTEM_NAME, codeSystemNameAttr.getNodeValue());
- }
- if (codeDisplayNameAttr != null) {
- Element displayNameElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
- displayNameElem.setAttribute(VALUE, codeDisplayNameAttr.getNodeValue());
- codeElement.appendChild(displayNameElem);
- }
- }
- return codeElement;
- }
-}
+ private static final String DATA_CRITERIA_EXTENSION = "2021-02-01";
+
+ /** The occurrence map. */
+ private Map occurrenceMap = new HashMap<>();
+
+ protected String extensionValue = null;
+
+ /** The Constant logger. */
+ private static final Logger logger =
+ LoggerFactory.getLogger(HQMFDataCriteriaElementGenerator.class);
+
+ /**
+ * Generate hqm for measure.
+ *
+ * @param me the me
+ * @return the string
+ */
+ @Override
+ public String generate(MeasureExport me) {
+ getExtensionValueBasedOnVersion(me);
+ XmlProcessor dataCriteriaXMLProcessor = createDateCriteriaTemplate();
+ me.setHqmfXmlProcessor(dataCriteriaXMLProcessor);
+
+ String simpleXMLStr = me.getSimpleXml();
+ XmlProcessor simpleXmlprocessor = new XmlProcessor(simpleXMLStr);
+ me.setSimpleXmlProcessor(simpleXmlprocessor);
+
+ createDataCriteriaForQDMELements(me, dataCriteriaXMLProcessor, simpleXmlprocessor);
+ addDataCriteriaComment(dataCriteriaXMLProcessor);
+ return dataCriteriaXMLProcessor.transform(dataCriteriaXMLProcessor.getOriginalDoc(), true);
+ }
+
+ /**
+ * Creates the date criteria template.
+ *
+ * @return the string
+ */
+ private XmlProcessor createDateCriteriaTemplate() {
+ XmlProcessor outputProcessor =
+ new XmlProcessor(
+ "");
+
+ Node dataCriteriaElem =
+ outputProcessor.getOriginalDoc().getElementsByTagName("dataCriteriaSection").item(0);
+ Element templateId = outputProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
+ dataCriteriaElem.appendChild(templateId);
+ Element itemChild = outputProcessor.getOriginalDoc().createElement(ITEM);
+ itemChild.setAttribute(ROOT, "2.16.840.1.113883.10.20.28.2.6");
+ // itemChild.setAttribute("extension", getDataCriteriaExtValueBasedOnVersion(me));
+ itemChild.setAttribute("extension", DATA_CRITERIA_EXTENSION);
+ templateId.appendChild(itemChild);
+ // creating Code Element for DataCriteria
+ Element codeElem = outputProcessor.getOriginalDoc().createElement(CODE);
+ codeElem.setAttribute(CODE, "57025-9");
+ codeElem.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.6.1");
+ dataCriteriaElem.appendChild(codeElem);
+ // creating title for DataCriteria
+ Element titleElem = outputProcessor.getOriginalDoc().createElement(TITLE);
+ titleElem.setAttribute(VALUE, "Data Criteria Section");
+ dataCriteriaElem.appendChild(titleElem);
+ // creating text for DataCriteria
+ Element textElem = outputProcessor.getOriginalDoc().createElement("text");
+ dataCriteriaElem.appendChild(textElem);
+
+ return outputProcessor;
+ }
+
+ private String getDataCriteriaExtValueBasedOnVersion() {
+ return VERSION_5_0_ID;
+ }
+
+ /**
+ * Creates the data criteria for qdm elements.
+ *
+ * @param me the me
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ */
+ private void createDataCriteriaForQDMELements(
+ MeasureExport me, XmlProcessor dataCriteriaXMLProcessor, XmlProcessor simpleXmlprocessor) {
+ String xPathForQDMNoAttribs = "/measure/elementLookUp/qdm[@datatype and @code ='false']";
+ String xpathForOtherSupplementalQDMs = "/measure/supplementalDataElements/elementRef/@id";
+ String xpathForMeasureGroupingItemCount = "/measure//itemCount/elementRef/@id";
+
+ try {
+ NodeList qdmNoAttributeNodeList =
+ simpleXmlprocessor.findNodeList(
+ simpleXmlprocessor.getOriginalDoc(), xPathForQDMNoAttribs);
+ generateCQLQDMNodeEntries(
+ dataCriteriaXMLProcessor, simpleXmlprocessor, qdmNoAttributeNodeList);
+
+ HQMFDataCriteriaElementGeneratorForCodes cqlBasedHQMFDataCriteriaElementGeneratorForCodes =
+ new HQMFDataCriteriaElementGeneratorForCodes();
+ cqlBasedHQMFDataCriteriaElementGeneratorForCodes.generate(me);
+
+ // generating QDM Entries for other Supplemental Data Elements
+ NodeList supplementalDataElements =
+ me.getSimpleXmlProcessor()
+ .findNodeList(
+ me.getSimpleXmlProcessor().getOriginalDoc(), xpathForOtherSupplementalQDMs);
+ generateOtherSupplementalDataQDMEntries(
+ me, dataCriteriaXMLProcessor, supplementalDataElements);
+
+ // generating QDM entries for measureGrouping ItemCountlist
+ NodeList measureGroupingItemCountList =
+ simpleXmlprocessor.findNodeList(
+ simpleXmlprocessor.getOriginalDoc(), xpathForMeasureGroupingItemCount);
+ generateMeasureGrpnItemCountQDMEntries(
+ me, dataCriteriaXMLProcessor, measureGroupingItemCountList);
+
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void getExtensionValueBasedOnVersion(MeasureExport me) {
+ if (me != null) {
+ extensionValue = getDataCriteriaExtValueBasedOnVersion();
+ }
+ }
+
+ /**
+ * Generate measure grp item count qdm entries.
+ *
+ * @param me the me
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param measureGroupingItemCountList the measure grouping item count list
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void generateMeasureGrpnItemCountQDMEntries(
+ MeasureExport me,
+ XmlProcessor dataCriteriaXMLProcessor,
+ NodeList measureGroupingItemCountList)
+ throws XPathExpressionException {
+
+ if (measureGroupingItemCountList == null || measureGroupingItemCountList.getLength() < 1) {
+ return;
+ }
+ List itemCountIDList = new ArrayList();
+ for (int i = 0; i < measureGroupingItemCountList.getLength(); i++) {
+ if (!itemCountIDList.contains(measureGroupingItemCountList.item(i).getNodeValue())) {
+ itemCountIDList.add(measureGroupingItemCountList.item(i).getNodeValue());
+ }
+ }
+ String xpathforElementLookUpElements =
+ "/measure/elementLookUp/qdm[" + getUUIDString(itemCountIDList) + "]";
+
+ NodeList measureGroupingElementRefNodeList =
+ me.getSimpleXmlProcessor()
+ .findNodeList(
+ me.getSimpleXmlProcessor().getOriginalDoc(), xpathforElementLookUpElements);
+ generateItemCountQDMEntries(me, dataCriteriaXMLProcessor, measureGroupingElementRefNodeList);
+ }
+
+ /**
+ * Generate supplemental data qdm entries.
+ *
+ * @param me the me
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param supplementalDataElements the supplemental data elements
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void generateOtherSupplementalDataQDMEntries(
+ MeasureExport me, XmlProcessor dataCriteriaXMLProcessor, NodeList supplementalDataElements)
+ throws XPathExpressionException {
+ if (supplementalDataElements == null || supplementalDataElements.getLength() < 1) {
+ return;
+ }
+ List supplementalElemenRefIds = new ArrayList();
+ for (int i = 0; i < supplementalDataElements.getLength(); i++) {
+ supplementalElemenRefIds.add(supplementalDataElements.item(i).getNodeValue());
+ }
+
+ String xpathforOtherSupplementalDataElements =
+ "/measure/elementLookUp/qdm["
+ + getUUIDString(supplementalElemenRefIds)
+ + "][@suppDataElement != 'true']";
+ NodeList otherSupplementalQDMNodeList =
+ me.getSimpleXmlProcessor()
+ .findNodeList(
+ me.getSimpleXmlProcessor().getOriginalDoc(), xpathforOtherSupplementalDataElements);
+
+ generateSupplementalDataQDMEntries(me, dataCriteriaXMLProcessor, otherSupplementalQDMNodeList);
+ }
+
+ /**
+ * Generate supplemental data qdm entries.
+ *
+ * @param me the me
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param qdmNodeList the qdm node list
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void generateSupplementalDataQDMEntries(
+ MeasureExport me, XmlProcessor dataCriteriaXMLProcessor, NodeList qdmNodeList)
+ throws XPathExpressionException {
+ for (int j = 0; j < qdmNodeList.getLength(); j++) {
+ Node qdmNode = qdmNodeList.item(j);
+ String qdmName = qdmNode.getAttributes().getNamedItem("name").getNodeValue();
+ String qdmDatatype = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String qdmUUID = qdmNode.getAttributes().getNamedItem("uuid").getNodeValue();
+ String qdmExtension = qdmName.replaceAll("\\s", "") + "_" + qdmDatatype.replaceAll("\\s", "");
+ String xpathForQDMEntry =
+ "/root/component/dataCriteriaSection/entry/*/id[@root='"
+ + qdmUUID
+ + "'][@extension=\""
+ + qdmExtension
+ + "\"]";
+ Node qmdEntryIDNode =
+ dataCriteriaXMLProcessor.findNode(
+ dataCriteriaXMLProcessor.getOriginalDoc(), xpathForQDMEntry);
+ if (qmdEntryIDNode == null) {
+ createXmlForDataCriteria(qdmNode, dataCriteriaXMLProcessor, me.getSimpleXmlProcessor());
+ }
+ }
+ }
+
+ /**
+ * Generate Item Count qdm entries.
+ *
+ * @param me the me
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param qdmNodeList the qdm node list
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void generateItemCountQDMEntries(
+ MeasureExport me, XmlProcessor dataCriteriaXMLProcessor, NodeList qdmNodeList)
+ throws XPathExpressionException {
+ for (int j = 0; j < qdmNodeList.getLength(); j++) {
+ Node qdmNode = qdmNodeList.item(j);
+ String qdmName = qdmNode.getAttributes().getNamedItem("name").getNodeValue();
+ String qdmDatatype = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String qdmUUID = qdmNode.getAttributes().getNamedItem("uuid").getNodeValue();
+ String qdmExtension = qdmName.replaceAll("\\s", "") + "_" + qdmDatatype.replaceAll("\\s", "");
+ if (qdmNode.getAttributes().getNamedItem("instance") != null) {
+ String instanceOfValue = qdmNode.getAttributes().getNamedItem("instance").getNodeValue();
+ String newExtension = instanceOfValue.replaceAll("\\s", "") + "_" + qdmExtension;
+ qdmExtension = newExtension;
+ }
+ String xpathForQDMEntry =
+ "/root/component/dataCriteriaSection/entry/*/id[@root='"
+ + qdmUUID
+ + "'][@extension=\""
+ + qdmExtension
+ + "\"]";
+ Node qmdEntryIDNode =
+ dataCriteriaXMLProcessor.findNode(
+ dataCriteriaXMLProcessor.getOriginalDoc(), xpathForQDMEntry);
+ if (qmdEntryIDNode == null) {
+ createXmlForDataCriteria(qdmNode, dataCriteriaXMLProcessor, me.getSimpleXmlProcessor());
+ }
+ }
+ }
+
+ /**
+ * Gets the UUID string.
+ *
+ * @param uuidList the uuid list
+ * @return the UUID string
+ */
+ private String getUUIDString(List uuidList) {
+ String uuidXPathString = "";
+ for (String uuidString : uuidList) {
+ uuidXPathString += "@uuid = '" + uuidString + "' or";
+ }
+
+ uuidXPathString = uuidXPathString.substring(0, uuidXPathString.lastIndexOf(" or"));
+ return uuidXPathString;
+ }
+
+ private void generateCQLQDMNodeEntries(
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ NodeList qdmNoAttributeNodeList)
+ throws XPathExpressionException {
+
+ if (qdmNoAttributeNodeList == null) {
+ return;
+ }
+
+ for (int i = 0; i < qdmNoAttributeNodeList.getLength(); i++) {
+ Node qdmNode = qdmNoAttributeNodeList.item(i);
+ createXmlForDataCriteria(qdmNode, dataCriteriaXMLProcessor, simpleXmlprocessor);
+ }
+ }
+
+ /**
+ * Generate qdm entry.
+ *
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param qdmNode the qdm node
+ * @param forceGenerate the force generate
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void generateQDMEntry(
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ Node qdmNode,
+ boolean forceGenerate)
+ throws XPathExpressionException {
+ String qdmUUID = qdmNode.getAttributes().getNamedItem(UUID).getNodeValue();
+
+ String xPathForIndividualElementRefs =
+ "/measure/subTreeLookUp//elementRef[@id='" + qdmUUID + "'][not(attribute)]";
+ NodeList elementRefList =
+ simpleXmlprocessor.findNodeList(
+ simpleXmlprocessor.getOriginalDoc(), xPathForIndividualElementRefs);
+ if (forceGenerate || elementRefList.getLength() > 0) {
+ createXmlForDataCriteria(qdmNode, dataCriteriaXMLProcessor, simpleXmlprocessor);
+ }
+ }
+
+ /**
+ * Create xml for data criteria.
+ *
+ * @param qdmNode the qdm node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @return void
+ */
+ private void createXmlForDataCriteria(
+ Node qdmNode, XmlProcessor dataCriteriaXMLProcessor, XmlProcessor simpleXmlprocessor) {
+ String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+
+ XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(5.6);
+ String xPathForTemplate = "/templates/template[text()='" + dataType.toLowerCase() + "']";
+ String actNodeStr = "";
+ try {
+
+ Node templateNode =
+ templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xPathForTemplate);
+ if (templateNode != null) {
+ String attrClass = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
+ String xpathForAct = "/templates/acts/act[@a_id='" + attrClass + "']";
+ Node actNode =
+ templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xpathForAct);
+ if (actNode != null) {
+ actNodeStr = actNode.getTextContent();
+ }
+
+ createDataCriteriaElementTag(
+ actNodeStr,
+ templateNode,
+ qdmNode,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor,
+ templateXMLProcessor);
+ }
+
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Gets the creates the data create element tag.
+ *
+ * @param actNodeStr the act node str
+ * @param templateNode the template node
+ * @param qdmNode the qdm node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ * @param templateXMLProcessor - templateXmlProcessor
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void createDataCriteriaElementTag(
+ String actNodeStr,
+ Node templateNode,
+ Node qdmNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ XmlProcessor templateXMLProcessor)
+ throws XPathExpressionException {
+ String oidValue = templateNode.getAttributes().getNamedItem(OID).getNodeValue();
+ String classCodeValue = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
+ String moodValue = templateNode.getAttributes().getNamedItem(MOOD).getNodeValue();
+
+ Node statusNode = templateNode.getAttributes().getNamedItem("status");
+ String statusValue = statusNode != null ? statusNode.getNodeValue() : "";
+ String rootValue = qdmNode.getAttributes().getNamedItem(ID).getNodeValue();
+ String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String qdmOidValue = qdmNode.getAttributes().getNamedItem(OID).getNodeValue();
+
+ String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ Node actionNegInd = templateNode.getAttributes().getNamedItem("actionNegationInd");
+ String entryCommentText = dataType;
+ // Local variable changes.
+ String qdmLocalVariableName = qdmName + "_" + dataType;
+ String localVariableName = qdmLocalVariableName;
+
+ qdmLocalVariableName = StringUtils.deleteWhitespace(qdmLocalVariableName);
+ localVariableName = StringUtils.deleteWhitespace(localVariableName);
+
+ Element dataCriteriaSectionElem =
+ (Element)
+ dataCriteriaXMLProcessor
+ .getOriginalDoc()
+ .getElementsByTagName("dataCriteriaSection")
+ .item(0);
+ Element componentElem =
+ (Element)
+ dataCriteriaXMLProcessor.getOriginalDoc().getElementsByTagName("component").item(0);
+ Attr nameSpaceAttr = dataCriteriaXMLProcessor.getOriginalDoc().createAttribute("xmlns:xsi");
+ nameSpaceAttr.setNodeValue(nameSpace);
+ componentElem.setAttributeNodeNS(nameSpaceAttr);
+ Attr qdmNameSpaceAttr =
+ dataCriteriaXMLProcessor.getOriginalDoc().createAttribute("xmlns:cql-ext");
+ qdmNameSpaceAttr.setNodeValue("urn:hhs-cql:hqmf-n1-extensions:v1");
+ componentElem.setAttributeNodeNS(qdmNameSpaceAttr);
+ // creating Entry Tag
+ Element entryElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement("entry");
+ entryElem.setAttribute(TYPE_CODE, "DRIV");
+ // Local Variable Name Tag - Inside Entry tag.
+ Element localVarElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement("localVariableName");
+ localVarElem.setAttribute(VALUE, localVariableName + "_" + UUIDUtilClient.uuid(5));
+ entryElem.appendChild(localVarElem);
+ Element dataCriteriaElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(actNodeStr);
+ entryElem.appendChild(dataCriteriaElem);
+ dataCriteriaElem.setAttribute(CLASS_CODE, classCodeValue);
+ dataCriteriaElem.setAttribute(MOOD_CODE, moodValue);
+ // adding actionNegationInd for Negative Datatypes
+ if (actionNegInd != null) {
+ dataCriteriaElem.setAttribute(ACTION_NEGATION_IND, actionNegInd.getNodeValue());
+ }
+ Element templateId = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
+ dataCriteriaElem.appendChild(templateId);
+ Element itemChild = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ITEM);
+ itemChild.setAttribute(ROOT, oidValue);
+ if (templateNode.getAttributes().getNamedItem("specificExtensionValue") != null) {
+ String specificExtensionValue =
+ templateNode.getAttributes().getNamedItem("specificExtensionValue").getNodeValue();
+ itemChild.setAttribute("extension", specificExtensionValue);
+ } else if (templateNode.getAttributes().getNamedItem("addExtensionInTemplate") == null) {
+ itemChild.setAttribute("extension", extensionValue);
+ }
+ templateId.appendChild(itemChild);
+ Element idElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ID);
+ idElem.setAttribute(ROOT, rootValue);
+ idElem.setAttribute("extension", qdmLocalVariableName);
+ dataCriteriaElem.appendChild(idElem);
+
+ boolean appendEntryElem = false;
+ String occurString = dataType + "-" + qdmOidValue;
+
+ if (qdmNode.getAttributes().getNamedItem("instance") != null) {
+ generateOutboundForOccur(
+ templateNode,
+ qdmNode,
+ dataCriteriaElem,
+ occurString,
+ dataCriteriaXMLProcessor,
+ simpleXmlprocessor);
+ entryCommentText =
+ qdmNode.getAttributes().getNamedItem("instance").getNodeValue() + " " + entryCommentText;
+ appendEntryElem = true;
+ } else if (!occurrenceMap.containsKey(occurString) /* || (attributeQDMNode != null) */) {
+
+ String isAddCodeTag = templateNode.getAttributes().getNamedItem("addCodeTag").getNodeValue();
+ if ("true".equalsIgnoreCase(isAddCodeTag)) { // Add Code Element to DataCriteria Element.
+ addCodeElementToDataCriteriaElement(
+ templateNode, dataCriteriaXMLProcessor, qdmNode, dataCriteriaElem);
+ }
+ Element titleElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TITLE);
+ titleElem.setAttribute(VALUE, dataType);
+ dataCriteriaElem.appendChild(titleElem);
+
+ if (StringUtils.isNotEmpty(statusValue)) {
+ Element statusCodeElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement("statusCode");
+ statusCodeElem.setAttribute(CODE, statusValue);
+ dataCriteriaElem.appendChild(statusCodeElem);
+ }
+
+ // Add value tag in entry element.
+ String addValueSetElement =
+ templateNode.getAttributes().getNamedItem("addValueTag").getNodeValue();
+ if ("true".equalsIgnoreCase(addValueSetElement)) {
+ Element valueElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(VALUE);
+ Node valueTypeAttr = templateNode.getAttributes().getNamedItem("valueType");
+ if (valueTypeAttr != null) {
+ valueElem.setAttribute(XSI_TYPE, valueTypeAttr.getNodeValue());
+ }
+
+ Node valueCodeSystem = templateNode.getAttributes().getNamedItem("valueCodeSystem");
+ Node valueCode = templateNode.getAttributes().getNamedItem("valueCode");
+ Node valueDisplayName = templateNode.getAttributes().getNamedItem("valueDisplayName");
+ Node valueCodeSystemName = templateNode.getAttributes().getNamedItem("valueCodeSystemName");
+ if (valueCode != null && valueCodeSystem != null) {
+ valueElem.setAttribute("code", valueCode.getNodeValue());
+ valueElem.setAttribute("codeSystem", valueCodeSystem.getNodeValue());
+ if (valueCodeSystemName != null) {
+ valueElem.setAttribute("codeSystemName", valueCodeSystemName.getNodeValue());
+ }
+ } else {
+ valueElem.setAttribute("valueSet", qdmOidValue);
+ addValueSetVersion(qdmNode, valueElem);
+ }
+
+ dataCriteriaElem.appendChild(valueElem);
+ }
+ if (templateNode.getAttributes().getNamedItem("includeSubTemplate") != null) {
+ appendSubTemplateNode(
+ templateNode,
+ dataCriteriaXMLProcessor,
+ templateXMLProcessor,
+ dataCriteriaElem,
+ qdmNode);
+ }
+ // checkForAttributes
+
+ appendEntryElem = true;
+ }
+ if (appendEntryElem) {
+ dataCriteriaSectionElem.appendChild(entryElem);
+ }
+ }
+
+ /**
+ * Method to add valueSetVersion attribute in value element tag.
+ *
+ * @param qdmNode the qdm node
+ * @param valueElem the value elem
+ */
+ protected void addValueSetVersion(Node qdmNode, Element valueElem) {
+ // This is to be commented until we start getting value set versions from VSAC.
+ boolean addVersionToValueTag = false;
+ String valueSetVersion = qdmNode.getAttributes().getNamedItem("version").getNodeValue();
+
+ if ("1.0".equals(valueSetVersion)
+ || "1".equals(valueSetVersion)
+ || StringUtils.isBlank(valueSetVersion)) {
+ addVersionToValueTag = false;
+ } else {
+ valueSetVersion = qdmNode.getAttributes().getNamedItem("version").getNodeValue();
+ addVersionToValueTag = true;
+ }
+ if (addVersionToValueTag) {
+ valueElem.setAttribute("valueSetVersion", valueSetVersion);
+ }
+ }
+
+ /**
+ * Generate outbound for occur.
+ *
+ * @param templateNode the template node
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem the data criteria elem
+ * @param occurString the occur string
+ */
+ private void generateOutboundForOccur(
+ Node templateNode,
+ Node qdmNode,
+ Element dataCriteriaElem,
+ String occurString,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor) {
+ Node refNode = occurrenceMap.get(occurString);
+
+ logger.debug("In generateOutboundForOccur()..refNode:" + refNode);
+ logger.debug("----------Occurance map:" + occurrenceMap);
+
+ if (refNode != null) {
+
+ try {
+ Node cloneRefNode = refNode.cloneNode(true);
+ String name = cloneRefNode.getAttributes().getNamedItem("name").getNodeValue();
+ String occName = qdmNode.getAttributes().getNamedItem("instance").getNodeValue();
+ cloneRefNode.getAttributes().getNamedItem("name").setNodeValue(occName + "_" + name);
+
+ if (!occurrenceMap.containsKey(occName + occurString)) {
+ occurrenceMap.remove(occurString);
+ generateQDMEntry(dataCriteriaXMLProcessor, simpleXmlprocessor, cloneRefNode, true);
+ occurrenceMap.put(occurString, refNode);
+ occurrenceMap.put(occName + occurString, cloneRefNode);
+ }
+
+ String refRootValue = cloneRefNode.getAttributes().getNamedItem(ID).getNodeValue();
+
+ String refDatatype = cloneRefNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String refQdmName = cloneRefNode.getAttributes().getNamedItem("name").getNodeValue();
+ String reExt = StringUtils.deleteWhitespace(refQdmName + "_" + refDatatype);
+
+ Element outboundRelElem =
+ dataCriteriaElem.getOwnerDocument().createElement("outboundRelationship");
+ outboundRelElem.setAttribute("typeCode", "OCCR");
+
+ Element criteriaRefElem =
+ dataCriteriaElem.getOwnerDocument().createElement("criteriaReference");
+ String refClassCodeValue = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
+ String refMoodValue = templateNode.getAttributes().getNamedItem(MOOD).getNodeValue();
+ criteriaRefElem.setAttribute(CLASS_CODE, refClassCodeValue);
+ criteriaRefElem.setAttribute(MOOD_CODE, refMoodValue);
+
+ Element idRelElem = dataCriteriaElem.getOwnerDocument().createElement(ID);
+ idRelElem.setAttribute(ROOT, refRootValue);
+ idRelElem.setAttribute("extension", reExt);
+
+ criteriaRefElem.appendChild(idRelElem);
+ outboundRelElem.appendChild(criteriaRefElem);
+ dataCriteriaElem.appendChild(outboundRelElem);
+ Node templateIdNode = dataCriteriaElem.getElementsByTagName("templateId").item(0);
+ dataCriteriaElem.removeChild(templateIdNode);
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Add Code Element To data Criteria Element based on condition.
+ *
+ * @param templateNode - Node
+ * @param dataCriteriaXMLProcessor - XmlProcessor
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem - Element
+ */
+ private void addCodeElementToDataCriteriaElement(
+ Node templateNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ Node qdmNode,
+ Element dataCriteriaElem) {
+ String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String qdmOidValue = qdmNode.getAttributes().getNamedItem(OID).getNodeValue();
+
+ // Patient Characteristic data type - contains code tag with valueSetId
+ // attribute and no title and value set tag.
+ boolean isPatientChar = templateNode.getAttributes().getNamedItem("valueSetId") != null;
+ boolean isAddValueSetInCodeTrue =
+ templateNode.getAttributes().getNamedItem("addValueSetInCode") != null;
+ boolean isIntervention =
+ "Intervention, Order".equalsIgnoreCase(dataType)
+ || "Intervention, Performed".equalsIgnoreCase(dataType)
+ || "Intervention, Recommended".equalsIgnoreCase(dataType)
+ || "Intervention, Not Ordered".equalsIgnoreCase(dataType)
+ || "Intervention, Not Performed".equalsIgnoreCase(dataType)
+ || "Intervention, Not Recommended".equalsIgnoreCase(dataType);
+ if (isAddValueSetInCodeTrue) {
+ Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ Node valueTypeAttr = templateNode.getAttributes().getNamedItem("valueType");
+ if (valueTypeAttr != null) {
+ codeElem.setAttribute(XSI_TYPE, valueTypeAttr.getNodeValue());
+ }
+ codeElem.setAttribute("valueSet", qdmOidValue);
+ addValueSetVersion(qdmNode, codeElem);
+ dataCriteriaElem.appendChild(codeElem);
+
+ } else if (isPatientChar) {
+ Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ codeElem.setAttribute(
+ templateNode.getAttributes().getNamedItem("valueSetId").getNodeValue(), qdmOidValue);
+ addValueSetVersion(qdmNode, codeElem);
+ dataCriteriaElem.appendChild(codeElem);
+ } else if (isIntervention) {
+ Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ codeElem.setAttribute("valueSet", qdmOidValue);
+ addValueSetVersion(qdmNode, codeElem);
+ dataCriteriaElem.appendChild(codeElem);
+ } else {
+ Element codeElement = createCodeForDatatype(templateNode, dataCriteriaXMLProcessor);
+ if (codeElement != null) {
+ dataCriteriaElem.appendChild(codeElement);
+ }
+ }
+ }
+
+ /**
+ * This method is called for populating version/expansion Identifier of value set when value set
+ * attribute mode is applied. If version is most recent, 1.0 or 1 is returned.
+ *
+ * @param qdmNode
+ * @return version
+ */
+ private String valueSetVersionStringValue(Node qdmNode) {
+ String version = qdmNode.getAttributes().getNamedItem("version").getNodeValue();
+ if (!"1.0".equals(version) && !"1".equals(version) && StringUtils.isNotBlank(version)) {
+ version = qdmNode.getAttributes().getNamedItem("version").getNodeValue();
+ } else {
+ version = null;
+ }
+ return version;
+ }
+
+ /**
+ * Add SubTemplate defined in Template.xml to data criteria Element.
+ *
+ * @param templateNode - Node
+ * @param dataCriteriaXMLProcessor - XmlProcessor for Data Criteria
+ * @param templateXMLProcessor -XmlProcessor for Template Xml.
+ * @param dataCriteriaElem - Element
+ * @param qdmNode the qdm node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void appendSubTemplateNode(
+ Node templateNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor templateXMLProcessor,
+ Element dataCriteriaElem,
+ Node qdmNode)
+ throws XPathExpressionException {
+ String subTemplateName =
+ templateNode.getAttributes().getNamedItem("includeSubTemplate").getNodeValue();
+ Node subTemplateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(), "/templates/subtemplates/" + subTemplateName);
+ NodeList subTemplateNodeChilds =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "/child::node()");
+ String qdmOidValue = qdmNode.getAttributes().getNamedItem(OID).getNodeValue();
+ String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ String qdmNameDataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String qdmTaxonomy = qdmNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
+
+ if (subTemplateNode.getAttributes().getNamedItem("changeAttribute") != null) {
+ String[] attributeToBeModified =
+ subTemplateNode.getAttributes().getNamedItem("changeAttribute").getNodeValue().split(",");
+ for (String changeAttribute : attributeToBeModified) {
+ NodeList attributedToBeChangedInNode = null;
+ attributedToBeChangedInNode =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "//" + changeAttribute);
+ if (changeAttribute.equalsIgnoreCase(ID)) {
+ String rootId = qdmNode.getAttributes().getNamedItem("uuid").getNodeValue();
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("root")
+ .setNodeValue(rootId);
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("extension")
+ .setNodeValue(java.util.UUID.randomUUID().toString());
+ } else if (changeAttribute.equalsIgnoreCase(CODE)) {
+ if (attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("code") != null) {
+ attributedToBeChangedInNode.item(0).getAttributes().removeNamedItem("code");
+ }
+
+ if (attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("codeSystem")
+ != null) {
+ attributedToBeChangedInNode.item(0).getAttributes().removeNamedItem("codeSystem");
+ }
+
+ if (attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("codeSystemName")
+ != null) {
+ attributedToBeChangedInNode.item(0).getAttributes().removeNamedItem("codeSystemName");
+ }
+
+ if (attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("codeSystemVersion")
+ != null) {
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .removeNamedItem("codeSystemVersion");
+ }
+
+ if (attributedToBeChangedInNode.item(0).getAttributes().getNamedItem("valueSetVersion")
+ != null) {
+ attributedToBeChangedInNode.item(0).getAttributes().removeNamedItem("valueSetVersion");
+ }
+
+ Attr attrNodeValueSet =
+ attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("valueSet");
+ attrNodeValueSet.setNodeValue(qdmOidValue);
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attrNodeValueSet);
+ String valueSetVersion = valueSetVersionStringValue(qdmNode);
+
+ if (valueSetVersion != null) {
+ Attr attrNode =
+ attributedToBeChangedInNode
+ .item(0)
+ .getOwnerDocument()
+ .createAttribute("valueSetVersion");
+ attrNode.setNodeValue(valueSetVersion);
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attrNode);
+ }
+
+ } else if (changeAttribute.equalsIgnoreCase(DISPLAY_NAME)) {
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("value")
+ .setNodeValue(
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(qdmName)
+ + " "
+ + qdmTaxonomy
+ + " value set");
+ } else if (changeAttribute.equalsIgnoreCase(TITLE)) {
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .getNamedItem("value")
+ .setNodeValue(qdmNameDataType);
+ } else if (changeAttribute.equalsIgnoreCase(ITEM)) {
+ for (int count = 0; count < attributedToBeChangedInNode.getLength(); count++) {
+ Node itemNode = attributedToBeChangedInNode.item(count);
+ itemNode.getAttributes().getNamedItem("extension").setNodeValue(extensionValue);
+ }
+
+ } else if (changeAttribute.equalsIgnoreCase("value")) {
+ Attr attrNode =
+ attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("valueSet");
+ attrNode.setNodeValue(qdmOidValue);
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(attrNode);
+ }
+ }
+ }
+
+ for (int i = 0; i < subTemplateNodeChilds.getLength(); i++) {
+ Node childNode = subTemplateNodeChilds.item(i);
+ Node nodeToAttach = dataCriteriaXMLProcessor.getOriginalDoc().importNode(childNode, true);
+ XmlProcessor.clean(nodeToAttach);
+ dataCriteriaElem.appendChild(nodeToAttach);
+ }
+ }
+
+ /**
+ * Adds the data criteria comment.
+ *
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ */
+ private void addDataCriteriaComment(XmlProcessor dataCriteriaXMLProcessor) {
+ Element element = dataCriteriaXMLProcessor.getOriginalDoc().getDocumentElement();
+ Comment comment =
+ dataCriteriaXMLProcessor.getOriginalDoc().createComment("Data Criteria Section");
+ element.getParentNode().insertBefore(comment, element);
+ }
+
+ /**
+ * Creates the code for datatype.
+ *
+ * @param templateNode the template node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @return the element
+ */
+ protected Element createCodeForDatatype(
+ Node templateNode, XmlProcessor dataCriteriaXMLProcessor) {
+ Node codeAttr = templateNode.getAttributes().getNamedItem(CODE);
+ Node codeSystemAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM);
+ Node codeSystemNameAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM_NAME);
+ Node codeDisplayNameAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM_DISPLAY_NAME);
+ Element codeElement = null;
+ if (codeAttr != null
+ || codeSystemAttr != null
+ || codeSystemNameAttr != null
+ || codeDisplayNameAttr != null) {
+ codeElement = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ if (codeAttr != null) {
+ codeElement.setAttribute(CODE, codeAttr.getNodeValue());
+ }
+ if (codeSystemAttr != null) {
+ codeElement.setAttribute(CODE_SYSTEM, codeSystemAttr.getNodeValue());
+ }
+ if (codeSystemNameAttr != null) {
+ codeElement.setAttribute(CODE_SYSTEM_NAME, codeSystemNameAttr.getNodeValue());
+ }
+ if (codeDisplayNameAttr != null) {
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ displayNameElem.setAttribute(VALUE, codeDisplayNameAttr.getNodeValue());
+ codeElement.appendChild(displayNameElem);
+ }
+ }
+ return codeElement;
+ }
+}
diff --git a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaElementGeneratorForCodes.java b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaElementGeneratorForCodes.java
index 1898cd1..7d80dfb 100644
--- a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaElementGeneratorForCodes.java
+++ b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaElementGeneratorForCodes.java
@@ -1,4 +1,3 @@
-
package gov.cms.madie.hqmf.qdm_5_6;
import gov.cms.madie.hqmf.Generator;
@@ -13,521 +12,551 @@
import javax.xml.xpath.XPathExpressionException;
-/**
- * The Class CQLBasedHQMFDataCriteriaElementGenerator.
- */
+/** The Class CQLBasedHQMFDataCriteriaElementGenerator. */
public class HQMFDataCriteriaElementGeneratorForCodes implements Generator {
- protected String extensionValue = null;
-
- /**
- * Generate hqm for measure.
- *
- * @param me
- * the me
- * @return the string
- */
- @Override
- public String generate(MeasureExport me) {
- getExtensionValueBasedOnVersion(me);
- XmlProcessor dataCriteriaXMLProcessor = me.getHqmfXmlProcessor();
-
- createDataCriteriaForQDMELements(dataCriteriaXMLProcessor, me.getSimpleXmlProcessor());
- return dataCriteriaXMLProcessor.transform(dataCriteriaXMLProcessor.getOriginalDoc(), true);
- }
-
- private String getDataCriteriaExtValueBasedOnVersion(MeasureExport me) {
- // TODO: get rid of the parameter - even better, get rid of this method and use the constant!
- return VERSION_5_0_ID;
- }
-
- /**
- * Creates the data criteria for qdm elements.
- *
- * @param dataCriteriaXMLProcessor
- * the data criteria xml processor
- * @param simpleXmlprocessor
- * the simple xmlprocessor
- */
- private void createDataCriteriaForQDMELements(XmlProcessor dataCriteriaXMLProcessor,
- XmlProcessor simpleXmlprocessor) {
-
- String xPathForDirectReferenceCodes = "/measure/elementLookUp/qdm[@datatype and @code ='true']";
-
- try {
- NodeList directReferenceCodeNodeList = simpleXmlprocessor.findNodeList(simpleXmlprocessor.getOriginalDoc(),
- xPathForDirectReferenceCodes);
- generateCQLDRCNodeEntries(dataCriteriaXMLProcessor, simpleXmlprocessor, directReferenceCodeNodeList);
-
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- }
-
- protected void getExtensionValueBasedOnVersion(MeasureExport me) {
- // TODO: get rid of this function too...boil up the constant
- if (me != null) {
- extensionValue = getDataCriteriaExtValueBasedOnVersion(me);
- }
- }
-
- private void generateCQLDRCNodeEntries(XmlProcessor dataCriteriaXMLProcessor, XmlProcessor simpleXmlprocessor,
- NodeList qdmNoAttributeNodeList) throws XPathExpressionException {
-
- if (qdmNoAttributeNodeList == null) {
- return;
- }
-
- for (int i = 0; i < qdmNoAttributeNodeList.getLength(); i++) {
- Node qdmNode = qdmNoAttributeNodeList.item(i);
- createXmlForDataCriteria(qdmNode, dataCriteriaXMLProcessor, simpleXmlprocessor);
- }
- }
-
- /**
- * Create xml for data criteria.
- *
- * @param qdmNode
- * the qdm node
- * @param dataCriteriaXMLProcessor
- * the data criteria xml processor
- * @param simpleXmlprocessor
- * the simple xmlprocessor
- */
- private void createXmlForDataCriteria(Node qdmNode, XmlProcessor dataCriteriaXMLProcessor,
- XmlProcessor simpleXmlprocessor) {
- String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
-
- XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(5.6);
- String xPathForTemplate = "/templates/template[text()='" + dataType.toLowerCase() + "']";
- String actNodeStr = "";
- try {
-
- Node templateNode = templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xPathForTemplate);
- if (templateNode != null) {
- String attrClass = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
- String xpathForAct = "/templates/acts/act[@a_id='" + attrClass + "']";
- Node actNode = templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xpathForAct);
- if (actNode != null) {
- actNodeStr = actNode.getTextContent();
- }
-
- createDataCriteriaElementTag(actNodeStr, templateNode, qdmNode, dataCriteriaXMLProcessor,
- templateXMLProcessor);
- }
-
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Gets the creates the data create element tag.
- *
- * @param actNodeStr
- * the act node str
- * @param templateNode
- * the template node
- * @param qdmNode
- * the qdm node
- * @param dataCriteriaXMLProcessor
- * the data criteria xml processor
- * @param templateXMLProcessor
- * - templateXmlProcessor
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private void createDataCriteriaElementTag(String actNodeStr,
- Node templateNode,
- Node qdmNode,
- XmlProcessor dataCriteriaXMLProcessor,
- XmlProcessor templateXMLProcessor)
- throws XPathExpressionException {
- String oidValue = templateNode.getAttributes().getNamedItem(OID).getNodeValue();
- String classCodeValue = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
- String moodValue = templateNode.getAttributes().getNamedItem(MOOD).getNodeValue();
- Node statusNode= templateNode.getAttributes().getNamedItem("status");
- String statusValue = statusNode != null ? statusNode.getNodeValue() : "";
- String rootValue = qdmNode.getAttributes().getNamedItem(ID).getNodeValue();
- String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
-
- Node actionNegInd = templateNode.getAttributes().getNamedItem("actionNegationInd");
- String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
- // Stan wants to generate unique id ( extension and root combination
- // which is different from Value set).
- String qdmLocalVariableName = codeOID + "_" + dataType;
-
- qdmLocalVariableName = StringUtils.deleteWhitespace(qdmLocalVariableName);
-
- Element dataCriteriaSectionElem = (Element) dataCriteriaXMLProcessor.getOriginalDoc()
- .getElementsByTagName("dataCriteriaSection").item(0);
- Element componentElem = (Element) dataCriteriaXMLProcessor.getOriginalDoc().getElementsByTagName("component")
- .item(0);
- Attr nameSpaceAttr = dataCriteriaXMLProcessor.getOriginalDoc().createAttribute("xmlns:xsi");
- nameSpaceAttr.setNodeValue(nameSpace);
- componentElem.setAttributeNodeNS(nameSpaceAttr);
- // xmlns:qdm="urn:hhs-qdm:hqmf-r2-extensions:v1"
- Attr qdmNameSpaceAttr = dataCriteriaXMLProcessor.getOriginalDoc().createAttribute("xmlns:cql-ext");
- qdmNameSpaceAttr.setNodeValue("urn:hhs-cql:hqmf-n1-extensions:v1");
- componentElem.setAttributeNodeNS(qdmNameSpaceAttr);
- // creating Entry Tag
- Element entryElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement("entry");
- entryElem.setAttribute(TYPE_CODE, "DRIV");
-
-
- Element dataCriteriaElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(actNodeStr);
- entryElem.appendChild(dataCriteriaElem);
- dataCriteriaElem.setAttribute(CLASS_CODE, classCodeValue);
- dataCriteriaElem.setAttribute(MOOD_CODE, moodValue);
- // adding actionNegationInd for Negative Datatypes
- if (actionNegInd != null) {
- dataCriteriaElem.setAttribute(ACTION_NEGATION_IND, actionNegInd.getNodeValue());
- }
- Element templateId = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
- dataCriteriaElem.appendChild(templateId);
- Element itemChild = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ITEM);
- itemChild.setAttribute(ROOT, oidValue);
- if(templateNode.getAttributes().getNamedItem("specificExtensionValue") != null){
- String specificExtensionValue = templateNode.getAttributes().getNamedItem("specificExtensionValue").getNodeValue();
- itemChild.setAttribute("extension", specificExtensionValue);
- }
- else if (templateNode.getAttributes().getNamedItem("addExtensionInTemplate") == null) {
- itemChild.setAttribute("extension", extensionValue);
- }
- templateId.appendChild(itemChild);
- Element idElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ID);
- idElem.setAttribute(ROOT, rootValue);
- idElem.setAttribute("extension", qdmLocalVariableName);
- dataCriteriaElem.appendChild(idElem);
-
- //boolean appendEntryElem = false;
-
- String isAddCodeTag = templateNode.getAttributes().getNamedItem("addCodeTag").getNodeValue();
- if ("true".equalsIgnoreCase(isAddCodeTag)) { // Add Code Element to
- // DataCriteria Element.
- addCodeElementToDataCriteriaElement(templateNode, dataCriteriaXMLProcessor, qdmNode, dataCriteriaElem);
- }
- Element titleElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TITLE);
- titleElem.setAttribute(VALUE, dataType);
- dataCriteriaElem.appendChild(titleElem);
- if(StringUtils.isNotEmpty(statusValue)) {
- Element statusCodeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement("statusCode");
- statusCodeElem.setAttribute(CODE, statusValue);
- dataCriteriaElem.appendChild(statusCodeElem);
- }
-
- // Add value tag in entry element.
- String addValueSetElement = templateNode.getAttributes().getNamedItem("addValueTag").getNodeValue();
- if ("true".equalsIgnoreCase(addValueSetElement)) {
- Element valueElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(VALUE);
-
- Node valueTypeAttr = templateNode.getAttributes().getNamedItem("valueType");
- if (valueTypeAttr != null) {
- valueElem.setAttribute(XSI_TYPE, valueTypeAttr.getNodeValue());
- }
-
- Node valueCodeSystem = templateNode.getAttributes().getNamedItem("valueCodeSystem");
- Node valueCode = templateNode.getAttributes().getNamedItem("valueCode");
- Node valueCodeSystemName = templateNode.getAttributes().getNamedItem("valueCodeSystemName");
-
- if (valueCode != null && valueCodeSystem != null) {
- valueElem.setAttribute("code", valueCode.getNodeValue());
- valueElem.setAttribute("codeSystem", valueCodeSystem.getNodeValue());
- if (valueCodeSystemName != null) {
- valueElem.setAttribute("codeSystemName", valueCodeSystemName.getNodeValue());
- }
- } else {
- String codeSystemOID = qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
- String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
- String codeSystemVersion = qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
- valueElem.setAttribute("code", codeOID);
- valueElem.setAttribute("codeSystem", codeSystemOID);
- valueElem.setAttribute("codeSystemName", codeSystemName);
-
- setCodeSystemVersion(qdmNode, valueElem, codeSystemVersion);
- }
-
- dataCriteriaElem.appendChild(valueElem);
- }
- if (templateNode.getAttributes().getNamedItem("includeSubTemplate") != null) {
- appendSubTemplateNode(templateNode, dataCriteriaXMLProcessor, templateXMLProcessor, dataCriteriaElem,
- qdmNode);
- }
-
- dataCriteriaSectionElem.appendChild(entryElem);
- }
-
-
- private void setCodeSystemVersion(Node qdmNode, Element valueElem, String codeSystemVersion) {
- Node isCodeSystemVersionIncludedNode = qdmNode.getAttributes().getNamedItem("isCodeSystemVersionIncluded");
- boolean isCodeSystemVersionIncluded = true;
- if(isCodeSystemVersionIncludedNode != null) {
- isCodeSystemVersionIncluded = Boolean.parseBoolean(isCodeSystemVersionIncludedNode.getNodeValue());
- }
- if(isCodeSystemVersionIncluded) {
- valueElem.setAttribute("codeSystemVersion", codeSystemVersion);
- }
- }
-
- /**
- * Add Code Element To data Criteria Element based on condition.
- *
- * @param templateNode
- * - Node
- * @param dataCriteriaXMLProcessor
- * - XmlProcessor
- * @param qdmNode
- * the qdm node
- * @param dataCriteriaElem
- * - Element
- */
- private void addCodeElementToDataCriteriaElement(Node templateNode, XmlProcessor dataCriteriaXMLProcessor,
- Node qdmNode, Element dataCriteriaElem) {
- String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
-
-
- // Patient Characteristic data type - contains code tag with valueSetId
- // attribute and no title and value set tag.
- boolean isPatientChar = templateNode.getAttributes().getNamedItem("valueSetId") != null;
- boolean isAddValueSetInCodeTrue = templateNode.getAttributes().getNamedItem("addValueSetInCode") != null;
- boolean isIntervention = "Intervention, Order".equalsIgnoreCase(dataType)
- || "Intervention, Performed".equalsIgnoreCase(dataType)
- || "Intervention, Recommended".equalsIgnoreCase(dataType)
- || "Intervention, Not Ordered".equalsIgnoreCase(dataType)
- || "Intervention, Not Performed".equalsIgnoreCase(dataType)
- || "Intervention, Not Recommended".equalsIgnoreCase(dataType);
- if (isAddValueSetInCodeTrue) {
- Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
- Node valueTypeAttr = templateNode.getAttributes().getNamedItem("valueType");
- if (valueTypeAttr != null) {
- codeElem.setAttribute(XSI_TYPE, valueTypeAttr.getNodeValue());
- }
- String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
- String codeSystemOID = qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
- String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
- String codeSystemVersion = qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
-
- codeElem.setAttribute("code", codeOID);
- codeElem.setAttribute("codeSystem", codeSystemOID);
- codeElem.setAttribute("codeSystemName", codeSystemName);
- setCodeSystemVersion(qdmNode, codeElem, codeSystemVersion);
-
- dataCriteriaElem.appendChild(codeElem);
-
- } else if (isPatientChar) {
- Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
-
- String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
- String codeSystemOID = qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
- String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
- String codeSystemVersion = qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
-
- codeElem.setAttribute("code", codeOID);
- codeElem.setAttribute("codeSystem", codeSystemOID);
- codeElem.setAttribute("codeSystemName", codeSystemName);
- setCodeSystemVersion(qdmNode, codeElem, codeSystemVersion);
- dataCriteriaElem.appendChild(codeElem);
- } else if (isIntervention) {
- Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
- String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
- String codeSystemOID = qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
- String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
- String codeSystemVersion = qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
-
- codeElem.setAttribute("code", codeOID);
- codeElem.setAttribute("codeSystem", codeSystemOID);
- codeElem.setAttribute("codeSystemName", codeSystemName);
- setCodeSystemVersion(qdmNode, codeElem, codeSystemVersion);
- dataCriteriaElem.appendChild(codeElem);
- } else {
- Element codeElement = createCodeForDatatype(templateNode, dataCriteriaXMLProcessor);
- if (codeElement != null) {
- dataCriteriaElem.appendChild(codeElement);
- }
- }
- }
-
-
- /**
- * Add SubTemplate defined in Template.xml to data criteria Element.
- *
- * @param templateNode
- * - Node
- * @param dataCriteriaXMLProcessor
- * - XmlProcessor for Data Criteria
- * @param templateXMLProcessor
- * -XmlProcessor for Template Xml.
- * @param dataCriteriaElem
- * - Element
- * @param qdmNode
- * the qdm node
- * @throws XPathExpressionException
- * the x path expression exception
- */
- private void appendSubTemplateNode(Node templateNode, XmlProcessor dataCriteriaXMLProcessor,
- XmlProcessor templateXMLProcessor, Element dataCriteriaElem, Node qdmNode) throws XPathExpressionException {
- String subTemplateName = templateNode.getAttributes().getNamedItem("includeSubTemplate").getNodeValue();
- Node subTemplateNode = templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(),
- "/templates/subtemplates/" + subTemplateName);
- String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
- String qdmNameDataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
- String qdmTaxonomy = qdmNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
- NodeList subTemplateNodeChilds = templateXMLProcessor.findNodeList(templateXMLProcessor.getOriginalDoc(), "/templates/subtemplates/"
- + subTemplateName + "/child::node()");
-
- if (subTemplateNode.getAttributes().getNamedItem("changeAttribute") != null) {
- String[] attributeToBeModified = subTemplateNode.getAttributes().getNamedItem("changeAttribute")
- .getNodeValue().split(",");
-
-
-
- for (String changeAttribute : attributeToBeModified) {
- NodeList attributedToBeChangedInNode;
- attributedToBeChangedInNode = templateXMLProcessor.findNodeList(templateXMLProcessor.getOriginalDoc(),
- "/templates/subtemplates/" + subTemplateName + "//" + changeAttribute);
-
- if (changeAttribute.equalsIgnoreCase(ID)) {
- String rootId = qdmNode.getAttributes().getNamedItem("uuid").getNodeValue();
-
- Node clonedNode = attributedToBeChangedInNode.item(0).cloneNode(true);
- clonedNode.getAttributes().getNamedItem("root").setNodeValue(rootId);
- clonedNode.getAttributes().getNamedItem("extension").setNodeValue(java.util.UUID.randomUUID().toString());
-
- replaceParentNodeWithClonedNode(attributedToBeChangedInNode.item(0), clonedNode);
- } else if (changeAttribute.equalsIgnoreCase(CODE)) {
- String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
- String codeSystemOID = qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
- String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
- String codeSystemVersion = qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
- Node isCodeSystemVersionIncludedNode = qdmNode.getAttributes().getNamedItem("isCodeSystemVersionIncluded");
- boolean isCodeSystemVersionIncluded = true;
- if(isCodeSystemVersionIncludedNode != null) {
- isCodeSystemVersionIncluded = Boolean.parseBoolean(isCodeSystemVersionIncludedNode.getNodeValue());
- }
-
- Node clonedNode = attributedToBeChangedInNode.item(0).cloneNode(true);
-
- if (clonedNode.getAttributes()
- .getNamedItem("valueSetVersion") != null) {
- clonedNode.getAttributes().removeNamedItem("valueSetVersion");
- }
-
- if (clonedNode.getAttributes().getNamedItem("valueSet") != null) {
- clonedNode.getAttributes().removeNamedItem("valueSet");
- }
-
- Attr attrNodeCode = clonedNode.getOwnerDocument().createAttribute("code");
- attrNodeCode.setNodeValue(codeOID);
- clonedNode.getAttributes().setNamedItem(attrNodeCode);
-
- Attr attrNodeCodeSystem = clonedNode.getOwnerDocument().createAttribute("codeSystem");
- attrNodeCodeSystem.setNodeValue(codeSystemOID);
- clonedNode.getAttributes().setNamedItem(attrNodeCodeSystem);
-
- Attr attrNodeCodeSystemName = clonedNode.getOwnerDocument().createAttribute("codeSystemName");
- attrNodeCodeSystemName.setNodeValue(codeSystemName);
- clonedNode.getAttributes().setNamedItem(attrNodeCodeSystemName);
-
- if(isCodeSystemVersionIncluded) {
- Attr attrNodeCodeSystemVersion = clonedNode.getOwnerDocument().createAttribute("codeSystemVersion");
- attrNodeCodeSystemVersion.setNodeValue(codeSystemVersion);
- clonedNode.getAttributes().setNamedItem(attrNodeCodeSystemVersion);
- }
- replaceParentNodeWithClonedNode(attributedToBeChangedInNode.item(0), clonedNode);
- } else if (changeAttribute.equalsIgnoreCase(DISPLAY_NAME)) {
- Node clonedNode = attributedToBeChangedInNode.item(0).cloneNode(true);
- clonedNode.getAttributes().getNamedItem("value").setNodeValue(HQMFDataCriteriaGenerator.removeOccurrenceFromName(qdmName) + " " + qdmTaxonomy + " value set");
- replaceParentNodeWithClonedNode(attributedToBeChangedInNode.item(0), clonedNode);
- } else if (changeAttribute.equalsIgnoreCase(TITLE)) {
- Node clonedNode = attributedToBeChangedInNode.item(0).cloneNode(true);
- clonedNode.getAttributes().getNamedItem("value").setNodeValue(qdmNameDataType);
- replaceParentNodeWithClonedNode(attributedToBeChangedInNode.item(0), clonedNode);
- } else if (changeAttribute.equalsIgnoreCase(ITEM)) {
- for (int count = 0; count < attributedToBeChangedInNode.getLength(); count++) {
- Node itemNode = attributedToBeChangedInNode.item(count);
- Node clonedNode = itemNode.cloneNode(true);
- clonedNode.getAttributes().getNamedItem("extension").setNodeValue(extensionValue);
- replaceParentNodeWithClonedNode(attributedToBeChangedInNode.item(count), clonedNode);
- }
- } else if (changeAttribute.equalsIgnoreCase("value")) {
- String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
- String codeSystemOID = qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
- String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
- String codeSystemVersion = qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
- Node isCodeSystemVersionIncludedNode = qdmNode.getAttributes().getNamedItem("isCodeSystemVersionIncluded");
- boolean isCodeSystemVersionIncluded = true;
- if(isCodeSystemVersionIncludedNode != null) {
- isCodeSystemVersionIncluded = Boolean.parseBoolean(isCodeSystemVersionIncludedNode.getNodeValue());
- }
-
- Attr codeAttribute = attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("code");
- codeAttribute.setNodeValue(codeOID);
- attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(codeAttribute);
-
- Attr codeSystemAttribute = attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("codeSystem");
- codeSystemAttribute.setNodeValue(codeSystemOID);
- attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(codeSystemAttribute);
-
- Attr codeSystemNameAttribute = attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("codeSystemName");
- codeSystemNameAttribute.setNodeValue(codeSystemName);
- attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(codeSystemNameAttribute);
-
- if(isCodeSystemVersionIncluded) {
- Attr codeSystemVersionAttribute = attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("codeSystemVersion");
- codeSystemVersionAttribute.setNodeValue(codeSystemVersion);
- attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(codeSystemVersionAttribute);
- }
- }
- }
- }
- for (int i = 0; i < subTemplateNodeChilds.getLength(); i++) {
- Node childNode = subTemplateNodeChilds.item(i);
- Node nodeToAttach = dataCriteriaXMLProcessor.getOriginalDoc().importNode(childNode, true);
- XmlProcessor.clean(nodeToAttach);
- dataCriteriaElem.appendChild(nodeToAttach);
- }
- }
-
-
- private void replaceParentNodeWithClonedNode(Node toBeChangedNode, Node clonedNode) {
- Node parentNode = toBeChangedNode.getParentNode();
- parentNode.replaceChild(clonedNode, toBeChangedNode);
- }
-
- /**
- * Creates the code for datatype.
- *
- * @param templateNode
- * the template node
- * @param dataCriteriaXMLProcessor
- * the data criteria xml processor
- * @return the element
- */
- protected Element createCodeForDatatype(Node templateNode, XmlProcessor dataCriteriaXMLProcessor) {
- Node codeAttr = templateNode.getAttributes().getNamedItem(CODE);
- Node codeSystemAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM);
- Node codeSystemNameAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM_NAME);
- Node codeDisplayNameAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM_DISPLAY_NAME);
- Element codeElement = null;
- if (codeAttr != null || codeSystemAttr != null || codeSystemNameAttr != null
- || codeDisplayNameAttr != null) {
- codeElement = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
- if (codeAttr != null) {
- codeElement.setAttribute(CODE, codeAttr.getNodeValue());
- }
- if (codeSystemAttr != null) {
- codeElement.setAttribute(CODE_SYSTEM, codeSystemAttr.getNodeValue());
- }
- if (codeSystemNameAttr != null) {
- codeElement.setAttribute(CODE_SYSTEM_NAME, codeSystemNameAttr.getNodeValue());
- }
- if (codeDisplayNameAttr != null) {
- Element displayNameElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
- displayNameElem.setAttribute(VALUE, codeDisplayNameAttr.getNodeValue());
- codeElement.appendChild(displayNameElem);
- }
- }
- return codeElement;
- }
-
+ protected String extensionValue = null;
+
+ /**
+ * Generate hqm for measure.
+ *
+ * @param me the me
+ * @return the string
+ */
+ @Override
+ public String generate(MeasureExport me) {
+ // This was previously determined by MAT version number, now directly using constant
+ extensionValue = VERSION_5_0_ID;
+ XmlProcessor dataCriteriaXMLProcessor = me.getHqmfXmlProcessor();
+
+ createDataCriteriaForQDMELements(dataCriteriaXMLProcessor, me.getSimpleXmlProcessor());
+ return dataCriteriaXMLProcessor.transform(dataCriteriaXMLProcessor.getOriginalDoc(), true);
+ }
+
+ /**
+ * Creates the data criteria for qdm elements.
+ *
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ */
+ private void createDataCriteriaForQDMELements(
+ XmlProcessor dataCriteriaXMLProcessor, XmlProcessor simpleXmlprocessor) {
+
+ String xPathForDirectReferenceCodes = "/measure/elementLookUp/qdm[@datatype and @code ='true']";
+
+ try {
+ NodeList directReferenceCodeNodeList =
+ simpleXmlprocessor.findNodeList(
+ simpleXmlprocessor.getOriginalDoc(), xPathForDirectReferenceCodes);
+ generateCQLDRCNodeEntries(
+ dataCriteriaXMLProcessor, simpleXmlprocessor, directReferenceCodeNodeList);
+
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void generateCQLDRCNodeEntries(
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor simpleXmlprocessor,
+ NodeList qdmNoAttributeNodeList)
+ throws XPathExpressionException {
+
+ if (qdmNoAttributeNodeList == null) {
+ return;
+ }
+
+ for (int i = 0; i < qdmNoAttributeNodeList.getLength(); i++) {
+ Node qdmNode = qdmNoAttributeNodeList.item(i);
+ createXmlForDataCriteria(qdmNode, dataCriteriaXMLProcessor, simpleXmlprocessor);
+ }
+ }
+
+ /**
+ * Create xml for data criteria.
+ *
+ * @param qdmNode the qdm node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param simpleXmlprocessor the simple xmlprocessor
+ */
+ private void createXmlForDataCriteria(
+ Node qdmNode, XmlProcessor dataCriteriaXMLProcessor, XmlProcessor simpleXmlprocessor) {
+ String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+
+ XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(5.6);
+ String xPathForTemplate = "/templates/template[text()='" + dataType.toLowerCase() + "']";
+ String actNodeStr = "";
+ try {
+
+ Node templateNode =
+ templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xPathForTemplate);
+ if (templateNode != null) {
+ String attrClass = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
+ String xpathForAct = "/templates/acts/act[@a_id='" + attrClass + "']";
+ Node actNode =
+ templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xpathForAct);
+ if (actNode != null) {
+ actNodeStr = actNode.getTextContent();
+ }
+
+ createDataCriteriaElementTag(
+ actNodeStr, templateNode, qdmNode, dataCriteriaXMLProcessor, templateXMLProcessor);
+ }
+
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Gets the creates the data create element tag.
+ *
+ * @param actNodeStr the act node str
+ * @param templateNode the template node
+ * @param qdmNode the qdm node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @param templateXMLProcessor - templateXmlProcessor
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void createDataCriteriaElementTag(
+ String actNodeStr,
+ Node templateNode,
+ Node qdmNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor templateXMLProcessor)
+ throws XPathExpressionException {
+ String oidValue = templateNode.getAttributes().getNamedItem(OID).getNodeValue();
+ String classCodeValue = templateNode.getAttributes().getNamedItem(CLASS).getNodeValue();
+ String moodValue = templateNode.getAttributes().getNamedItem(MOOD).getNodeValue();
+ Node statusNode = templateNode.getAttributes().getNamedItem("status");
+ String statusValue = statusNode != null ? statusNode.getNodeValue() : "";
+ String rootValue = qdmNode.getAttributes().getNamedItem(ID).getNodeValue();
+ String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+
+ Node actionNegInd = templateNode.getAttributes().getNamedItem("actionNegationInd");
+ String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
+ // Stan wants to generate unique id ( extension and root combination
+ // which is different from Value set).
+ String qdmLocalVariableName = codeOID + "_" + dataType;
+
+ qdmLocalVariableName = StringUtils.deleteWhitespace(qdmLocalVariableName);
+
+ Element dataCriteriaSectionElem =
+ (Element)
+ dataCriteriaXMLProcessor
+ .getOriginalDoc()
+ .getElementsByTagName("dataCriteriaSection")
+ .item(0);
+ Element componentElem =
+ (Element)
+ dataCriteriaXMLProcessor.getOriginalDoc().getElementsByTagName("component").item(0);
+ Attr nameSpaceAttr = dataCriteriaXMLProcessor.getOriginalDoc().createAttribute("xmlns:xsi");
+ nameSpaceAttr.setNodeValue(nameSpace);
+ componentElem.setAttributeNodeNS(nameSpaceAttr);
+ // xmlns:qdm="urn:hhs-qdm:hqmf-r2-extensions:v1"
+ Attr qdmNameSpaceAttr =
+ dataCriteriaXMLProcessor.getOriginalDoc().createAttribute("xmlns:cql-ext");
+ qdmNameSpaceAttr.setNodeValue("urn:hhs-cql:hqmf-n1-extensions:v1");
+ componentElem.setAttributeNodeNS(qdmNameSpaceAttr);
+ // creating Entry Tag
+ Element entryElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement("entry");
+ entryElem.setAttribute(TYPE_CODE, "DRIV");
+
+ Element dataCriteriaElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(actNodeStr);
+ entryElem.appendChild(dataCriteriaElem);
+ dataCriteriaElem.setAttribute(CLASS_CODE, classCodeValue);
+ dataCriteriaElem.setAttribute(MOOD_CODE, moodValue);
+ // adding actionNegationInd for Negative Datatypes
+ if (actionNegInd != null) {
+ dataCriteriaElem.setAttribute(ACTION_NEGATION_IND, actionNegInd.getNodeValue());
+ }
+ Element templateId = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
+ dataCriteriaElem.appendChild(templateId);
+ Element itemChild = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ITEM);
+ itemChild.setAttribute(ROOT, oidValue);
+ if (templateNode.getAttributes().getNamedItem("specificExtensionValue") != null) {
+ String specificExtensionValue =
+ templateNode.getAttributes().getNamedItem("specificExtensionValue").getNodeValue();
+ itemChild.setAttribute("extension", specificExtensionValue);
+ } else if (templateNode.getAttributes().getNamedItem("addExtensionInTemplate") == null) {
+ itemChild.setAttribute("extension", extensionValue);
+ }
+ templateId.appendChild(itemChild);
+ Element idElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(ID);
+ idElem.setAttribute(ROOT, rootValue);
+ idElem.setAttribute("extension", qdmLocalVariableName);
+ dataCriteriaElem.appendChild(idElem);
+
+ // boolean appendEntryElem = false;
+
+ String isAddCodeTag = templateNode.getAttributes().getNamedItem("addCodeTag").getNodeValue();
+ if ("true".equalsIgnoreCase(isAddCodeTag)) { // Add Code Element to
+ // DataCriteria Element.
+ addCodeElementToDataCriteriaElement(
+ templateNode, dataCriteriaXMLProcessor, qdmNode, dataCriteriaElem);
+ }
+ Element titleElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(TITLE);
+ titleElem.setAttribute(VALUE, dataType);
+ dataCriteriaElem.appendChild(titleElem);
+ if (StringUtils.isNotEmpty(statusValue)) {
+ Element statusCodeElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement("statusCode");
+ statusCodeElem.setAttribute(CODE, statusValue);
+ dataCriteriaElem.appendChild(statusCodeElem);
+ }
+
+ // Add value tag in entry element.
+ String addValueSetElement =
+ templateNode.getAttributes().getNamedItem("addValueTag").getNodeValue();
+ if ("true".equalsIgnoreCase(addValueSetElement)) {
+ Element valueElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(VALUE);
+
+ Node valueTypeAttr = templateNode.getAttributes().getNamedItem("valueType");
+ if (valueTypeAttr != null) {
+ valueElem.setAttribute(XSI_TYPE, valueTypeAttr.getNodeValue());
+ }
+
+ Node valueCodeSystem = templateNode.getAttributes().getNamedItem("valueCodeSystem");
+ Node valueCode = templateNode.getAttributes().getNamedItem("valueCode");
+ Node valueCodeSystemName = templateNode.getAttributes().getNamedItem("valueCodeSystemName");
+
+ if (valueCode != null && valueCodeSystem != null) {
+ valueElem.setAttribute("code", valueCode.getNodeValue());
+ valueElem.setAttribute("codeSystem", valueCodeSystem.getNodeValue());
+ if (valueCodeSystemName != null) {
+ valueElem.setAttribute("codeSystemName", valueCodeSystemName.getNodeValue());
+ }
+ } else {
+ String codeSystemOID = qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
+ String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
+ String codeSystemVersion =
+ qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
+ valueElem.setAttribute("code", codeOID);
+ valueElem.setAttribute("codeSystem", codeSystemOID);
+ valueElem.setAttribute("codeSystemName", codeSystemName);
+
+ setCodeSystemVersion(qdmNode, valueElem, codeSystemVersion);
+ }
+
+ dataCriteriaElem.appendChild(valueElem);
+ }
+ if (templateNode.getAttributes().getNamedItem("includeSubTemplate") != null) {
+ appendSubTemplateNode(
+ templateNode, dataCriteriaXMLProcessor, templateXMLProcessor, dataCriteriaElem, qdmNode);
+ }
+
+ dataCriteriaSectionElem.appendChild(entryElem);
+ }
+
+ private void setCodeSystemVersion(Node qdmNode, Element valueElem, String codeSystemVersion) {
+ Node isCodeSystemVersionIncludedNode =
+ qdmNode.getAttributes().getNamedItem("isCodeSystemVersionIncluded");
+ boolean isCodeSystemVersionIncluded = true;
+ if (isCodeSystemVersionIncludedNode != null) {
+ isCodeSystemVersionIncluded =
+ Boolean.parseBoolean(isCodeSystemVersionIncludedNode.getNodeValue());
+ }
+ if (isCodeSystemVersionIncluded) {
+ valueElem.setAttribute("codeSystemVersion", codeSystemVersion);
+ }
+ }
+
+ /**
+ * Add Code Element To data Criteria Element based on condition.
+ *
+ * @param templateNode - Node
+ * @param dataCriteriaXMLProcessor - XmlProcessor
+ * @param qdmNode the qdm node
+ * @param dataCriteriaElem - Element
+ */
+ private void addCodeElementToDataCriteriaElement(
+ Node templateNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ Node qdmNode,
+ Element dataCriteriaElem) {
+ String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+
+ // Patient Characteristic data type - contains code tag with valueSetId
+ // attribute and no title and value set tag.
+ boolean isPatientChar = templateNode.getAttributes().getNamedItem("valueSetId") != null;
+ boolean isAddValueSetInCodeTrue =
+ templateNode.getAttributes().getNamedItem("addValueSetInCode") != null;
+ boolean isIntervention =
+ "Intervention, Order".equalsIgnoreCase(dataType)
+ || "Intervention, Performed".equalsIgnoreCase(dataType)
+ || "Intervention, Recommended".equalsIgnoreCase(dataType)
+ || "Intervention, Not Ordered".equalsIgnoreCase(dataType)
+ || "Intervention, Not Performed".equalsIgnoreCase(dataType)
+ || "Intervention, Not Recommended".equalsIgnoreCase(dataType);
+ if (isAddValueSetInCodeTrue) {
+ Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ Node valueTypeAttr = templateNode.getAttributes().getNamedItem("valueType");
+ if (valueTypeAttr != null) {
+ codeElem.setAttribute(XSI_TYPE, valueTypeAttr.getNodeValue());
+ }
+ String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
+ String codeSystemOID = qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
+ String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
+ String codeSystemVersion =
+ qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
+
+ codeElem.setAttribute("code", codeOID);
+ codeElem.setAttribute("codeSystem", codeSystemOID);
+ codeElem.setAttribute("codeSystemName", codeSystemName);
+ setCodeSystemVersion(qdmNode, codeElem, codeSystemVersion);
+
+ dataCriteriaElem.appendChild(codeElem);
+
+ } else if (isPatientChar) {
+ Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+
+ String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
+ String codeSystemOID = qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
+ String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
+ String codeSystemVersion =
+ qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
+
+ codeElem.setAttribute("code", codeOID);
+ codeElem.setAttribute("codeSystem", codeSystemOID);
+ codeElem.setAttribute("codeSystemName", codeSystemName);
+ setCodeSystemVersion(qdmNode, codeElem, codeSystemVersion);
+ dataCriteriaElem.appendChild(codeElem);
+ } else if (isIntervention) {
+ Element codeElem = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
+ String codeSystemOID = qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
+ String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
+ String codeSystemVersion =
+ qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
+
+ codeElem.setAttribute("code", codeOID);
+ codeElem.setAttribute("codeSystem", codeSystemOID);
+ codeElem.setAttribute("codeSystemName", codeSystemName);
+ setCodeSystemVersion(qdmNode, codeElem, codeSystemVersion);
+ dataCriteriaElem.appendChild(codeElem);
+ } else {
+ Element codeElement = createCodeForDatatype(templateNode, dataCriteriaXMLProcessor);
+ if (codeElement != null) {
+ dataCriteriaElem.appendChild(codeElement);
+ }
+ }
+ }
+
+ /**
+ * Add SubTemplate defined in Template.xml to data criteria Element.
+ *
+ * @param templateNode - Node
+ * @param dataCriteriaXMLProcessor - XmlProcessor for Data Criteria
+ * @param templateXMLProcessor -XmlProcessor for Template Xml.
+ * @param dataCriteriaElem - Element
+ * @param qdmNode the qdm node
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void appendSubTemplateNode(
+ Node templateNode,
+ XmlProcessor dataCriteriaXMLProcessor,
+ XmlProcessor templateXMLProcessor,
+ Element dataCriteriaElem,
+ Node qdmNode)
+ throws XPathExpressionException {
+ String subTemplateName =
+ templateNode.getAttributes().getNamedItem("includeSubTemplate").getNodeValue();
+ Node subTemplateNode =
+ templateXMLProcessor.findNode(
+ templateXMLProcessor.getOriginalDoc(), "/templates/subtemplates/" + subTemplateName);
+ String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ String qdmNameDataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String qdmTaxonomy = qdmNode.getAttributes().getNamedItem(TAXONOMY).getNodeValue();
+ NodeList subTemplateNodeChilds =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "/child::node()");
+
+ if (subTemplateNode.getAttributes().getNamedItem("changeAttribute") != null) {
+ String[] attributeToBeModified =
+ subTemplateNode.getAttributes().getNamedItem("changeAttribute").getNodeValue().split(",");
+
+ for (String changeAttribute : attributeToBeModified) {
+ NodeList attributedToBeChangedInNode;
+ attributedToBeChangedInNode =
+ templateXMLProcessor.findNodeList(
+ templateXMLProcessor.getOriginalDoc(),
+ "/templates/subtemplates/" + subTemplateName + "//" + changeAttribute);
+
+ if (changeAttribute.equalsIgnoreCase(ID)) {
+ String rootId = qdmNode.getAttributes().getNamedItem("uuid").getNodeValue();
+
+ Node clonedNode = attributedToBeChangedInNode.item(0).cloneNode(true);
+ clonedNode.getAttributes().getNamedItem("root").setNodeValue(rootId);
+ clonedNode
+ .getAttributes()
+ .getNamedItem("extension")
+ .setNodeValue(java.util.UUID.randomUUID().toString());
+
+ replaceParentNodeWithClonedNode(attributedToBeChangedInNode.item(0), clonedNode);
+ } else if (changeAttribute.equalsIgnoreCase(CODE)) {
+ String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
+ String codeSystemOID =
+ qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
+ String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
+ String codeSystemVersion =
+ qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
+ Node isCodeSystemVersionIncludedNode =
+ qdmNode.getAttributes().getNamedItem("isCodeSystemVersionIncluded");
+ boolean isCodeSystemVersionIncluded = true;
+ if (isCodeSystemVersionIncludedNode != null) {
+ isCodeSystemVersionIncluded =
+ Boolean.parseBoolean(isCodeSystemVersionIncludedNode.getNodeValue());
+ }
+
+ Node clonedNode = attributedToBeChangedInNode.item(0).cloneNode(true);
+
+ if (clonedNode.getAttributes().getNamedItem("valueSetVersion") != null) {
+ clonedNode.getAttributes().removeNamedItem("valueSetVersion");
+ }
+
+ if (clonedNode.getAttributes().getNamedItem("valueSet") != null) {
+ clonedNode.getAttributes().removeNamedItem("valueSet");
+ }
+
+ Attr attrNodeCode = clonedNode.getOwnerDocument().createAttribute("code");
+ attrNodeCode.setNodeValue(codeOID);
+ clonedNode.getAttributes().setNamedItem(attrNodeCode);
+
+ Attr attrNodeCodeSystem = clonedNode.getOwnerDocument().createAttribute("codeSystem");
+ attrNodeCodeSystem.setNodeValue(codeSystemOID);
+ clonedNode.getAttributes().setNamedItem(attrNodeCodeSystem);
+
+ Attr attrNodeCodeSystemName =
+ clonedNode.getOwnerDocument().createAttribute("codeSystemName");
+ attrNodeCodeSystemName.setNodeValue(codeSystemName);
+ clonedNode.getAttributes().setNamedItem(attrNodeCodeSystemName);
+
+ if (isCodeSystemVersionIncluded) {
+ Attr attrNodeCodeSystemVersion =
+ clonedNode.getOwnerDocument().createAttribute("codeSystemVersion");
+ attrNodeCodeSystemVersion.setNodeValue(codeSystemVersion);
+ clonedNode.getAttributes().setNamedItem(attrNodeCodeSystemVersion);
+ }
+ replaceParentNodeWithClonedNode(attributedToBeChangedInNode.item(0), clonedNode);
+ } else if (changeAttribute.equalsIgnoreCase(DISPLAY_NAME)) {
+ Node clonedNode = attributedToBeChangedInNode.item(0).cloneNode(true);
+ clonedNode
+ .getAttributes()
+ .getNamedItem("value")
+ .setNodeValue(
+ HQMFDataCriteriaGenerator.removeOccurrenceFromName(qdmName)
+ + " "
+ + qdmTaxonomy
+ + " value set");
+ replaceParentNodeWithClonedNode(attributedToBeChangedInNode.item(0), clonedNode);
+ } else if (changeAttribute.equalsIgnoreCase(TITLE)) {
+ Node clonedNode = attributedToBeChangedInNode.item(0).cloneNode(true);
+ clonedNode.getAttributes().getNamedItem("value").setNodeValue(qdmNameDataType);
+ replaceParentNodeWithClonedNode(attributedToBeChangedInNode.item(0), clonedNode);
+ } else if (changeAttribute.equalsIgnoreCase(ITEM)) {
+ for (int count = 0; count < attributedToBeChangedInNode.getLength(); count++) {
+ Node itemNode = attributedToBeChangedInNode.item(count);
+ Node clonedNode = itemNode.cloneNode(true);
+ clonedNode.getAttributes().getNamedItem("extension").setNodeValue(extensionValue);
+ replaceParentNodeWithClonedNode(attributedToBeChangedInNode.item(count), clonedNode);
+ }
+ } else if (changeAttribute.equalsIgnoreCase("value")) {
+ String codeOID = qdmNode.getAttributes().getNamedItem("oid").getNodeValue();
+ String codeSystemOID =
+ qdmNode.getAttributes().getNamedItem("codeSystemOID").getNodeValue();
+ String codeSystemName = qdmNode.getAttributes().getNamedItem("taxonomy").getNodeValue();
+ String codeSystemVersion =
+ qdmNode.getAttributes().getNamedItem("codeSystemVersion").getNodeValue();
+ Node isCodeSystemVersionIncludedNode =
+ qdmNode.getAttributes().getNamedItem("isCodeSystemVersionIncluded");
+ boolean isCodeSystemVersionIncluded = true;
+ if (isCodeSystemVersionIncludedNode != null) {
+ isCodeSystemVersionIncluded =
+ Boolean.parseBoolean(isCodeSystemVersionIncludedNode.getNodeValue());
+ }
+
+ Attr codeAttribute =
+ attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("code");
+ codeAttribute.setNodeValue(codeOID);
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(codeAttribute);
+
+ Attr codeSystemAttribute =
+ attributedToBeChangedInNode.item(0).getOwnerDocument().createAttribute("codeSystem");
+ codeSystemAttribute.setNodeValue(codeSystemOID);
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(codeSystemAttribute);
+
+ Attr codeSystemNameAttribute =
+ attributedToBeChangedInNode
+ .item(0)
+ .getOwnerDocument()
+ .createAttribute("codeSystemName");
+ codeSystemNameAttribute.setNodeValue(codeSystemName);
+ attributedToBeChangedInNode.item(0).getAttributes().setNamedItem(codeSystemNameAttribute);
+
+ if (isCodeSystemVersionIncluded) {
+ Attr codeSystemVersionAttribute =
+ attributedToBeChangedInNode
+ .item(0)
+ .getOwnerDocument()
+ .createAttribute("codeSystemVersion");
+ codeSystemVersionAttribute.setNodeValue(codeSystemVersion);
+ attributedToBeChangedInNode
+ .item(0)
+ .getAttributes()
+ .setNamedItem(codeSystemVersionAttribute);
+ }
+ }
+ }
+ }
+ for (int i = 0; i < subTemplateNodeChilds.getLength(); i++) {
+ Node childNode = subTemplateNodeChilds.item(i);
+ Node nodeToAttach = dataCriteriaXMLProcessor.getOriginalDoc().importNode(childNode, true);
+ XmlProcessor.clean(nodeToAttach);
+ dataCriteriaElem.appendChild(nodeToAttach);
+ }
+ }
+
+ private void replaceParentNodeWithClonedNode(Node toBeChangedNode, Node clonedNode) {
+ Node parentNode = toBeChangedNode.getParentNode();
+ parentNode.replaceChild(clonedNode, toBeChangedNode);
+ }
+
+ /**
+ * Creates the code for datatype.
+ *
+ * @param templateNode the template node
+ * @param dataCriteriaXMLProcessor the data criteria xml processor
+ * @return the element
+ */
+ protected Element createCodeForDatatype(
+ Node templateNode, XmlProcessor dataCriteriaXMLProcessor) {
+ Node codeAttr = templateNode.getAttributes().getNamedItem(CODE);
+ Node codeSystemAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM);
+ Node codeSystemNameAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM_NAME);
+ Node codeDisplayNameAttr = templateNode.getAttributes().getNamedItem(CODE_SYSTEM_DISPLAY_NAME);
+ Element codeElement = null;
+ if (codeAttr != null
+ || codeSystemAttr != null
+ || codeSystemNameAttr != null
+ || codeDisplayNameAttr != null) {
+ codeElement = dataCriteriaXMLProcessor.getOriginalDoc().createElement(CODE);
+ if (codeAttr != null) {
+ codeElement.setAttribute(CODE, codeAttr.getNodeValue());
+ }
+ if (codeSystemAttr != null) {
+ codeElement.setAttribute(CODE_SYSTEM, codeSystemAttr.getNodeValue());
+ }
+ if (codeSystemNameAttr != null) {
+ codeElement.setAttribute(CODE_SYSTEM_NAME, codeSystemNameAttr.getNodeValue());
+ }
+ if (codeDisplayNameAttr != null) {
+ Element displayNameElem =
+ dataCriteriaXMLProcessor.getOriginalDoc().createElement(DISPLAY_NAME);
+ displayNameElem.setAttribute(VALUE, codeDisplayNameAttr.getNodeValue());
+ codeElement.appendChild(displayNameElem);
+ }
+ }
+ return codeElement;
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaGenerator.java b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaGenerator.java
index ba3106e..9fda873 100644
--- a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaGenerator.java
+++ b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFDataCriteriaGenerator.java
@@ -5,53 +5,58 @@
import gov.cms.madie.hqmf.dto.MeasureExport;
import org.springframework.stereotype.Service;
-/**
- * The Class HQMFDataCriteriaGenerator.
- */
+/** The Class HQMFDataCriteriaGenerator. */
@Service
public class HQMFDataCriteriaGenerator implements Generator {
-
- /**
- * Generate hqmf for measure.
- *
- * @param me the me
- * @return the string
- * @throws Exception the exception
- */
- @Override
- public String generate(MeasureExport me) throws Exception {
-
- HQMFDataCriteriaElementGenerator cqlBasedHQMFDataCriteriaElementGenerator = new HQMFDataCriteriaElementGenerator();
- cqlBasedHQMFDataCriteriaElementGenerator.generate(me);
-
- HQMFPopulationLogicGenerator cqlBasedHQMFPopulationLogicGenerator = new HQMFPopulationLogicGenerator();
- cqlBasedHQMFPopulationLogicGenerator.generate(me);
-
- HQMFMeasureObservationLogicGenerator cqlBasedHQMFMeasureObservationLogicGenerator = new HQMFMeasureObservationLogicGenerator();
- cqlBasedHQMFMeasureObservationLogicGenerator.generate(me);
-
- XmlProcessor dataCriteriaXMLProcessor = me.getHqmfXmlProcessor();
- return removePreambleAndRootTags(dataCriteriaXMLProcessor.transform(dataCriteriaXMLProcessor.getOriginalDoc(), true));
- }
-
- /**
- * @param xmlString
- * @return
- */
- private String removePreambleAndRootTags(String xmlString) {
- xmlString = xmlString.replaceAll("\\<\\?xml(.+?)\\?\\>", "").trim()
- .replaceAll("(<\\?[^<]*\\?>)?", "");/* remove preamble */
- xmlString = xmlString.replaceAll("", "").replaceAll("","");
- return xmlString;
- }
-
- //Strip out 'Occurrence A_' at the start of qdmName If found.
- public static String removeOccurrenceFromName(String qdmName){
- String regExpression = "Occurrence [A-Z]_.*";
- String newQdmName = qdmName;
- if(newQdmName.matches(regExpression)){
- newQdmName = newQdmName.substring(newQdmName.indexOf('_')+1);
- }
- return newQdmName;
- }
+
+ /**
+ * Generate hqmf for measure.
+ *
+ * @param me the me
+ * @return the string
+ * @throws Exception the exception
+ */
+ @Override
+ public String generate(MeasureExport me) throws Exception {
+
+ HQMFDataCriteriaElementGenerator cqlBasedHQMFDataCriteriaElementGenerator =
+ new HQMFDataCriteriaElementGenerator();
+ cqlBasedHQMFDataCriteriaElementGenerator.generate(me);
+
+ HQMFPopulationLogicGenerator cqlBasedHQMFPopulationLogicGenerator =
+ new HQMFPopulationLogicGenerator();
+ cqlBasedHQMFPopulationLogicGenerator.generate(me);
+
+ HQMFMeasureObservationLogicGenerator cqlBasedHQMFMeasureObservationLogicGenerator =
+ new HQMFMeasureObservationLogicGenerator();
+ cqlBasedHQMFMeasureObservationLogicGenerator.generate(me);
+
+ XmlProcessor dataCriteriaXMLProcessor = me.getHqmfXmlProcessor();
+ return removePreambleAndRootTags(
+ dataCriteriaXMLProcessor.transform(dataCriteriaXMLProcessor.getOriginalDoc(), true));
+ }
+
+ /**
+ * @param xmlString
+ * @return
+ */
+ private String removePreambleAndRootTags(String xmlString) {
+ xmlString =
+ xmlString
+ .replaceAll("\\<\\?xml(.+?)\\?\\>", "")
+ .trim()
+ .replaceAll("(<\\?[^<]*\\?>)?", ""); /* remove preamble */
+ xmlString = xmlString.replaceAll("", "").replaceAll("", "");
+ return xmlString;
+ }
+
+ // Strip out 'Occurrence A_' at the start of qdmName If found.
+ public static String removeOccurrenceFromName(String qdmName) {
+ String regExpression = "Occurrence [A-Z]_.*";
+ String newQdmName = qdmName;
+ if (newQdmName.matches(regExpression)) {
+ newQdmName = newQdmName.substring(newQdmName.indexOf('_') + 1);
+ }
+ return newQdmName;
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFGenerator.java b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFGenerator.java
index 830738a..5422c2a 100644
--- a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFGenerator.java
+++ b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFGenerator.java
@@ -5,7 +5,7 @@
import gov.cms.madie.hqmf.XmlProcessor;
import gov.cms.madie.hqmf.dto.MeasureExport;
import lombok.AllArgsConstructor;
-import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@@ -15,94 +15,94 @@
*
* @author jmeyer
*/
+@Slf4j
@Service
@AllArgsConstructor
-@NoArgsConstructor
public class HQMFGenerator implements Generator {
- private HQMFMeasureDetailsGenerator hqmfMeasureDetailsGenerator;
- private HQMFDataCriteriaGenerator hqmfDataCriteriaGenerator;
-
- private final Logger logger = LoggerFactory.getLogger(HQMFDataCriteriaGenerator.class);
+ private HQMFMeasureDetailsGenerator hqmfMeasureDetailsGenerator;
+ private HQMFDataCriteriaGenerator hqmfDataCriteriaGenerator;
- /**
- * Generate hqmf for CQL Based measures (QDM version 5.5)
- *
- * @param me the me
- * @return the string
- */
- @Override
- public String generate(MeasureExport me) throws Exception {
- try {
- // MAT 6911: Export CQL based HQMF w/ Meta Data Section
- String hqmfXML = hqmfMeasureDetailsGenerator.generate(me);
- // Inline comments are added after the end of last componentOf tag.
- // This is removed in this method
- hqmfXML = replaceInlineCommentFromEnd(hqmfXML);
+ private final Logger logger = LoggerFactory.getLogger(HQMFDataCriteriaGenerator.class);
- String dataCriteriaXML = hqmfDataCriteriaGenerator.generate(me);
- hqmfXML= appendToHQMF(dataCriteriaXML, hqmfXML);
-
- XmlProcessor hqmfProcessor = new XmlProcessor(hqmfXML);
- me.setHqmfXmlProcessor(hqmfProcessor);
-
- //generateNarrative(me);
- return finalCleanUp(me);
- } catch (Exception e) {
- logger.error("Unable to generate HQMF for QDM v5.6. Exception Stack Strace is as followed : ");
- throw e;
- }
- }
+ /**
+ * Generate hqmf for CQL Based measures (QDM version 5.5)
+ *
+ * @param me the me
+ * @return the string
+ */
+ @Override
+ public String generate(MeasureExport me) throws Exception {
+ try {
+ // MAT 6911: Export CQL based HQMF w/ Meta Data Section
+ String hqmfXML = hqmfMeasureDetailsGenerator.generate(me);
+ // Inline comments are added after the end of last componentOf tag.
+ // This is removed in this method
+ hqmfXML = replaceInlineCommentFromEnd(hqmfXML);
- /**
- * Inline comments are added after the end of last componentOf tag. This is
- * removed in this method
- *
- * @param eMeasureDetailsXML
- * - String eMeasureDetailsXML.
- * @return String eMeasureDetailsXML.
- */
- private String replaceInlineCommentFromEnd(String eMeasureDetailsXML) {
- int indexOfComponentOf = eMeasureDetailsXML.lastIndexOf("");
- eMeasureDetailsXML = eMeasureDetailsXML.substring(0, indexOfComponentOf);
- eMeasureDetailsXML = eMeasureDetailsXML.concat("");
- return eMeasureDetailsXML;
- }
-
- /**
- * Append to hqmf.
- *
- * @param dataCriteriaXML the data criteria xml
- * @param hqmfXML the hqmf xml
- * @return the string
- */
- private String appendToHQMF(String dataCriteriaXML, String hqmfXML) {
- int indexOfEnd = hqmfXML.indexOf("");
- if(indexOfEnd > -1){
- hqmfXML = hqmfXML.substring(0, indexOfEnd) + dataCriteriaXML + hqmfXML.substring(indexOfEnd);
- }
- return hqmfXML;
- }
-
- /**
- * Final clean up.
- *
- * @param me the me
- * @return the string
- */
- private String finalCleanUp(MeasureExport me) {
- HQMFFinalCleanUp.clean(me);
- return removeXmlTagNamespace(me.getHqmfXmlProcessor().transform(me.getHqmfXmlProcessor().getOriginalDoc(), true));
- }
-
- /**
- * Removes the xml tag namespace.
- *
- * @param xmlString the xml string
- * @return the string
- */
- private String removeXmlTagNamespace(String xmlString) {
- xmlString = xmlString.replaceAll(" xmlns=\"\"", "").replaceAll(""", """);
- return xmlString;
- }
+ String dataCriteriaXML = hqmfDataCriteriaGenerator.generate(me);
+ hqmfXML = appendToHQMF(dataCriteriaXML, hqmfXML);
+
+ XmlProcessor hqmfProcessor = new XmlProcessor(hqmfXML);
+ me.setHqmfXmlProcessor(hqmfProcessor);
+
+ // generateNarrative(me);
+ return finalCleanUp(me);
+ } catch (Exception e) {
+ logger.error(
+ "Unable to generate HQMF for QDM v5.6. Exception Stack Strace is as followed : ");
+ throw e;
+ }
+ }
+
+ /**
+ * Inline comments are added after the end of last componentOf tag. This is removed in this method
+ *
+ * @param eMeasureDetailsXML - String eMeasureDetailsXML.
+ * @return String eMeasureDetailsXML.
+ */
+ private String replaceInlineCommentFromEnd(String eMeasureDetailsXML) {
+ int indexOfComponentOf = eMeasureDetailsXML.lastIndexOf("");
+ eMeasureDetailsXML = eMeasureDetailsXML.substring(0, indexOfComponentOf);
+ eMeasureDetailsXML = eMeasureDetailsXML.concat("");
+ return eMeasureDetailsXML;
+ }
+
+ /**
+ * Append to hqmf.
+ *
+ * @param dataCriteriaXML the data criteria xml
+ * @param hqmfXML the hqmf xml
+ * @return the string
+ */
+ private String appendToHQMF(String dataCriteriaXML, String hqmfXML) {
+ int indexOfEnd = hqmfXML.indexOf("");
+ if (indexOfEnd > -1) {
+ hqmfXML = hqmfXML.substring(0, indexOfEnd) + dataCriteriaXML + hqmfXML.substring(indexOfEnd);
+ }
+ return hqmfXML;
+ }
+
+ /**
+ * Final clean up.
+ *
+ * @param me the me
+ * @return the string
+ */
+ private String finalCleanUp(MeasureExport me) {
+ HQMFFinalCleanUp.clean(me);
+ return removeXmlTagNamespace(
+ me.getHqmfXmlProcessor().transform(me.getHqmfXmlProcessor().getOriginalDoc(), true));
+ }
+
+ /**
+ * Removes the xml tag namespace.
+ *
+ * @param xmlString the xml string
+ * @return the string
+ */
+ private String removeXmlTagNamespace(String xmlString) {
+ xmlString = xmlString.replaceAll(" xmlns=\"\"", "").replaceAll(""", """);
+ return xmlString;
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureDetailsGenerator.java b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureDetailsGenerator.java
index d23dfc8..3a63a49 100644
--- a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureDetailsGenerator.java
+++ b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureDetailsGenerator.java
@@ -1,6 +1,5 @@
package gov.cms.madie.hqmf.qdm_5_6;
-
import gov.cms.madie.hqmf.Generator;
import gov.cms.madie.hqmf.XMLUtility;
import gov.cms.madie.hqmf.XmlProcessor;
@@ -17,127 +16,139 @@
@Slf4j
@Service
public class HQMFMeasureDetailsGenerator implements Generator {
-
- private static final String CONVERSION_FILE_FOR_CQL_BASED_HQMF_HEADER = "xsl/qdm_v5_6_measure_details.xsl";
- @Override
- public String generate(MeasureExport me) {
- String simpleXML = me.getSimpleXml();
- String releaseVersion = me.getReleaseVersion();
+ private static final String CONVERSION_FILE_FOR_CQL_BASED_HQMF_HEADER =
+ "xsl/qdm_v5_6_measure_details.xsl";
+
+ @Override
+ public String generate(MeasureExport me) {
+ String simpleXML = me.getSimpleXml();
+ String releaseVersion = me.getReleaseVersion();
+
+ simpleXML = addReleaseVersionToSimpleXML(simpleXML);
+ String measureDetailsHQMF_XML =
+ XMLUtility.getInstance()
+ .applyXSL(
+ simpleXML,
+ XMLUtility.getInstance().getXMLResource(CONVERSION_FILE_FOR_CQL_BASED_HQMF_HEADER));
+ measureDetailsHQMF_XML = incrementEndDatebyOne(measureDetailsHQMF_XML);
+ return measureDetailsHQMF_XML.replaceAll("xmlns=\"\"", "");
+ }
+
+ private String addReleaseVersionToSimpleXML(String simpleXML) {
+ // if(releaseVersion == null || releaseVersion.trim().length() == 0){
+ // return simpleXML;
+ // }
+
+ // TODO: CREATE CONSTANT Hardcoded to 5.6 for now...probably refactor to accept Measure Export,
+ // measure, and pull QDM model from measure?
+ String releaseVersion = "5.6"; // MATPropertiesService.get().getQdmVersion();
+ int measureDetailsTagIndex = simpleXML.indexOf("");
+ if (measureDetailsTagIndex > -1) {
+ simpleXML =
+ simpleXML.substring(0, measureDetailsTagIndex)
+ + ""
+ + simpleXML.substring(measureDetailsTagIndex);
+ }
+
+ return simpleXML;
+ }
+
+ /**
+ * Increment end date by one.
+ *
+ * @param measureDetailsHQMF_XML the measure details hqm f_ xml
+ * @return the string
+ */
+ private String incrementEndDatebyOne(String measureDetailsHQMF_XML) {
+ XmlProcessor measureDetailsXml = new XmlProcessor(measureDetailsHQMF_XML);
+ String xpathMeasurementPeriodStr =
+ "/QualityMeasureDocument/controlVariable/measurePeriod/value/high";
+ try {
+ Node endDateHigh =
+ measureDetailsXml.findNode(measureDetailsXml.getOriginalDoc(), xpathMeasurementPeriodStr);
+ if (endDateHigh != null) {
+ String highEndDate = endDateHigh.getAttributes().getNamedItem("value").getNodeValue();
+ highEndDate = formatDate(highEndDate);
+ endDateHigh.getAttributes().getNamedItem("value").setNodeValue(highEndDate);
+ }
+ // to edit default startDate in HQMF measureDetails
+ editDefaultStartDate(measureDetailsXml);
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+
+ return measureDetailsXml.transform(measureDetailsXml.getOriginalDoc(), true);
+ }
- simpleXML = addReleaseVersionToSimpleXML(simpleXML);
- String measureDetailsHQMF_XML = XMLUtility.getInstance()
- .applyXSL(simpleXML, XMLUtility.getInstance().getXMLResource(CONVERSION_FILE_FOR_CQL_BASED_HQMF_HEADER));
- measureDetailsHQMF_XML = incrementEndDatebyOne(measureDetailsHQMF_XML);
- return measureDetailsHQMF_XML.replaceAll("xmlns=\"\"", "");
- }
-
- private String addReleaseVersionToSimpleXML(String simpleXML) {
-// if(releaseVersion == null || releaseVersion.trim().length() == 0){
-// return simpleXML;
-// }
+ /**
+ * Edits the default start date.
+ *
+ * @param measureDetailsXml the measure details xml
+ */
+ private void editDefaultStartDate(XmlProcessor measureDetailsXml) {
+ String xpathMeasurementPeriodStr =
+ "/QualityMeasureDocument/controlVariable/measurePeriod/value/phase/low";
+ try {
+ Node measurementPeriodLowNode =
+ measureDetailsXml.findNode(measureDetailsXml.getOriginalDoc(), xpathMeasurementPeriodStr);
+ if (measurementPeriodLowNode != null) {
+ String lowDateValue =
+ measurementPeriodLowNode.getAttributes().getNamedItem("value").getNodeValue();
+ measurementPeriodLowNode
+ .getAttributes()
+ .getNamedItem("value")
+ .setNodeValue(getLowValue(lowDateValue));
+ }
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
- // TODO: CREATE CONSTANT Hardcoded to 5.6 for now...probably refactor to accept Measure Export, measure, and pull QDM model from measure?
- String releaseVersion = "5.6"; // MATPropertiesService.get().getQdmVersion();
- int measureDetailsTagIndex = simpleXML.indexOf("");
- if(measureDetailsTagIndex > -1){
- simpleXML = simpleXML.substring(0, measureDetailsTagIndex) + "" + simpleXML.substring(measureDetailsTagIndex);
- }
-
- return simpleXML;
- }
-
- /**
- * Increment end date by one.
- *
- * @param measureDetailsHQMF_XML the measure details hqm f_ xml
- * @return the string
- */
- private String incrementEndDatebyOne(String measureDetailsHQMF_XML){
- XmlProcessor measureDetailsXml = new XmlProcessor(measureDetailsHQMF_XML);
- String xpathMeasurementPeriodStr = "/QualityMeasureDocument/controlVariable/measurePeriod/value/high";
- try {
- Node endDateHigh = measureDetailsXml.findNode(measureDetailsXml.getOriginalDoc(),
- xpathMeasurementPeriodStr);
- if(endDateHigh!=null){
- String highEndDate = endDateHigh.getAttributes().getNamedItem("value").getNodeValue();
- highEndDate = formatDate(highEndDate);
- endDateHigh.getAttributes().getNamedItem("value").setNodeValue(highEndDate);
- }
- //to edit default startDate in HQMF measureDetails
- editDefaultStartDate(measureDetailsXml);
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
+ /**
+ * Gets the low value.
+ *
+ * @param lowValue the low value
+ * @return the low value
+ */
+ private String getLowValue(String lowValue) {
+ String mm = lowValue.substring(4, 6);
+ String dd = lowValue.substring(6, 8);
+ String year = getCurrentYear();
+ // Low date
+ return year + mm + dd;
+ }
- return measureDetailsXml.transform(measureDetailsXml.getOriginalDoc(), true);
- }
-
- /**
- * Edits the default start date.
- *
- * @param measureDetailsXml the measure details xml
- */
- private void editDefaultStartDate(XmlProcessor measureDetailsXml) {
- String xpathMeasurementPeriodStr = "/QualityMeasureDocument/controlVariable/measurePeriod/value/phase/low";
- try {
- Node measurementPeriodLowNode = measureDetailsXml.findNode(measureDetailsXml.getOriginalDoc(),
- xpathMeasurementPeriodStr);
- if(measurementPeriodLowNode!=null){
- String lowDateValue = measurementPeriodLowNode.getAttributes().
- getNamedItem("value").getNodeValue();
- measurementPeriodLowNode.getAttributes().getNamedItem("value").
- setNodeValue(getLowValue(lowDateValue));
- }
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Gets the low value.
- *
- * @param lowValue the low value
- * @return the low value
- */
- private String getLowValue(String lowValue){
- String mm = lowValue.substring(4,6);
- String dd = lowValue.substring(6,8);
- String year = getCurrentYear();
- // Low date
- return year + mm + dd;
- }
-
- /**
- * Gets the current year.
- *
- * @return the current year
- */
- private String getCurrentYear(){
- Calendar now = Calendar.getInstance();
- int year = now.get(Calendar.YEAR);
- String currentYear = String.valueOf(year);
- return currentYear;
- }
-
-
- /**
- * Format date.
- *
- * @param date the date
- * @return the string
- */
- private String formatDate(String date){
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
- Calendar c = Calendar.getInstance();
- try {
- c.setTime(sdf.parse(date));
- } catch (ParseException e) {
- e.printStackTrace();
- }
- c.add(Calendar.DATE, 1); // to add one to End Date
- date = sdf.format(c.getTime());
- return date;
- }
+ /**
+ * Gets the current year.
+ *
+ * @return the current year
+ */
+ private String getCurrentYear() {
+ Calendar now = Calendar.getInstance();
+ int year = now.get(Calendar.YEAR);
+ String currentYear = String.valueOf(year);
+ return currentYear;
+ }
+ /**
+ * Format date.
+ *
+ * @param date the date
+ * @return the string
+ */
+ private String formatDate(String date) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+ Calendar c = Calendar.getInstance();
+ try {
+ c.setTime(sdf.parse(date));
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ c.add(Calendar.DATE, 1); // to add one to End Date
+ date = sdf.format(c.getTime());
+ return date;
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureObservationLogicGenerator.java b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureObservationLogicGenerator.java
index a147583..acba644 100644
--- a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureObservationLogicGenerator.java
+++ b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureObservationLogicGenerator.java
@@ -1,6 +1,5 @@
package gov.cms.madie.hqmf.qdm_5_6;
-
import gov.cms.madie.hqmf.QDMTemplateProcessorFactory;
import gov.cms.madie.hqmf.UUIDUtilClient;
import gov.cms.madie.hqmf.XmlProcessor;
@@ -22,1028 +21,1144 @@
import java.util.Map;
import java.util.TreeMap;
-/**
- * The Class HQMFPopulationLogicGenerator.
- */
+/** The Class HQMFPopulationLogicGenerator. */
public class HQMFMeasureObservationLogicGenerator extends HQMFClauseLogicGenerator {
- private static final String MEASURE_OBSERVATION_EXTENSION_VALUE = "2018-05-01";
-
- private static final int DATETIMEDIFF_CHILD_COUNT = 2;
-
- private Map clauseLogicMap = new HashMap<>();
-
- private Map measureGroupingMap = new TreeMap<>();
-
- private MeasureExport me;
-
- private String scoringType;
-
- private boolean clauseLogicHasElementRef = false;
-
- /**
- * MAP of Functional Ops AGGREGATE that can be used in Measure Observation.
- */
- private static final Map FUNCTIONAL_OPS_AGGREGATE = new TreeMap<>(
- String.CASE_INSENSITIVE_ORDER);
-
- /**
- * MAP of Functional Ops INCLUDED FUNCTIONS that can be used in Measure
- * Observation.
- */
- private static final Map INCLUDED_FUNCTIONAL_NAMES = new TreeMap<>(
- String.CASE_INSENSITIVE_ORDER);
- static {
- FUNCTIONAL_OPS_AGGREGATE.put("MAX", "MAX");
- FUNCTIONAL_OPS_AGGREGATE.put("MIN", "MIN");
- FUNCTIONAL_OPS_AGGREGATE.put("SUM", "SUM");
- FUNCTIONAL_OPS_AGGREGATE.put("AVG", "AVERAGE");
- FUNCTIONAL_OPS_AGGREGATE.put("COUNT", "COUNT");
- FUNCTIONAL_OPS_AGGREGATE.put("MEDIAN", "MEDIAN");
- FUNCTIONAL_OPS_AGGREGATE.put("DATETIMEDIFF", null);
- INCLUDED_FUNCTIONAL_NAMES.put("FIRST", "FIRST");
- INCLUDED_FUNCTIONAL_NAMES.put("SECOND", "SECOND");
- INCLUDED_FUNCTIONAL_NAMES.put("THIRD", "THIRD");
- INCLUDED_FUNCTIONAL_NAMES.put("FOURTH", "FOURTH");
- INCLUDED_FUNCTIONAL_NAMES.put("FIFTH", "FIFTH");
- INCLUDED_FUNCTIONAL_NAMES.put("MOST RECENT", "MOST RECENT");
- INCLUDED_FUNCTIONAL_NAMES.put("COUNT", "COUNT");
- INCLUDED_FUNCTIONAL_NAMES.put("DATETIMEDIFF", "DATETIMEDIFF");
- }
-
- @Override
- public String generate(MeasureExport me) throws Exception {
- this.me = me;
- setMeasureExport(me);
- getMeasureScoringType(me);
- generateClauseLogicMap(me);
- getAllMeasureGroupings(me);
- generateMeasureObSection(me);
- return null;
- }
-
- /**
- * Get DotNotation from templates.xml.
- *
- * @param attributeName
- * -String
- * @param dataTypeName
- * - String
- * @throws XPathExpressionException
- * -Exception
- * @return String dot notation.
- */
- private String getQdmAttributeMapppingDotNotation(String attributeName, String dataTypeName)
- throws XPathExpressionException {
- XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(5.6);
- String xPath = "/templates/attributeMappings/attributeMapping[@qdmAttribute=\"" + attributeName + "\"]";
- Node attributeMappingNode = templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xPath);
- if (attributeMappingNode == null) {
- xPath = "/templates/attributeMappings/attributeMapping[@qdmAttribute='" + attributeName
- + "' and @datatypes = \"" + dataTypeName.toLowerCase() + "\"]";
- attributeMappingNode = templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xPath);
- }
- if (attributeMappingNode != null) {
- return attributeMappingNode.getAttributes().getNamedItem("dotNotation").getNodeValue();
- } else {
- return null;
- }
- }
-
- /**
- * Method to generate MeasureObservation Criteria Section.
- *
- * @param me
- * - MeasureExport
- * @throws XPathExpressionException
- * - Exception
- */
- private void generateMeasureObSection(MeasureExport me) throws XPathExpressionException {
- String isInGrouping = "";
- for (Integer key : measureGroupingMap.keySet()) {
- NodeList groupingChildList = measureGroupingMap.get(key);
- for (int i = 0; i < groupingChildList.getLength(); i++) {
- Node groupingChildListItem = groupingChildList.item(i);
-
- String popType = groupingChildListItem.getAttributes().getNamedItem(TYPE).getNodeValue();
- if (groupingChildList.item(i).getAttributes().getNamedItem(GROUPING_CHECK) != null) {
- isInGrouping = groupingChildList.item(i).getAttributes().getNamedItem(GROUPING_CHECK)
- .getNodeValue();
- }
- switch (popType) {
- case "measureObservation":
- if (isInGrouping != null && !isInGrouping.isEmpty()) {
- if (isInGrouping.equalsIgnoreCase("true")) {
-
- Node measureObSectionComponentElement = createMeasureObservationSection(
- me.getHqmfXmlProcessor());
-
- generateMeasureObDefinition(groupingChildListItem, measureObSectionComponentElement);
- }
- } else {
- Node measureObSectionComponentElement = createMeasureObservationSection(
- me.getHqmfXmlProcessor());
-
- generateMeasureObDefinition(groupingChildListItem, measureObSectionComponentElement);
- }
- break;
- case "denominator":
- break;
- case "numerator":
- break;
- default:
- // do nothing.
- break;
- }
- }
- }
- }
-
- /**
- * Method to generate default criteriaTag for all population types included in
- * measure grouping.
- *
- * @param measureObsClauseNode
- * - Node
- * @param measureObservationSecElement
- * - Element
- * @throws XPathExpressionException
- * - Exception
- */
- private void generateMeasureObDefinition(Node measureObsClauseNode, Node measureObservationSecElement) {
-
- if (!measureObsClauseNode.hasChildNodes()) {
- return;
- }
-
- Document doc = measureObservationSecElement.getOwnerDocument();
- Comment comment = doc.createComment(
- "Definition for " + measureObsClauseNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
- Element definitionElement = doc.createElement("definition");
- Element measureObDefinitionElement = doc.createElement("measureObservationDefinition");
- measureObDefinitionElement.setAttribute(CLASS_CODE, "OBS");
- measureObDefinitionElement.setAttribute(MOOD_CODE, "DEF");
- Element idElem = doc.createElement(ID);
- idElem.setAttribute(ROOT, measureObsClauseNode.getAttributes().getNamedItem("uuid").getNodeValue());
- idElem.setAttribute(EXTENSION, "MeasureObservation");
- measureObDefinitionElement.appendChild(idElem);
-
- Element codeElem = doc.createElement(CODE);
- codeElem.setAttribute(CODE, "AGGREGATE");
- codeElem.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.5.4");
- measureObDefinitionElement.appendChild(codeElem);
- generateCQLLogicForMeasureObservation(measureObsClauseNode, measureObDefinitionElement);
- definitionElement.appendChild(measureObDefinitionElement);
- Element measurObSectionElement = (Element) measureObservationSecElement.getFirstChild();
- measurObSectionElement.appendChild(comment);
- measurObSectionElement.appendChild(definitionElement);
- }
-
- private void generateCQLLogicForMeasureObservation(Node measureObservationNode, Element measureObservationElementNode) {
-
- if (!measureObservationNode.hasChildNodes()) {
- return;
- }
-
- String extensionAttribute = "";
-
- Document doc = measureObservationElementNode.getOwnerDocument();
-
- Element valueElement = doc.createElement(VALUE);
- valueElement.setAttribute("xsi:type", "INT");
- valueElement.setAttribute("nullFlavor", "DER");
-
- Node firstChildNode = measureObservationNode.getFirstChild();
- String firstChildNodeName = firstChildNode.getNodeName();
-
- if ("cqlfunction".equals(firstChildNodeName)) {
-
- String functionName = firstChildNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- extensionAttribute += functionName;
-
- Element expressionElement = createExpressionTag(measureObservationNode, doc, firstChildNode);
- valueElement.appendChild(expressionElement);
- measureObservationElementNode.appendChild(valueElement);
-
- } else if ("cqlaggfunction".equals(firstChildNodeName)) {
-
- String aggFunctionName = firstChildNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- String aggFunctionHQMFName = getAggMethodCode(aggFunctionName);
-
- extensionAttribute += aggFunctionHQMFName + " Of ";
-
- Node aggNodeChild = firstChildNode.getFirstChild();
- if ("cqlfunction".equals(aggNodeChild.getNodeName())) {
-
- String functionName = aggNodeChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- extensionAttribute += functionName;
-
- Element expressionElement = createExpressionTag(measureObservationNode, doc, aggNodeChild);
- valueElement.appendChild(expressionElement);
- measureObservationElementNode.appendChild(valueElement);
- }
-
- Element methodCodeElement = doc.createElement("methodCode");
- Element itemElement = doc.createElement(ITEM);
- itemElement.setAttribute(CODE, aggFunctionHQMFName);
- itemElement.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.5.84");
-
- methodCodeElement.appendChild(itemElement);
- measureObservationElementNode.appendChild(methodCodeElement);
- }
-
- if (extensionAttribute.length() > 0) {
- NodeList idList = measureObservationElementNode.getElementsByTagName(ID);
- if (idList.getLength() > 0) {
- Node id = idList.item(0);
- id.getAttributes().getNamedItem(EXTENSION).setNodeValue(extensionAttribute);
- }
- }
-
- // check for associated population id and add related HQMF nodes.
- handleMeasureObservationAssociations(measureObservationNode, measureObservationElementNode);
- }
-
- private void handleMeasureObservationAssociations(Node measureObservationNode, Element measureObDefinitionElement) {
- Node associatedPopulationNode = null;
- try {
- associatedPopulationNode = getAssociatedPopulationNode(measureObservationNode);
- if (associatedPopulationNode != null && associatedPopulationNode.hasChildNodes()) {
-
- // the measure observation criteria reference root and extension should come from the root and extension values of the associated
- // population
- String measureObservationCriteriaReferenceIdRoot = associatedPopulationNode.getAttributes().getNamedItem("uuid").getNodeValue();
- String measureObservationCriteriaReferenceIdExtension = associatedPopulationNode.getAttributes().getNamedItem("type").getNodeValue();
-
- Document doc = measureObDefinitionElement.getOwnerDocument();
-
- Element component = doc.createElement("component");
- component.setAttribute(TYPE_CODE, "COMP");
-
- Element criteriaReference = doc.createElement("criteriaReference");
- criteriaReference.setAttribute(CLASS_CODE, "OBS");
- criteriaReference.setAttribute(MOOD_CODE, "EVN");
-
- Element id = doc.createElement(ID);
- id.setAttribute(ROOT, measureObservationCriteriaReferenceIdRoot);
- id.setAttribute(EXTENSION, measureObservationCriteriaReferenceIdExtension);
-
- measureObDefinitionElement.appendChild(component);
- component.appendChild(criteriaReference);
- criteriaReference.appendChild(id);
- }
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- }
-
- private Node getAssociatedPopulationNode(Node measureObservationNode) throws XPathExpressionException {
- String associatedPopulationUUID = getAssociatedPopulationUUID(measureObservationNode);
- String associatedClauseXPath = "//measureGrouping/group/clause[@uuid = '" + associatedPopulationUUID + "']";
-
- Node associatedPopulationNode = me.getSimpleXmlProcessor().findNode(measureObservationNode.getOwnerDocument(),
- associatedClauseXPath);
- return associatedPopulationNode;
- }
-
- public String getAssociatedPopulationUUID(Node msrObsClauseNode) {
- String associatedPopuUUID = "";
-
- if (scoringType.equalsIgnoreCase("Continuous Variable")) {
- associatedPopuUUID = findMeasurePopulationUUID(msrObsClauseNode.getParentNode());
- } else {
- if (msrObsClauseNode.getAttributes().getNamedItem(ASSOCIATED_POPULATION_UUID) != null) {
- associatedPopuUUID = msrObsClauseNode.getAttributes().getNamedItem(ASSOCIATED_POPULATION_UUID).getNodeValue();
- }
- }
-
- return associatedPopuUUID;
- }
-
- private String findMeasurePopulationUUID(Node parentNode) {
-
- String uuid = "";
-
- NodeList nodeList = parentNode.getChildNodes();
- for (int i = 0; i < nodeList.getLength(); i++) {
- Node node = nodeList.item(i);
- if (MEASURE_POPULATION.equals(node.getAttributes().getNamedItem(TYPE).getNodeValue())) {
- uuid = node.getAttributes().getNamedItem(UUID).getNodeValue();
- break;
- }
- }
-
- return uuid;
- }
-
- /**
- * Create tag for Measure Observation.
- *
- * @param item
- * @param doc
- * @param cqlFunctionNode
- * @return
- */
- public Element createExpressionTag(Node item, Document doc, Node cqlFunctionNode) {
-
- Element expressionElement = doc.createElement("expression");
- String cqlFunctionNameValue = cqlFunctionNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
-
- String cqlLibraryNameXPath = "//cqlLookUp/library";
-
- try {
-
- Node cqlLibraryNameNode = me.getSimpleXmlProcessor().findNode(item.getOwnerDocument(), cqlLibraryNameXPath);
- String libraryName = "";
- if (cqlLibraryNameNode != null) {
- libraryName = cqlLibraryNameNode.getTextContent();
- }
- String expressionValueAttribute = libraryName + ".\"" + cqlFunctionNameValue + "\"";
- expressionElement.setAttribute(VALUE, expressionValueAttribute);
-
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
-
- return expressionElement;
- }
-
- private String getAggMethodCode(String aggregateFunctionName) {
-
- String hqmfCodeForAggFunction = "";
- switch (aggregateFunctionName) {
-
- case "Count":
- case "Sum":
- case "Average":
- case "Median":
- case "Mode":
- hqmfCodeForAggFunction = aggregateFunctionName.toUpperCase();
- break;
-
- case "Sample Standard Deviation":
- hqmfCodeForAggFunction = "STDEV.S";
- break;
- case "Sample Variance":
- hqmfCodeForAggFunction = "VARIANCE.S";
- break;
- case "Population Standard Deviation":
- hqmfCodeForAggFunction = "STDEV.P";
- break;
- case "Population Variance":
- hqmfCodeForAggFunction = "VARIANCE.P";
- break;
- case "Minimum":
- hqmfCodeForAggFunction = "MIN";
- break;
- case "Maximum":
- hqmfCodeForAggFunction = "MAX";
- break;
- default:
- break;
- }
-
- return hqmfCodeForAggFunction;
- }
-
- /**
- * Method to find Node's Parent - Subtree Name.
- *
- * @param node
- * - Node
- * @return SubTree DisplayName.
- */
- private String findSubTreeDisplayName(Node node) {
- String displayName = null;
- if (node != null) {
- String nodeName = node.getNodeName();
- if ("subTree".equals(nodeName)) {
- displayName = node.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- if (node.getAttributes().getNamedItem("qdmVariable") != null &&
- node.getAttributes().getNamedItem("qdmVariable").getNodeValue().equalsIgnoreCase("true")) {
- displayName = "qdm_var_" + displayName.replace("$", "");
- }
- } else {
- displayName = findSubTreeDisplayName(node.getParentNode());
- }
- }
- return StringUtils.deleteWhitespace(displayName);
- }
-
- /**
- * Method to Evaluate Clause logic Node types and generate Clause Logic in Data
- * Criteria section if applicable and generates value expression/precondition.
- *
- * @param clauseNodes
- * - Clause Logic Nodes
- * @param elementRefList
- * - Element Ref List
- * @param measureObDefinitionElement
- * - DOM element
- * @throws XPathExpressionException
- * - Exception.
- */
- private String generateMOClauseLogic(Node clauseNodes, List elementRefList,
- Element measureObDefinitionElement, boolean isClauseLogicGeneratable, String variableName,
- boolean checkIfDateTimeDiff) throws XPathExpressionException {
- String localVariableName = null;
- Node firstChildNode = null;
- Node parentSubTreeNode = null;
- String preCodExp = null;
- if (variableName != null) {
- localVariableName = variableName;
- }
- if (isClauseLogicGeneratable) {
- firstChildNode = clauseNodes.getFirstChild();
- if (clauseNodes.getParentNode() != null) {
- parentSubTreeNode = clauseNodes.getParentNode().cloneNode(false);
- } else if (clauseNodes.getNodeName().equals("subTree")) {
- parentSubTreeNode = clauseNodes.cloneNode(false);
- }
- } else {
- if (checkIfParentSubTree(clauseNodes).getNodeName().equalsIgnoreCase("subTree")) {
- if (clauseNodes.getNodeName().equals("elementRef")) {
- firstChildNode = clauseNodes;
- } else {
- firstChildNode = clauseNodes.getFirstChild();
- }
- parentSubTreeNode = clauseNodes.cloneNode(false);
- } else {
- firstChildNode = clauseNodes;
- parentSubTreeNode = clauseNodes.getParentNode().cloneNode(false);
- }
- }
- String firstChildNodeName = firstChildNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- switch (firstChildNode.getNodeName()) {
- case "setOp":
- generateForSetOp(measureObDefinitionElement, isClauseLogicGeneratable, checkIfDateTimeDiff,
- localVariableName, firstChildNode, parentSubTreeNode);
- break;
- case "relationalOp":
- preCodExp = generateForRelationalOperator(measureObDefinitionElement, isClauseLogicGeneratable,
- checkIfDateTimeDiff, localVariableName, firstChildNode, parentSubTreeNode);
- break;
- case "elementRef":
- elementRefList.add(firstChildNode);
- if (localVariableName != null) {
- preCodExp = generateValueAndExpressionTag(elementRefList, measureObDefinitionElement,
- localVariableName);
- } else {
- preCodExp = generateValueAndExpressionTag(elementRefList, measureObDefinitionElement,
- null);
- }
- break;
- case "functionalOp":
- if (INCLUDED_FUNCTIONAL_NAMES.containsKey(firstChildNodeName)) {
- preCodExp = generateForFunctionalOperator(elementRefList, measureObDefinitionElement,
- checkIfDateTimeDiff, firstChildNode, parentSubTreeNode, firstChildNodeName);
- }
- break;
- case "subTreeRef":
- generateForSubTreeRef(elementRefList, measureObDefinitionElement, isClauseLogicGeneratable,
- checkIfDateTimeDiff, localVariableName, firstChildNode, parentSubTreeNode);
- break;
- default:
- break;
- }
- return preCodExp;
- }
-
- /**
- * @param elementRefList
- * @param measureObDefinitionElement
- * @param isClauseLogicGeneratable
- * @param checkIfDateTimeDiff
- * @param localVariableName
- * @param firstChildNode
- * @param parentSubTreeNode
- * @throws XPathExpressionException
- */
- private void generateForSubTreeRef(List elementRefList, Element measureObDefinitionElement,
- boolean isClauseLogicGeneratable, boolean checkIfDateTimeDiff, String localVariableName,
- Node firstChildNode, Node parentSubTreeNode) throws XPathExpressionException {
- Node subTreeRefNodeLogic = clauseLogicMap.get(firstChildNode.getAttributes().getNamedItem("id").getNodeValue());
- Node subTreeRefParentNode = parentSubTreeNode.cloneNode(false);
- subTreeRefParentNode.appendChild(subTreeRefNodeLogic.cloneNode(true));
- String firstSubTreeNodeName = subTreeRefNodeLogic.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- if (subTreeRefNodeLogic.getNodeName().equalsIgnoreCase("functionalOp")) {
- if (firstSubTreeNodeName.equalsIgnoreCase(DATETIMEDIFF)) {
- generateMOClauseLogicForDateTimeDiff(subTreeRefNodeLogic, elementRefList, measureObDefinitionElement);
- } else {
- if (isClauseLogicGeneratable) {
- localVariableName = generateClauseLogicForChildsInsideFnxOp(subTreeRefParentNode,
- checkIfDateTimeDiff);
- }
- generateMOClauseLogic(subTreeRefParentNode, elementRefList, measureObDefinitionElement, false,
- localVariableName, checkIfDateTimeDiff);
- }
- } else {
- if (isClauseLogicGeneratable) {
- localVariableName = generateClauseLogicForChildsInsideFnxOp(subTreeRefParentNode, checkIfDateTimeDiff);
- }
- generateMOClauseLogic(subTreeRefParentNode, elementRefList, measureObDefinitionElement, false,
- localVariableName, checkIfDateTimeDiff);
- }
- }
-
- private String generateForFunctionalOperator(List elementRefList, Element measureObDefinitionElement,
- boolean checkIfDateTimeDiff, Node firstChildNode, Node parentSubTreeNode, String firstChildNodeName)
- throws XPathExpressionException {
- String localVariableName;
- String preCodExp = null;
- if (DATETIMEDIFF.equalsIgnoreCase(firstChildNodeName)) {
- generateMOClauseLogicForDateTimeDiff(firstChildNode, elementRefList, measureObDefinitionElement);
- } else {
- Node childNode = firstChildNode.getFirstChild().getFirstChild();
- String childNodeName = "";
- boolean isDateTimeDiff = false;
- if (childNode != null) {
- childNodeName = childNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- }
- if (childNodeName.equalsIgnoreCase(DATETIMEDIFF)) {
- isDateTimeDiff = true;
- }
- if (!isDateTimeDiff) {
- Node functionalOp = firstChildNode.cloneNode(true);
- parentSubTreeNode.appendChild(functionalOp);
- localVariableName = generateClauseLogicForChildsInsideFnxOp(parentSubTreeNode, false);
- preCodExp = generateMOClauseLogic(parentSubTreeNode.getFirstChild(), elementRefList,
- measureObDefinitionElement, false, localVariableName, checkIfDateTimeDiff);
- }
- }
- return preCodExp;
- }
-
- private String generateForRelationalOperator(Element measureObDefinitionElement, boolean isClauseLogicGeneratable,
- boolean checkIfDateTimeDiff, String localVariableName, Node firstChildNode, Node parentSubTreeNode)
- throws XPathExpressionException {
- String preConditionExpressionValue = null;
- Node relOpsNode = firstChildNode.cloneNode(true);
- parentSubTreeNode.appendChild(relOpsNode);
- Node relOpsFirstChild = relOpsNode.getFirstChild();
- // will not generate clause logic with timing LHS as DATETIMEDIFF
- if (!relOpsFirstChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue()
- .equalsIgnoreCase(DATETIMEDIFF)) {
- if (isClauseLogicGeneratable) {
- localVariableName = generateClauseLogicForChildsInsideFnxOp(parentSubTreeNode, checkIfDateTimeDiff);
- }
- if (localVariableName != null) {
- List relOpLHSQdm = findFirstLHSElementRef(firstChildNode, new ArrayList<>(),
- measureObDefinitionElement);
- if (relOpLHSQdm != null && relOpLHSQdm.size() > 0) {
- clauseLogicHasElementRef = true;
- preConditionExpressionValue = generateValueAndExpressionTag(relOpLHSQdm, measureObDefinitionElement, localVariableName);
- } else {
- Element valueElementRelOp = measureObDefinitionElement.getOwnerDocument().createElement("value");
- valueElementRelOp.setAttribute(XSI_TYPE, "PQ");
- Element expressionElementRelOp = measureObDefinitionElement.getOwnerDocument()
- .createElement("expression");
- expressionElementRelOp.setAttribute(VALUE, localVariableName);
- valueElementRelOp.appendChild(expressionElementRelOp);
- measureObDefinitionElement.appendChild(valueElementRelOp);
- }
- }
- }
- return preConditionExpressionValue;
- }
-
- private void generateForSetOp(Element measureObDefinitionElement, boolean isClauseLogicGeneratable,
- boolean checkIfDateTimeDiff, String localVariableName, Node firstChildNode, Node parentSubTreeNode)
- throws XPathExpressionException {
- Node setOpsNode = firstChildNode.cloneNode(true);
- parentSubTreeNode.appendChild(setOpsNode);
- if (isClauseLogicGeneratable) {
- localVariableName = generateClauseLogicForChildsInsideFnxOp(parentSubTreeNode, checkIfDateTimeDiff);
- }
- if (localVariableName != null) {
- Element valueElement = measureObDefinitionElement.getOwnerDocument().createElement("value");
- valueElement.setAttribute(XSI_TYPE, "PQ");
- Element expressionElement = measureObDefinitionElement.getOwnerDocument().createElement("expression");
- expressionElement.setAttribute(VALUE, localVariableName);
- valueElement.appendChild(expressionElement);
- measureObDefinitionElement.appendChild(valueElement);
- }
- }
-
- private Node getSubTreeNode(Node parentNode) {
- Node subTreeNode = null;
- if (parentNode != null) {
- String nodeName = parentNode.getNodeName();
- if ("subTree".equals(nodeName)) {
- subTreeNode = parentNode;
- } else {
- subTreeNode = getSubTreeNode(parentNode.getParentNode());
- }
- }
- return subTreeNode;
- }
-
- /**
- * Method to generate Measure Observation Clause logic for Date TimeDiff.
- *
- * @param clauseNodes
- * - CLause Logic Nodes
- * @param elementRefList
- * - Element Ref List
- * @param measureObDefinitionElement
- * - DOM Element.
- * @throws XPathExpressionException
- * - Exception.
- */
- private void generateMOClauseLogicForDateTimeDiff(Node clauseNodes, List elementRefList,
- Element measureObDefinitionElement) throws XPathExpressionException {
- NodeList childNodes = clauseNodes.getChildNodes();
- if (childNodes.getLength() >= DATETIMEDIFF_CHILD_COUNT) { // DATETIMEDIFF SHOULD HAVE TWO OR MORE CHILDREN.
- boolean generateValueExpression = false;
- String localVariableName = StringUtils.EMPTY;
- StringBuilder preCondExp = new StringBuilder();
- Node firstChildNode;
- for (int i = 0; i < childNodes.getLength(); i++) {
- firstChildNode = childNodes.item(i);
- String firstChildNodeName = firstChildNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
- Node parentSubTreeNode = getSubTreeNode(clauseNodes.getParentNode());
- switch (firstChildNode.getNodeName()) {
- case "relationalOp":
- Node relOpsNode = firstChildNode.cloneNode(true);
- parentSubTreeNode = parentSubTreeNode.cloneNode(false);
- parentSubTreeNode.appendChild(relOpsNode);
- localVariableName = generateClauseLogicForChildsInsideFnxOp(parentSubTreeNode, true);
- if (localVariableName != null) {
- List relOpLHSQDM = findFirstLHSElementRef(firstChildNode, new ArrayList<>(),
- measureObDefinitionElement);
- if (relOpLHSQDM != null && relOpLHSQDM.size() > 0) {
- preCondExp.append(generateValueAndExpressionTag(relOpLHSQDM, measureObDefinitionElement, localVariableName));
- clauseLogicHasElementRef = true;
- } else {
- Element valueElementRelOp = measureObDefinitionElement.getOwnerDocument()
- .createElement("value");
- valueElementRelOp.setAttribute(XSI_TYPE, "PQ");
- Element expressionElementRelOp = measureObDefinitionElement.getOwnerDocument()
- .createElement("expression");
- expressionElementRelOp.setAttribute(VALUE, localVariableName);
- valueElementRelOp.appendChild(expressionElementRelOp);
- measureObDefinitionElement.appendChild(valueElementRelOp);
- }
- }
- break;
- case "elementRef":
- elementRefList.add(firstChildNode);
- generateValueExpression = true;
- break;
- case "functionalOp":
- if (INCLUDED_FUNCTIONAL_NAMES.containsKey(firstChildNodeName)) {
- parentSubTreeNode = parentSubTreeNode.cloneNode(false);
- if (!DATETIMEDIFF.equalsIgnoreCase(firstChildNodeName)) {
- Node functionalOp = firstChildNode.cloneNode(true);
- parentSubTreeNode.appendChild(functionalOp);
- localVariableName = generateClauseLogicForChildsInsideFnxOp(parentSubTreeNode, true);
- if (localVariableName != null) {
- preCondExp.append(generateMOClauseLogic(functionalOp.getFirstChild(), new ArrayList<>(),
- measureObDefinitionElement, false, localVariableName, false));
- }
- }
- }
- break;
- case "subTreeRef":
- Node subTreeRefNodeLogic = clauseLogicMap.get(firstChildNode.getAttributes().getNamedItem("id").getNodeValue());
- if (!subTreeRefNodeLogic.getNodeName().equalsIgnoreCase("setOp")
- && !subTreeRefNodeLogic.getNodeName().equalsIgnoreCase("elementRef")) {
- Node subTreeRefParentNode = parentSubTreeNode.cloneNode(false);
- subTreeRefParentNode.appendChild(subTreeRefNodeLogic);
- preCondExp.append(generateMOClauseLogic(subTreeRefParentNode, new ArrayList<>(),
- measureObDefinitionElement, true, localVariableName, true));
- } else if (subTreeRefNodeLogic.getNodeName().equalsIgnoreCase("elementRef")) {
- elementRefList.add(subTreeRefNodeLogic);
- generateValueExpression = true;
- break;
- }
- break;
- default:
- break;
- }
- }
- if (generateValueExpression || StringUtils.isNotEmpty(preCondExp)) {
- String preConditionExpression = generateValueAndExpressionTag(elementRefList, measureObDefinitionElement, null);
- if (StringUtils.isNotEmpty(preCondExp)) {
- preConditionExpression = preCondExp.toString() + preConditionExpression;
- }
- generatePreCondition(measureObDefinitionElement, preConditionExpression, elementRefList);
- }
- }
- }
-
- /**
- * Method to find First QDM Element used in Clause Logic.
- *
- * @param firstChildNode
- * - Clause Logic First Child Node.
- * @param arrayList
- * - Element Ref List
- * @param measureObDefinitionElement
- * - DOM Element.
- * @return - Element Ref List
- */
- private List findFirstLHSElementRef(Node firstChildNode, List arrayList,
- Element measureObDefinitionElement) {
- if (firstChildNode.hasChildNodes()) {
- Node lhsNode = firstChildNode.getFirstChild();
- switch (lhsNode.getNodeName()) {
- case "elementRef":
- arrayList.add(lhsNode);
- break;
- case "setOp":
- arrayList = null;
- break;
- case "relationalOp":
- arrayList = findFirstLHSElementRef(lhsNode, arrayList, measureObDefinitionElement);
- break;
- case "functionalOp":
- if (!lhsNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue().equalsIgnoreCase(DATETIMEDIFF)) {
- if (lhsNode.hasChildNodes()) {
- arrayList = findFirstLHSElementRef(lhsNode, arrayList,
- measureObDefinitionElement);
- break;
- } else {
- arrayList = null;
- break;
- }
- }
- break;
- case "subTreeRef":
- Node subTreeRefNodeLogic = clauseLogicMap
- .get(lhsNode.getAttributes().getNamedItem("id").getNodeValue());
- arrayList = findFirstLHSElementRef(subTreeRefNodeLogic.getParentNode(), arrayList,
- measureObDefinitionElement);
- break;
- default:
- break;
- }
- }
- return arrayList;
- }
-
- /**
- * This method generates clause logic For Functional Op.
- *
- * @param clauseNodes
- * - Clause Logic Nodes.
- * @param checkIfDatimeDiff
- * - Boolean
- * @return - LocalVariable Name.
- * @throws XPathExpressionException
- * - Exception
- */
- private String generateClauseLogicForChildsInsideFnxOp(Node clauseNodes, boolean checkIfDatimeDiff)
- throws XPathExpressionException {
- Node generatedClauseEntryNode = generateSubTreeXML(clauseNodes, checkIfDatimeDiff);
- String localVariableNameValue = null;
- if (generatedClauseEntryNode != null) {
- localVariableNameValue = findSubTreeDisplayName(clauseNodes);
- localVariableNameValue = localVariableNameValue + "_" + UUIDUtilClient.uuid(5);
- NodeList localVariableNode = ((Element) generatedClauseEntryNode)
- .getElementsByTagName("localVariableName");
- if (localVariableNode != null) {
- Element localVariableElement = (Element) localVariableNode.item(0);
- if (localVariableElement != null) {
- localVariableElement.setAttribute(VALUE, localVariableNameValue);
- } else {
- localVariableElement = generatedClauseEntryNode.getOwnerDocument()
- .createElement("localVariableName");
- localVariableElement.setAttribute(VALUE, localVariableNameValue);
- generatedClauseEntryNode.insertBefore(localVariableElement,
- generatedClauseEntryNode.getFirstChild());
- }
- } else {
- Element localVariableElement = generatedClauseEntryNode.getOwnerDocument()
- .createElement("localVariableName");
- localVariableElement.setAttribute(VALUE, localVariableNameValue);
- generatedClauseEntryNode.insertBefore(localVariableElement, generatedClauseEntryNode.getFirstChild());
- }
- } else {
- if (getSubTreeNodeMap().containsKey(clauseNodes.getAttributes().getNamedItem("uuid").getNodeValue())) {
- localVariableNameValue = findSubTreeDisplayName(clauseNodes);
- }
- }
- return localVariableNameValue;
- }
-
- /**
- * Method to Generate precondition Tag.
- *
- * @param measureObDefinitionElement
- * - DOM Element
- * @param preConditionJoinExpressionValue
- * - Expression String.
- * @param elementRefList
- * - Element Ref List.
- */
- private void generatePreCondition(Element measureObDefinitionElement, String preConditionJoinExpressionValue,
- List elementRefList) {
- // precondition is created if and only if more than 1 qdm is applied.
- if (elementRefList.size() > 1 && preConditionJoinExpressionValue != null
- && preConditionJoinExpressionValue.length() > 0 || clauseLogicHasElementRef) {
- Element preConditionElement = measureObDefinitionElement.getOwnerDocument().createElement("precondition");
- preConditionElement.setAttribute(TYPE_CODE, "PRCN");
- Element joinElement = measureObDefinitionElement.getOwnerDocument().createElement("join");
- joinElement.setAttribute(CLASS_CODE, "OBS");
- joinElement.setAttribute(MOOD_CODE, "DEF");
- Element valueElement = measureObDefinitionElement.getOwnerDocument().createElement("value");
- valueElement.setAttribute(XSI_TYPE, "ED");
- valueElement.setAttribute(VALUE, preConditionJoinExpressionValue);
- joinElement.appendChild(valueElement);
- preConditionElement.appendChild(joinElement);
- measureObDefinitionElement.appendChild(preConditionElement);
- }
- }
-
- /**
- * Method to Generate Value/Expression tags.This method also returns
- * precondition Expression value.
- *
- * @param elementRefList
- * -List
- * @param measureObDefinitionElement
- * -Element
- * @param clauseLocalVariableName
- * - Local Variable Name.
- * @throws XPathExpressionException
- * Exception
- * @return String -String.
- */
- private String generateValueAndExpressionTag(List elementRefList,
- Element measureObDefinitionElement,
- String clauseLocalVariableName) throws XPathExpressionException {
- Node valueExpressionList = measureObDefinitionElement.getElementsByTagName("expression").item(0);
- Element expressionElement;
- if (valueExpressionList != null) {
- expressionElement = (Element) valueExpressionList;
- } else {
- Element valueElement = measureObDefinitionElement.getOwnerDocument().createElement("value");
- valueElement.setAttribute(XSI_TYPE, "PQ");
- expressionElement = measureObDefinitionElement.getOwnerDocument().createElement("expression");
- valueElement.appendChild(expressionElement);
- measureObDefinitionElement.appendChild(valueElement);
- }
- String expressionValue = "";
- if (expressionElement.getAttributes().getNamedItem("value") != null) {
- expressionValue = expressionElement.getAttributes().getNamedItem("value").getNodeValue();
- }
- String preConditionJoinExpressionValue = "";
- for (Node node : elementRefList) {
- String qdmUUID = node.getAttributes().getNamedItem("id").getNodeValue();
- String xPath = "/measure/elementLookUp/qdm[@uuid ='" + qdmUUID + "']";
- Node qdmNode = me.getSimpleXmlProcessor().findNode(me.getSimpleXmlProcessor().getOriginalDoc(), xPath);
- String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
- String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
- String ext = qdmName + "_" + dataType;
- if (qdmNode.getAttributes().getNamedItem(INSTANCE) != null) {
- ext = qdmNode.getAttributes().getNamedItem(INSTANCE).getNodeValue() + "_" + ext;
- }
- String qdmAttributeName = "";
- ext = StringUtils.deleteWhitespace(ext);
- String root = node.getAttributes().getNamedItem(ID).getNodeValue();
- if (node.hasChildNodes()) {
- ext = node.getFirstChild().getAttributes().getNamedItem("attrUUID").getNodeValue();
- qdmAttributeName = node.getFirstChild().getAttributes().getNamedItem(NAME).getNodeValue();
- }
- Node idNodeQDM = me.getHqmfXmlProcessor().findNode(me.getHqmfXmlProcessor().getOriginalDoc(),
- "//entry/*/id[@root='" + root + "'][@extension=\"" + ext + "\"]");
- if (idNodeQDM != null) {
- Node entryNodeForElementRef = idNodeQDM.getParentNode().getParentNode();
- String localVariableName = clauseLocalVariableName;
- if (clauseLocalVariableName == null) {
- localVariableName = entryNodeForElementRef.getFirstChild().getAttributes().getNamedItem("value")
- .getNodeValue();
- }
- String attributeMapping = "";
- // if the parent of elementRef is setOp then we'll not
- // be generating attribute Mapping for that particular QDM
- // in value Expression
- if (qdmAttributeName.length() != 0 && !node.getParentNode().getNodeName().equals("setOp")) {
- attributeMapping = getQdmAttributeMapppingDotNotation(qdmAttributeName, dataType);
- }
- if (expressionValue.length() == 0) {
- expressionValue = localVariableName;
- preConditionJoinExpressionValue = localVariableName + ".getPatient().id";
- } else {
- expressionValue += " - " + localVariableName;
- preConditionJoinExpressionValue += " == " + localVariableName + ".getPatient().id";
- }
- // appending attributeMapping for expressionValue
- if (attributeMapping != null && attributeMapping.length() != 0) {
- expressionValue += "." + attributeMapping;
- }
- }
- }
- expressionElement.setAttribute(VALUE, expressionValue);
- return preConditionJoinExpressionValue;
- }
-
- /**
- * Method to generate component and MeasureObservationSection default tags.
- *
- * @param outputProcessor
- * - XmlProcessor.
- * @return - Node.
- * @throws XPathExpressionException
- * -Exception
- */
- private Node createMeasureObservationSection(XmlProcessor outputProcessor) throws XPathExpressionException {
- Node measureObservationSection = outputProcessor.findNode(outputProcessor.getOriginalDoc(),
- "//component/measureObservationSection");
- if (measureObservationSection == null) {
- return createNewMeasureObservationSection(outputProcessor);
- } else {
- return measureObservationSection.getParentNode();
- }
- }
-
- public Node createNewMeasureObservationSection(XmlProcessor outputProcessor) {
- Element componentElement = outputProcessor.getOriginalDoc().createElement("component");
- Attr nameSpaceAttr = outputProcessor.getOriginalDoc().createAttribute("xmlns:xsi");
- nameSpaceAttr.setNodeValue(nameSpace);
- componentElement.setAttributeNodeNS(nameSpaceAttr);
- Node measureObSectionElem = outputProcessor.getOriginalDoc().createElement("measureObservationSection");
- Element templateId = outputProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
- measureObSectionElem.appendChild(templateId);
- Element itemChild = outputProcessor.getOriginalDoc().createElement(ITEM);
- itemChild.setAttribute(ROOT, "2.16.840.1.113883.10.20.28.2.4");
- itemChild.setAttribute(EXTENSION, MEASURE_OBSERVATION_EXTENSION_VALUE);
- templateId.appendChild(itemChild);
- Element idElement = outputProcessor.getOriginalDoc().createElement(ID);
- idElement.setAttribute(ROOT, java.util.UUID.randomUUID().toString());
- idElement.setAttribute(EXTENSION, "MeasureObservations");
- measureObSectionElem.appendChild(idElement);
- Element codeElem = outputProcessor.getOriginalDoc().createElement(CODE);
- codeElem.setAttribute(CODE, "57027-5");
- codeElem.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.6.1");
- codeElem.setAttribute(CODE_SYSTEM_NAME, "LOINC");
- measureObSectionElem.appendChild(codeElem);
- Element titleElem = outputProcessor.getOriginalDoc().createElement(TITLE);
- titleElem.setAttribute(VALUE, "Measure Observation Section");
- measureObSectionElem.appendChild(titleElem);
-
- // creating text for PopulationCriteria
- Element textElem = outputProcessor.getOriginalDoc().createElement("text");
-
- measureObSectionElem.appendChild(textElem);
- componentElement.appendChild(measureObSectionElem);
- outputProcessor.getOriginalDoc().getDocumentElement().appendChild(componentElement);
- return componentElement;
- }
-
- /**
- * Get Measure Scoring type.
- *
- * @param me
- * - MeasureExport
- * @throws XPathExpressionException
- * - {@link Exception}
- */
- private void getMeasureScoringType(MeasureExport me) throws XPathExpressionException {
- String xPathScoringType = "/measure/measureDetails/scoring/text()";
- javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
- scoringType = (String) xPath.evaluate(xPathScoringType, me.getSimpleXmlProcessor().getOriginalDoc(),
- XPathConstants.STRING);
- }
-
- /**
- * Method to populate clause UUID and displayName.
- *
- * @param me
- * - MeasureExport
- * @throws XPathExpressionException
- * - {@link Exception}
- */
- private void generateClauseLogicMap(MeasureExport me) throws XPathExpressionException {
- String xPath = "/measure/subTreeLookUp/subTree";
- NodeList subTreeNodeList = me.getSimpleXmlProcessor().findNodeList(me.getSimpleXmlProcessor().getOriginalDoc(),
- xPath);
- for (int i = 0; i < subTreeNodeList.getLength(); i++) {
- String uuid = subTreeNodeList.item(i).getAttributes().getNamedItem(UUID).getNodeValue();
- Node firstChildNode = subTreeNodeList.item(i).getFirstChild();
- if (firstChildNode != null) {
- clauseLogicMap.put(uuid, firstChildNode);
- }
- }
- }
-
- /**
- * Method to populate all measure groupings in measureGroupingMap.
- *
- * @param me
- * - MeasureExport
- * @throws XPathExpressionException
- * - {@link Exception}
- */
- private void getAllMeasureGroupings(MeasureExport me) throws XPathExpressionException {
- String xPath = "/measure/measureGrouping/group";
- NodeList measureGroupings = me.getSimpleXmlProcessor().findNodeList(me.getSimpleXmlProcessor().getOriginalDoc(),
- xPath);
- for (int i = 0; i < measureGroupings.getLength(); i++) {
- String measureGroupingSequence = measureGroupings.item(i).getAttributes().getNamedItem("sequence")
- .getNodeValue();
- NodeList childNodeList = measureGroupings.item(i).getChildNodes();
- measureGroupingMap.put(Integer.parseInt(measureGroupingSequence), childNodeList);
- }
- }
+ private static final String MEASURE_OBSERVATION_EXTENSION_VALUE = "2018-05-01";
+
+ private static final int DATETIMEDIFF_CHILD_COUNT = 2;
+
+ private Map clauseLogicMap = new HashMap<>();
+
+ private Map measureGroupingMap = new TreeMap<>();
+
+ private MeasureExport me;
+
+ private String scoringType;
+
+ private boolean clauseLogicHasElementRef = false;
+
+ /** MAP of Functional Ops AGGREGATE that can be used in Measure Observation. */
+ private static final Map FUNCTIONAL_OPS_AGGREGATE =
+ new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+ /** MAP of Functional Ops INCLUDED FUNCTIONS that can be used in Measure Observation. */
+ private static final Map INCLUDED_FUNCTIONAL_NAMES =
+ new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+ static {
+ FUNCTIONAL_OPS_AGGREGATE.put("MAX", "MAX");
+ FUNCTIONAL_OPS_AGGREGATE.put("MIN", "MIN");
+ FUNCTIONAL_OPS_AGGREGATE.put("SUM", "SUM");
+ FUNCTIONAL_OPS_AGGREGATE.put("AVG", "AVERAGE");
+ FUNCTIONAL_OPS_AGGREGATE.put("COUNT", "COUNT");
+ FUNCTIONAL_OPS_AGGREGATE.put("MEDIAN", "MEDIAN");
+ FUNCTIONAL_OPS_AGGREGATE.put("DATETIMEDIFF", null);
+ INCLUDED_FUNCTIONAL_NAMES.put("FIRST", "FIRST");
+ INCLUDED_FUNCTIONAL_NAMES.put("SECOND", "SECOND");
+ INCLUDED_FUNCTIONAL_NAMES.put("THIRD", "THIRD");
+ INCLUDED_FUNCTIONAL_NAMES.put("FOURTH", "FOURTH");
+ INCLUDED_FUNCTIONAL_NAMES.put("FIFTH", "FIFTH");
+ INCLUDED_FUNCTIONAL_NAMES.put("MOST RECENT", "MOST RECENT");
+ INCLUDED_FUNCTIONAL_NAMES.put("COUNT", "COUNT");
+ INCLUDED_FUNCTIONAL_NAMES.put("DATETIMEDIFF", "DATETIMEDIFF");
+ }
+
+ @Override
+ public String generate(MeasureExport me) throws Exception {
+ this.me = me;
+ setMeasureExport(me);
+ getMeasureScoringType(me);
+ generateClauseLogicMap(me);
+ getAllMeasureGroupings(me);
+ generateMeasureObSection(me);
+ return null;
+ }
+
+ /**
+ * Get DotNotation from templates.xml.
+ *
+ * @param attributeName -String
+ * @param dataTypeName - String
+ * @throws XPathExpressionException -Exception
+ * @return String dot notation.
+ */
+ private String getQdmAttributeMapppingDotNotation(String attributeName, String dataTypeName)
+ throws XPathExpressionException {
+ XmlProcessor templateXMLProcessor = QDMTemplateProcessorFactory.getTemplateProcessor(5.6);
+ String xPath =
+ "/templates/attributeMappings/attributeMapping[@qdmAttribute=\"" + attributeName + "\"]";
+ Node attributeMappingNode =
+ templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xPath);
+ if (attributeMappingNode == null) {
+ xPath =
+ "/templates/attributeMappings/attributeMapping[@qdmAttribute='"
+ + attributeName
+ + "' and @datatypes = \""
+ + dataTypeName.toLowerCase()
+ + "\"]";
+ attributeMappingNode =
+ templateXMLProcessor.findNode(templateXMLProcessor.getOriginalDoc(), xPath);
+ }
+ if (attributeMappingNode != null) {
+ return attributeMappingNode.getAttributes().getNamedItem("dotNotation").getNodeValue();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Method to generate MeasureObservation Criteria Section.
+ *
+ * @param me - MeasureExport
+ * @throws XPathExpressionException - Exception
+ */
+ private void generateMeasureObSection(MeasureExport me) throws XPathExpressionException {
+ String isInGrouping = "";
+ for (Integer key : measureGroupingMap.keySet()) {
+ NodeList groupingChildList = measureGroupingMap.get(key);
+ for (int i = 0; i < groupingChildList.getLength(); i++) {
+ Node groupingChildListItem = groupingChildList.item(i);
+
+ String popType = groupingChildListItem.getAttributes().getNamedItem(TYPE).getNodeValue();
+ if (groupingChildList.item(i).getAttributes().getNamedItem(GROUPING_CHECK) != null) {
+ isInGrouping =
+ groupingChildList.item(i).getAttributes().getNamedItem(GROUPING_CHECK).getNodeValue();
+ }
+ switch (popType) {
+ case "measureObservation":
+ if (isInGrouping != null && !isInGrouping.isEmpty()) {
+ if (isInGrouping.equalsIgnoreCase("true")) {
+
+ Node measureObSectionComponentElement =
+ createMeasureObservationSection(me.getHqmfXmlProcessor());
+
+ generateMeasureObDefinition(
+ groupingChildListItem, measureObSectionComponentElement);
+ }
+ } else {
+ Node measureObSectionComponentElement =
+ createMeasureObservationSection(me.getHqmfXmlProcessor());
+
+ generateMeasureObDefinition(groupingChildListItem, measureObSectionComponentElement);
+ }
+ break;
+ case "denominator":
+ break;
+ case "numerator":
+ break;
+ default:
+ // do nothing.
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Method to generate default criteriaTag for all population types included in measure grouping.
+ *
+ * @param measureObsClauseNode - Node
+ * @param measureObservationSecElement - Element
+ * @throws XPathExpressionException - Exception
+ */
+ private void generateMeasureObDefinition(
+ Node measureObsClauseNode, Node measureObservationSecElement) {
+
+ if (!measureObsClauseNode.hasChildNodes()) {
+ return;
+ }
+
+ Document doc = measureObservationSecElement.getOwnerDocument();
+ Comment comment =
+ doc.createComment(
+ "Definition for "
+ + measureObsClauseNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue());
+ Element definitionElement = doc.createElement("definition");
+ Element measureObDefinitionElement = doc.createElement("measureObservationDefinition");
+ measureObDefinitionElement.setAttribute(CLASS_CODE, "OBS");
+ measureObDefinitionElement.setAttribute(MOOD_CODE, "DEF");
+ Element idElem = doc.createElement(ID);
+ idElem.setAttribute(
+ ROOT, measureObsClauseNode.getAttributes().getNamedItem("uuid").getNodeValue());
+ idElem.setAttribute(EXTENSION, "MeasureObservation");
+ measureObDefinitionElement.appendChild(idElem);
+
+ Element codeElem = doc.createElement(CODE);
+ codeElem.setAttribute(CODE, "AGGREGATE");
+ codeElem.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.5.4");
+ measureObDefinitionElement.appendChild(codeElem);
+ generateCQLLogicForMeasureObservation(measureObsClauseNode, measureObDefinitionElement);
+ definitionElement.appendChild(measureObDefinitionElement);
+ Element measurObSectionElement = (Element) measureObservationSecElement.getFirstChild();
+ measurObSectionElement.appendChild(comment);
+ measurObSectionElement.appendChild(definitionElement);
+ }
+
+ private void generateCQLLogicForMeasureObservation(
+ Node measureObservationNode, Element measureObservationElementNode) {
+
+ if (!measureObservationNode.hasChildNodes()) {
+ return;
+ }
+
+ String extensionAttribute = "";
+
+ Document doc = measureObservationElementNode.getOwnerDocument();
+
+ Element valueElement = doc.createElement(VALUE);
+ valueElement.setAttribute("xsi:type", "INT");
+ valueElement.setAttribute("nullFlavor", "DER");
+
+ Node firstChildNode = measureObservationNode.getFirstChild();
+ String firstChildNodeName = firstChildNode.getNodeName();
+
+ if ("cqlfunction".equals(firstChildNodeName)) {
+
+ String functionName =
+ firstChildNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ extensionAttribute += functionName;
+
+ Element expressionElement = createExpressionTag(measureObservationNode, doc, firstChildNode);
+ valueElement.appendChild(expressionElement);
+ measureObservationElementNode.appendChild(valueElement);
+
+ } else if ("cqlaggfunction".equals(firstChildNodeName)) {
+
+ String aggFunctionName =
+ firstChildNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ String aggFunctionHQMFName = getAggMethodCode(aggFunctionName);
+
+ extensionAttribute += aggFunctionHQMFName + " Of ";
+
+ Node aggNodeChild = firstChildNode.getFirstChild();
+ if ("cqlfunction".equals(aggNodeChild.getNodeName())) {
+
+ String functionName =
+ aggNodeChild.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ extensionAttribute += functionName;
+
+ Element expressionElement = createExpressionTag(measureObservationNode, doc, aggNodeChild);
+ valueElement.appendChild(expressionElement);
+ measureObservationElementNode.appendChild(valueElement);
+ }
+
+ Element methodCodeElement = doc.createElement("methodCode");
+ Element itemElement = doc.createElement(ITEM);
+ itemElement.setAttribute(CODE, aggFunctionHQMFName);
+ itemElement.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.5.84");
+
+ methodCodeElement.appendChild(itemElement);
+ measureObservationElementNode.appendChild(methodCodeElement);
+ }
+
+ if (extensionAttribute.length() > 0) {
+ NodeList idList = measureObservationElementNode.getElementsByTagName(ID);
+ if (idList.getLength() > 0) {
+ Node id = idList.item(0);
+ id.getAttributes().getNamedItem(EXTENSION).setNodeValue(extensionAttribute);
+ }
+ }
+
+ // check for associated population id and add related HQMF nodes.
+ handleMeasureObservationAssociations(measureObservationNode, measureObservationElementNode);
+ }
+
+ private void handleMeasureObservationAssociations(
+ Node measureObservationNode, Element measureObDefinitionElement) {
+ Node associatedPopulationNode = null;
+ try {
+ associatedPopulationNode = getAssociatedPopulationNode(measureObservationNode);
+ if (associatedPopulationNode != null && associatedPopulationNode.hasChildNodes()) {
+
+ // the measure observation criteria reference root and extension should come from the root
+ // and extension values of the associated
+ // population
+ String measureObservationCriteriaReferenceIdRoot =
+ associatedPopulationNode.getAttributes().getNamedItem("uuid").getNodeValue();
+ String measureObservationCriteriaReferenceIdExtension =
+ associatedPopulationNode.getAttributes().getNamedItem("type").getNodeValue();
+
+ Document doc = measureObDefinitionElement.getOwnerDocument();
+
+ Element component = doc.createElement("component");
+ component.setAttribute(TYPE_CODE, "COMP");
+
+ Element criteriaReference = doc.createElement("criteriaReference");
+ criteriaReference.setAttribute(CLASS_CODE, "OBS");
+ criteriaReference.setAttribute(MOOD_CODE, "EVN");
+
+ Element id = doc.createElement(ID);
+ id.setAttribute(ROOT, measureObservationCriteriaReferenceIdRoot);
+ id.setAttribute(EXTENSION, measureObservationCriteriaReferenceIdExtension);
+
+ measureObDefinitionElement.appendChild(component);
+ component.appendChild(criteriaReference);
+ criteriaReference.appendChild(id);
+ }
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private Node getAssociatedPopulationNode(Node measureObservationNode)
+ throws XPathExpressionException {
+ String associatedPopulationUUID = getAssociatedPopulationUUID(measureObservationNode);
+ String associatedClauseXPath =
+ "//measureGrouping/group/clause[@uuid = '" + associatedPopulationUUID + "']";
+
+ Node associatedPopulationNode =
+ me.getSimpleXmlProcessor()
+ .findNode(measureObservationNode.getOwnerDocument(), associatedClauseXPath);
+ return associatedPopulationNode;
+ }
+
+ public String getAssociatedPopulationUUID(Node msrObsClauseNode) {
+ String associatedPopuUUID = "";
+
+ if (scoringType.equalsIgnoreCase("Continuous Variable")) {
+ associatedPopuUUID = findMeasurePopulationUUID(msrObsClauseNode.getParentNode());
+ } else {
+ if (msrObsClauseNode.getAttributes().getNamedItem(ASSOCIATED_POPULATION_UUID) != null) {
+ associatedPopuUUID =
+ msrObsClauseNode
+ .getAttributes()
+ .getNamedItem(ASSOCIATED_POPULATION_UUID)
+ .getNodeValue();
+ }
+ }
+
+ return associatedPopuUUID;
+ }
+
+ private String findMeasurePopulationUUID(Node parentNode) {
+
+ String uuid = "";
+
+ NodeList nodeList = parentNode.getChildNodes();
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node node = nodeList.item(i);
+ if (MEASURE_POPULATION.equals(node.getAttributes().getNamedItem(TYPE).getNodeValue())) {
+ uuid = node.getAttributes().getNamedItem(UUID).getNodeValue();
+ break;
+ }
+ }
+
+ return uuid;
+ }
+
+ /**
+ * Create tag for Measure Observation.
+ *
+ * @param item
+ * @param doc
+ * @param cqlFunctionNode
+ * @return
+ */
+ public Element createExpressionTag(Node item, Document doc, Node cqlFunctionNode) {
+
+ Element expressionElement = doc.createElement("expression");
+ String cqlFunctionNameValue =
+ cqlFunctionNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+
+ String cqlLibraryNameXPath = "//cqlLookUp/library";
+
+ try {
+
+ Node cqlLibraryNameNode =
+ me.getSimpleXmlProcessor().findNode(item.getOwnerDocument(), cqlLibraryNameXPath);
+ String libraryName = "";
+ if (cqlLibraryNameNode != null) {
+ libraryName = cqlLibraryNameNode.getTextContent();
+ }
+ String expressionValueAttribute = libraryName + ".\"" + cqlFunctionNameValue + "\"";
+ expressionElement.setAttribute(VALUE, expressionValueAttribute);
+
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+
+ return expressionElement;
+ }
+
+ private String getAggMethodCode(String aggregateFunctionName) {
+
+ String hqmfCodeForAggFunction = "";
+ switch (aggregateFunctionName) {
+ case "Count":
+ case "Sum":
+ case "Average":
+ case "Median":
+ case "Mode":
+ hqmfCodeForAggFunction = aggregateFunctionName.toUpperCase();
+ break;
+
+ case "Sample Standard Deviation":
+ hqmfCodeForAggFunction = "STDEV.S";
+ break;
+ case "Sample Variance":
+ hqmfCodeForAggFunction = "VARIANCE.S";
+ break;
+ case "Population Standard Deviation":
+ hqmfCodeForAggFunction = "STDEV.P";
+ break;
+ case "Population Variance":
+ hqmfCodeForAggFunction = "VARIANCE.P";
+ break;
+ case "Minimum":
+ hqmfCodeForAggFunction = "MIN";
+ break;
+ case "Maximum":
+ hqmfCodeForAggFunction = "MAX";
+ break;
+ default:
+ break;
+ }
+
+ return hqmfCodeForAggFunction;
+ }
+
+ /**
+ * Method to find Node's Parent - Subtree Name.
+ *
+ * @param node - Node
+ * @return SubTree DisplayName.
+ */
+ private String findSubTreeDisplayName(Node node) {
+ String displayName = null;
+ if (node != null) {
+ String nodeName = node.getNodeName();
+ if ("subTree".equals(nodeName)) {
+ displayName = node.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ if (node.getAttributes().getNamedItem("qdmVariable") != null
+ && node.getAttributes()
+ .getNamedItem("qdmVariable")
+ .getNodeValue()
+ .equalsIgnoreCase("true")) {
+ displayName = "qdm_var_" + displayName.replace("$", "");
+ }
+ } else {
+ displayName = findSubTreeDisplayName(node.getParentNode());
+ }
+ }
+ return StringUtils.deleteWhitespace(displayName);
+ }
+
+ /**
+ * Method to Evaluate Clause logic Node types and generate Clause Logic in Data Criteria section
+ * if applicable and generates value expression/precondition.
+ *
+ * @param clauseNodes - Clause Logic Nodes
+ * @param elementRefList - Element Ref List
+ * @param measureObDefinitionElement - DOM element
+ * @throws XPathExpressionException - Exception.
+ */
+ private String generateMOClauseLogic(
+ Node clauseNodes,
+ List elementRefList,
+ Element measureObDefinitionElement,
+ boolean isClauseLogicGeneratable,
+ String variableName,
+ boolean checkIfDateTimeDiff)
+ throws XPathExpressionException {
+ String localVariableName = null;
+ Node firstChildNode = null;
+ Node parentSubTreeNode = null;
+ String preCodExp = null;
+ if (variableName != null) {
+ localVariableName = variableName;
+ }
+ if (isClauseLogicGeneratable) {
+ firstChildNode = clauseNodes.getFirstChild();
+ if (clauseNodes.getParentNode() != null) {
+ parentSubTreeNode = clauseNodes.getParentNode().cloneNode(false);
+ } else if (clauseNodes.getNodeName().equals("subTree")) {
+ parentSubTreeNode = clauseNodes.cloneNode(false);
+ }
+ } else {
+ if (checkIfParentSubTree(clauseNodes).getNodeName().equalsIgnoreCase("subTree")) {
+ if (clauseNodes.getNodeName().equals("elementRef")) {
+ firstChildNode = clauseNodes;
+ } else {
+ firstChildNode = clauseNodes.getFirstChild();
+ }
+ parentSubTreeNode = clauseNodes.cloneNode(false);
+ } else {
+ firstChildNode = clauseNodes;
+ parentSubTreeNode = clauseNodes.getParentNode().cloneNode(false);
+ }
+ }
+ String firstChildNodeName =
+ firstChildNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ switch (firstChildNode.getNodeName()) {
+ case "setOp":
+ generateForSetOp(
+ measureObDefinitionElement,
+ isClauseLogicGeneratable,
+ checkIfDateTimeDiff,
+ localVariableName,
+ firstChildNode,
+ parentSubTreeNode);
+ break;
+ case "relationalOp":
+ preCodExp =
+ generateForRelationalOperator(
+ measureObDefinitionElement,
+ isClauseLogicGeneratable,
+ checkIfDateTimeDiff,
+ localVariableName,
+ firstChildNode,
+ parentSubTreeNode);
+ break;
+ case "elementRef":
+ elementRefList.add(firstChildNode);
+ if (localVariableName != null) {
+ preCodExp =
+ generateValueAndExpressionTag(
+ elementRefList, measureObDefinitionElement, localVariableName);
+ } else {
+ preCodExp =
+ generateValueAndExpressionTag(elementRefList, measureObDefinitionElement, null);
+ }
+ break;
+ case "functionalOp":
+ if (INCLUDED_FUNCTIONAL_NAMES.containsKey(firstChildNodeName)) {
+ preCodExp =
+ generateForFunctionalOperator(
+ elementRefList,
+ measureObDefinitionElement,
+ checkIfDateTimeDiff,
+ firstChildNode,
+ parentSubTreeNode,
+ firstChildNodeName);
+ }
+ break;
+ case "subTreeRef":
+ generateForSubTreeRef(
+ elementRefList,
+ measureObDefinitionElement,
+ isClauseLogicGeneratable,
+ checkIfDateTimeDiff,
+ localVariableName,
+ firstChildNode,
+ parentSubTreeNode);
+ break;
+ default:
+ break;
+ }
+ return preCodExp;
+ }
+
+ /**
+ * @param elementRefList
+ * @param measureObDefinitionElement
+ * @param isClauseLogicGeneratable
+ * @param checkIfDateTimeDiff
+ * @param localVariableName
+ * @param firstChildNode
+ * @param parentSubTreeNode
+ * @throws XPathExpressionException
+ */
+ private void generateForSubTreeRef(
+ List elementRefList,
+ Element measureObDefinitionElement,
+ boolean isClauseLogicGeneratable,
+ boolean checkIfDateTimeDiff,
+ String localVariableName,
+ Node firstChildNode,
+ Node parentSubTreeNode)
+ throws XPathExpressionException {
+ Node subTreeRefNodeLogic =
+ clauseLogicMap.get(firstChildNode.getAttributes().getNamedItem("id").getNodeValue());
+ Node subTreeRefParentNode = parentSubTreeNode.cloneNode(false);
+ subTreeRefParentNode.appendChild(subTreeRefNodeLogic.cloneNode(true));
+ String firstSubTreeNodeName =
+ subTreeRefNodeLogic.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ if (subTreeRefNodeLogic.getNodeName().equalsIgnoreCase("functionalOp")) {
+ if (firstSubTreeNodeName.equalsIgnoreCase(DATETIMEDIFF)) {
+ generateMOClauseLogicForDateTimeDiff(
+ subTreeRefNodeLogic, elementRefList, measureObDefinitionElement);
+ } else {
+ if (isClauseLogicGeneratable) {
+ localVariableName =
+ generateClauseLogicForChildsInsideFnxOp(subTreeRefParentNode, checkIfDateTimeDiff);
+ }
+ generateMOClauseLogic(
+ subTreeRefParentNode,
+ elementRefList,
+ measureObDefinitionElement,
+ false,
+ localVariableName,
+ checkIfDateTimeDiff);
+ }
+ } else {
+ if (isClauseLogicGeneratable) {
+ localVariableName =
+ generateClauseLogicForChildsInsideFnxOp(subTreeRefParentNode, checkIfDateTimeDiff);
+ }
+ generateMOClauseLogic(
+ subTreeRefParentNode,
+ elementRefList,
+ measureObDefinitionElement,
+ false,
+ localVariableName,
+ checkIfDateTimeDiff);
+ }
+ }
+
+ private String generateForFunctionalOperator(
+ List elementRefList,
+ Element measureObDefinitionElement,
+ boolean checkIfDateTimeDiff,
+ Node firstChildNode,
+ Node parentSubTreeNode,
+ String firstChildNodeName)
+ throws XPathExpressionException {
+ String localVariableName;
+ String preCodExp = null;
+ if (DATETIMEDIFF.equalsIgnoreCase(firstChildNodeName)) {
+ generateMOClauseLogicForDateTimeDiff(
+ firstChildNode, elementRefList, measureObDefinitionElement);
+ } else {
+ Node childNode = firstChildNode.getFirstChild().getFirstChild();
+ String childNodeName = "";
+ boolean isDateTimeDiff = false;
+ if (childNode != null) {
+ childNodeName = childNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ }
+ if (childNodeName.equalsIgnoreCase(DATETIMEDIFF)) {
+ isDateTimeDiff = true;
+ }
+ if (!isDateTimeDiff) {
+ Node functionalOp = firstChildNode.cloneNode(true);
+ parentSubTreeNode.appendChild(functionalOp);
+ localVariableName = generateClauseLogicForChildsInsideFnxOp(parentSubTreeNode, false);
+ preCodExp =
+ generateMOClauseLogic(
+ parentSubTreeNode.getFirstChild(),
+ elementRefList,
+ measureObDefinitionElement,
+ false,
+ localVariableName,
+ checkIfDateTimeDiff);
+ }
+ }
+ return preCodExp;
+ }
+
+ private String generateForRelationalOperator(
+ Element measureObDefinitionElement,
+ boolean isClauseLogicGeneratable,
+ boolean checkIfDateTimeDiff,
+ String localVariableName,
+ Node firstChildNode,
+ Node parentSubTreeNode)
+ throws XPathExpressionException {
+ String preConditionExpressionValue = null;
+ Node relOpsNode = firstChildNode.cloneNode(true);
+ parentSubTreeNode.appendChild(relOpsNode);
+ Node relOpsFirstChild = relOpsNode.getFirstChild();
+ // will not generate clause logic with timing LHS as DATETIMEDIFF
+ if (!relOpsFirstChild
+ .getAttributes()
+ .getNamedItem(DISPLAY_NAME)
+ .getNodeValue()
+ .equalsIgnoreCase(DATETIMEDIFF)) {
+ if (isClauseLogicGeneratable) {
+ localVariableName =
+ generateClauseLogicForChildsInsideFnxOp(parentSubTreeNode, checkIfDateTimeDiff);
+ }
+ if (localVariableName != null) {
+ List relOpLHSQdm =
+ findFirstLHSElementRef(firstChildNode, new ArrayList<>(), measureObDefinitionElement);
+ if (relOpLHSQdm != null && relOpLHSQdm.size() > 0) {
+ clauseLogicHasElementRef = true;
+ preConditionExpressionValue =
+ generateValueAndExpressionTag(
+ relOpLHSQdm, measureObDefinitionElement, localVariableName);
+ } else {
+ Element valueElementRelOp =
+ measureObDefinitionElement.getOwnerDocument().createElement("value");
+ valueElementRelOp.setAttribute(XSI_TYPE, "PQ");
+ Element expressionElementRelOp =
+ measureObDefinitionElement.getOwnerDocument().createElement("expression");
+ expressionElementRelOp.setAttribute(VALUE, localVariableName);
+ valueElementRelOp.appendChild(expressionElementRelOp);
+ measureObDefinitionElement.appendChild(valueElementRelOp);
+ }
+ }
+ }
+ return preConditionExpressionValue;
+ }
+
+ private void generateForSetOp(
+ Element measureObDefinitionElement,
+ boolean isClauseLogicGeneratable,
+ boolean checkIfDateTimeDiff,
+ String localVariableName,
+ Node firstChildNode,
+ Node parentSubTreeNode)
+ throws XPathExpressionException {
+ Node setOpsNode = firstChildNode.cloneNode(true);
+ parentSubTreeNode.appendChild(setOpsNode);
+ if (isClauseLogicGeneratable) {
+ localVariableName =
+ generateClauseLogicForChildsInsideFnxOp(parentSubTreeNode, checkIfDateTimeDiff);
+ }
+ if (localVariableName != null) {
+ Element valueElement = measureObDefinitionElement.getOwnerDocument().createElement("value");
+ valueElement.setAttribute(XSI_TYPE, "PQ");
+ Element expressionElement =
+ measureObDefinitionElement.getOwnerDocument().createElement("expression");
+ expressionElement.setAttribute(VALUE, localVariableName);
+ valueElement.appendChild(expressionElement);
+ measureObDefinitionElement.appendChild(valueElement);
+ }
+ }
+
+ private Node getSubTreeNode(Node parentNode) {
+ Node subTreeNode = null;
+ if (parentNode != null) {
+ String nodeName = parentNode.getNodeName();
+ if ("subTree".equals(nodeName)) {
+ subTreeNode = parentNode;
+ } else {
+ subTreeNode = getSubTreeNode(parentNode.getParentNode());
+ }
+ }
+ return subTreeNode;
+ }
+
+ /**
+ * Method to generate Measure Observation Clause logic for Date TimeDiff.
+ *
+ * @param clauseNodes - CLause Logic Nodes
+ * @param elementRefList - Element Ref List
+ * @param measureObDefinitionElement - DOM Element.
+ * @throws XPathExpressionException - Exception.
+ */
+ private void generateMOClauseLogicForDateTimeDiff(
+ Node clauseNodes, List elementRefList, Element measureObDefinitionElement)
+ throws XPathExpressionException {
+ NodeList childNodes = clauseNodes.getChildNodes();
+ if (childNodes.getLength()
+ >= DATETIMEDIFF_CHILD_COUNT) { // DATETIMEDIFF SHOULD HAVE TWO OR MORE CHILDREN.
+ boolean generateValueExpression = false;
+ String localVariableName = StringUtils.EMPTY;
+ StringBuilder preCondExp = new StringBuilder();
+ Node firstChildNode;
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ firstChildNode = childNodes.item(i);
+ String firstChildNodeName =
+ firstChildNode.getAttributes().getNamedItem(DISPLAY_NAME).getNodeValue();
+ Node parentSubTreeNode = getSubTreeNode(clauseNodes.getParentNode());
+ switch (firstChildNode.getNodeName()) {
+ case "relationalOp":
+ Node relOpsNode = firstChildNode.cloneNode(true);
+ parentSubTreeNode = parentSubTreeNode.cloneNode(false);
+ parentSubTreeNode.appendChild(relOpsNode);
+ localVariableName = generateClauseLogicForChildsInsideFnxOp(parentSubTreeNode, true);
+ if (localVariableName != null) {
+ List relOpLHSQDM =
+ findFirstLHSElementRef(
+ firstChildNode, new ArrayList<>(), measureObDefinitionElement);
+ if (relOpLHSQDM != null && relOpLHSQDM.size() > 0) {
+ preCondExp.append(
+ generateValueAndExpressionTag(
+ relOpLHSQDM, measureObDefinitionElement, localVariableName));
+ clauseLogicHasElementRef = true;
+ } else {
+ Element valueElementRelOp =
+ measureObDefinitionElement.getOwnerDocument().createElement("value");
+ valueElementRelOp.setAttribute(XSI_TYPE, "PQ");
+ Element expressionElementRelOp =
+ measureObDefinitionElement.getOwnerDocument().createElement("expression");
+ expressionElementRelOp.setAttribute(VALUE, localVariableName);
+ valueElementRelOp.appendChild(expressionElementRelOp);
+ measureObDefinitionElement.appendChild(valueElementRelOp);
+ }
+ }
+ break;
+ case "elementRef":
+ elementRefList.add(firstChildNode);
+ generateValueExpression = true;
+ break;
+ case "functionalOp":
+ if (INCLUDED_FUNCTIONAL_NAMES.containsKey(firstChildNodeName)) {
+ parentSubTreeNode = parentSubTreeNode.cloneNode(false);
+ if (!DATETIMEDIFF.equalsIgnoreCase(firstChildNodeName)) {
+ Node functionalOp = firstChildNode.cloneNode(true);
+ parentSubTreeNode.appendChild(functionalOp);
+ localVariableName =
+ generateClauseLogicForChildsInsideFnxOp(parentSubTreeNode, true);
+ if (localVariableName != null) {
+ preCondExp.append(
+ generateMOClauseLogic(
+ functionalOp.getFirstChild(),
+ new ArrayList<>(),
+ measureObDefinitionElement,
+ false,
+ localVariableName,
+ false));
+ }
+ }
+ }
+ break;
+ case "subTreeRef":
+ Node subTreeRefNodeLogic =
+ clauseLogicMap.get(
+ firstChildNode.getAttributes().getNamedItem("id").getNodeValue());
+ if (!subTreeRefNodeLogic.getNodeName().equalsIgnoreCase("setOp")
+ && !subTreeRefNodeLogic.getNodeName().equalsIgnoreCase("elementRef")) {
+ Node subTreeRefParentNode = parentSubTreeNode.cloneNode(false);
+ subTreeRefParentNode.appendChild(subTreeRefNodeLogic);
+ preCondExp.append(
+ generateMOClauseLogic(
+ subTreeRefParentNode,
+ new ArrayList<>(),
+ measureObDefinitionElement,
+ true,
+ localVariableName,
+ true));
+ } else if (subTreeRefNodeLogic.getNodeName().equalsIgnoreCase("elementRef")) {
+ elementRefList.add(subTreeRefNodeLogic);
+ generateValueExpression = true;
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (generateValueExpression || StringUtils.isNotEmpty(preCondExp)) {
+ String preConditionExpression =
+ generateValueAndExpressionTag(elementRefList, measureObDefinitionElement, null);
+ if (StringUtils.isNotEmpty(preCondExp)) {
+ preConditionExpression = preCondExp.toString() + preConditionExpression;
+ }
+ generatePreCondition(measureObDefinitionElement, preConditionExpression, elementRefList);
+ }
+ }
+ }
+
+ /**
+ * Method to find First QDM Element used in Clause Logic.
+ *
+ * @param firstChildNode - Clause Logic First Child Node.
+ * @param arrayList - Element Ref List
+ * @param measureObDefinitionElement - DOM Element.
+ * @return - Element Ref List
+ */
+ private List findFirstLHSElementRef(
+ Node firstChildNode, List arrayList, Element measureObDefinitionElement) {
+ if (firstChildNode.hasChildNodes()) {
+ Node lhsNode = firstChildNode.getFirstChild();
+ switch (lhsNode.getNodeName()) {
+ case "elementRef":
+ arrayList.add(lhsNode);
+ break;
+ case "setOp":
+ arrayList = null;
+ break;
+ case "relationalOp":
+ arrayList = findFirstLHSElementRef(lhsNode, arrayList, measureObDefinitionElement);
+ break;
+ case "functionalOp":
+ if (!lhsNode
+ .getAttributes()
+ .getNamedItem(DISPLAY_NAME)
+ .getNodeValue()
+ .equalsIgnoreCase(DATETIMEDIFF)) {
+ if (lhsNode.hasChildNodes()) {
+ arrayList = findFirstLHSElementRef(lhsNode, arrayList, measureObDefinitionElement);
+ break;
+ } else {
+ arrayList = null;
+ break;
+ }
+ }
+ break;
+ case "subTreeRef":
+ Node subTreeRefNodeLogic =
+ clauseLogicMap.get(lhsNode.getAttributes().getNamedItem("id").getNodeValue());
+ arrayList =
+ findFirstLHSElementRef(
+ subTreeRefNodeLogic.getParentNode(), arrayList, measureObDefinitionElement);
+ break;
+ default:
+ break;
+ }
+ }
+ return arrayList;
+ }
+
+ /**
+ * This method generates clause logic For Functional Op.
+ *
+ * @param clauseNodes - Clause Logic Nodes.
+ * @param checkIfDatimeDiff - Boolean
+ * @return - LocalVariable Name.
+ * @throws XPathExpressionException - Exception
+ */
+ private String generateClauseLogicForChildsInsideFnxOp(
+ Node clauseNodes, boolean checkIfDatimeDiff) throws XPathExpressionException {
+ Node generatedClauseEntryNode = generateSubTreeXML(clauseNodes, checkIfDatimeDiff);
+ String localVariableNameValue = null;
+ if (generatedClauseEntryNode != null) {
+ localVariableNameValue = findSubTreeDisplayName(clauseNodes);
+ localVariableNameValue = localVariableNameValue + "_" + UUIDUtilClient.uuid(5);
+ NodeList localVariableNode =
+ ((Element) generatedClauseEntryNode).getElementsByTagName("localVariableName");
+ if (localVariableNode != null) {
+ Element localVariableElement = (Element) localVariableNode.item(0);
+ if (localVariableElement != null) {
+ localVariableElement.setAttribute(VALUE, localVariableNameValue);
+ } else {
+ localVariableElement =
+ generatedClauseEntryNode.getOwnerDocument().createElement("localVariableName");
+ localVariableElement.setAttribute(VALUE, localVariableNameValue);
+ generatedClauseEntryNode.insertBefore(
+ localVariableElement, generatedClauseEntryNode.getFirstChild());
+ }
+ } else {
+ Element localVariableElement =
+ generatedClauseEntryNode.getOwnerDocument().createElement("localVariableName");
+ localVariableElement.setAttribute(VALUE, localVariableNameValue);
+ generatedClauseEntryNode.insertBefore(
+ localVariableElement, generatedClauseEntryNode.getFirstChild());
+ }
+ } else {
+ if (getSubTreeNodeMap()
+ .containsKey(clauseNodes.getAttributes().getNamedItem("uuid").getNodeValue())) {
+ localVariableNameValue = findSubTreeDisplayName(clauseNodes);
+ }
+ }
+ return localVariableNameValue;
+ }
+
+ /**
+ * Method to Generate precondition Tag.
+ *
+ * @param measureObDefinitionElement - DOM Element
+ * @param preConditionJoinExpressionValue - Expression String.
+ * @param elementRefList - Element Ref List.
+ */
+ private void generatePreCondition(
+ Element measureObDefinitionElement,
+ String preConditionJoinExpressionValue,
+ List elementRefList) {
+ // precondition is created if and only if more than 1 qdm is applied.
+ if (elementRefList.size() > 1
+ && preConditionJoinExpressionValue != null
+ && preConditionJoinExpressionValue.length() > 0
+ || clauseLogicHasElementRef) {
+ Element preConditionElement =
+ measureObDefinitionElement.getOwnerDocument().createElement("precondition");
+ preConditionElement.setAttribute(TYPE_CODE, "PRCN");
+ Element joinElement = measureObDefinitionElement.getOwnerDocument().createElement("join");
+ joinElement.setAttribute(CLASS_CODE, "OBS");
+ joinElement.setAttribute(MOOD_CODE, "DEF");
+ Element valueElement = measureObDefinitionElement.getOwnerDocument().createElement("value");
+ valueElement.setAttribute(XSI_TYPE, "ED");
+ valueElement.setAttribute(VALUE, preConditionJoinExpressionValue);
+ joinElement.appendChild(valueElement);
+ preConditionElement.appendChild(joinElement);
+ measureObDefinitionElement.appendChild(preConditionElement);
+ }
+ }
+
+ /**
+ * Method to Generate Value/Expression tags.This method also returns precondition Expression
+ * value.
+ *
+ * @param elementRefList -List
+ * @param measureObDefinitionElement -Element
+ * @param clauseLocalVariableName - Local Variable Name.
+ * @throws XPathExpressionException Exception
+ * @return String -String.
+ */
+ private String generateValueAndExpressionTag(
+ List elementRefList, Element measureObDefinitionElement, String clauseLocalVariableName)
+ throws XPathExpressionException {
+ Node valueExpressionList =
+ measureObDefinitionElement.getElementsByTagName("expression").item(0);
+ Element expressionElement;
+ if (valueExpressionList != null) {
+ expressionElement = (Element) valueExpressionList;
+ } else {
+ Element valueElement = measureObDefinitionElement.getOwnerDocument().createElement("value");
+ valueElement.setAttribute(XSI_TYPE, "PQ");
+ expressionElement = measureObDefinitionElement.getOwnerDocument().createElement("expression");
+ valueElement.appendChild(expressionElement);
+ measureObDefinitionElement.appendChild(valueElement);
+ }
+ String expressionValue = "";
+ if (expressionElement.getAttributes().getNamedItem("value") != null) {
+ expressionValue = expressionElement.getAttributes().getNamedItem("value").getNodeValue();
+ }
+ String preConditionJoinExpressionValue = "";
+ for (Node node : elementRefList) {
+ String qdmUUID = node.getAttributes().getNamedItem("id").getNodeValue();
+ String xPath = "/measure/elementLookUp/qdm[@uuid ='" + qdmUUID + "']";
+ Node qdmNode =
+ me.getSimpleXmlProcessor().findNode(me.getSimpleXmlProcessor().getOriginalDoc(), xPath);
+ String dataType = qdmNode.getAttributes().getNamedItem("datatype").getNodeValue();
+ String qdmName = qdmNode.getAttributes().getNamedItem(NAME).getNodeValue();
+ String ext = qdmName + "_" + dataType;
+ if (qdmNode.getAttributes().getNamedItem(INSTANCE) != null) {
+ ext = qdmNode.getAttributes().getNamedItem(INSTANCE).getNodeValue() + "_" + ext;
+ }
+ String qdmAttributeName = "";
+ ext = StringUtils.deleteWhitespace(ext);
+ String root = node.getAttributes().getNamedItem(ID).getNodeValue();
+ if (node.hasChildNodes()) {
+ ext = node.getFirstChild().getAttributes().getNamedItem("attrUUID").getNodeValue();
+ qdmAttributeName = node.getFirstChild().getAttributes().getNamedItem(NAME).getNodeValue();
+ }
+ Node idNodeQDM =
+ me.getHqmfXmlProcessor()
+ .findNode(
+ me.getHqmfXmlProcessor().getOriginalDoc(),
+ "//entry/*/id[@root='" + root + "'][@extension=\"" + ext + "\"]");
+ if (idNodeQDM != null) {
+ Node entryNodeForElementRef = idNodeQDM.getParentNode().getParentNode();
+ String localVariableName = clauseLocalVariableName;
+ if (clauseLocalVariableName == null) {
+ localVariableName =
+ entryNodeForElementRef
+ .getFirstChild()
+ .getAttributes()
+ .getNamedItem("value")
+ .getNodeValue();
+ }
+ String attributeMapping = "";
+ // if the parent of elementRef is setOp then we'll not
+ // be generating attribute Mapping for that particular QDM
+ // in value Expression
+ if (qdmAttributeName.length() != 0 && !node.getParentNode().getNodeName().equals("setOp")) {
+ attributeMapping = getQdmAttributeMapppingDotNotation(qdmAttributeName, dataType);
+ }
+ if (expressionValue.length() == 0) {
+ expressionValue = localVariableName;
+ preConditionJoinExpressionValue = localVariableName + ".getPatient().id";
+ } else {
+ expressionValue += " - " + localVariableName;
+ preConditionJoinExpressionValue += " == " + localVariableName + ".getPatient().id";
+ }
+ // appending attributeMapping for expressionValue
+ if (attributeMapping != null && attributeMapping.length() != 0) {
+ expressionValue += "." + attributeMapping;
+ }
+ }
+ }
+ expressionElement.setAttribute(VALUE, expressionValue);
+ return preConditionJoinExpressionValue;
+ }
+
+ /**
+ * Method to generate component and MeasureObservationSection default tags.
+ *
+ * @param outputProcessor - XmlProcessor.
+ * @return - Node.
+ * @throws XPathExpressionException -Exception
+ */
+ private Node createMeasureObservationSection(XmlProcessor outputProcessor)
+ throws XPathExpressionException {
+ Node measureObservationSection =
+ outputProcessor.findNode(
+ outputProcessor.getOriginalDoc(), "//component/measureObservationSection");
+ if (measureObservationSection == null) {
+ return createNewMeasureObservationSection(outputProcessor);
+ } else {
+ return measureObservationSection.getParentNode();
+ }
+ }
+
+ public Node createNewMeasureObservationSection(XmlProcessor outputProcessor) {
+ Element componentElement = outputProcessor.getOriginalDoc().createElement("component");
+ Attr nameSpaceAttr = outputProcessor.getOriginalDoc().createAttribute("xmlns:xsi");
+ nameSpaceAttr.setNodeValue(nameSpace);
+ componentElement.setAttributeNodeNS(nameSpaceAttr);
+ Node measureObSectionElem =
+ outputProcessor.getOriginalDoc().createElement("measureObservationSection");
+ Element templateId = outputProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
+ measureObSectionElem.appendChild(templateId);
+ Element itemChild = outputProcessor.getOriginalDoc().createElement(ITEM);
+ itemChild.setAttribute(ROOT, "2.16.840.1.113883.10.20.28.2.4");
+ itemChild.setAttribute(EXTENSION, MEASURE_OBSERVATION_EXTENSION_VALUE);
+ templateId.appendChild(itemChild);
+ Element idElement = outputProcessor.getOriginalDoc().createElement(ID);
+ idElement.setAttribute(ROOT, java.util.UUID.randomUUID().toString());
+ idElement.setAttribute(EXTENSION, "MeasureObservations");
+ measureObSectionElem.appendChild(idElement);
+ Element codeElem = outputProcessor.getOriginalDoc().createElement(CODE);
+ codeElem.setAttribute(CODE, "57027-5");
+ codeElem.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.6.1");
+ codeElem.setAttribute(CODE_SYSTEM_NAME, "LOINC");
+ measureObSectionElem.appendChild(codeElem);
+ Element titleElem = outputProcessor.getOriginalDoc().createElement(TITLE);
+ titleElem.setAttribute(VALUE, "Measure Observation Section");
+ measureObSectionElem.appendChild(titleElem);
+
+ // creating text for PopulationCriteria
+ Element textElem = outputProcessor.getOriginalDoc().createElement("text");
+
+ measureObSectionElem.appendChild(textElem);
+ componentElement.appendChild(measureObSectionElem);
+ outputProcessor.getOriginalDoc().getDocumentElement().appendChild(componentElement);
+ return componentElement;
+ }
+
+ /**
+ * Get Measure Scoring type.
+ *
+ * @param me - MeasureExport
+ * @throws XPathExpressionException - {@link Exception}
+ */
+ private void getMeasureScoringType(MeasureExport me) throws XPathExpressionException {
+ String xPathScoringType = "/measure/measureDetails/scoring/text()";
+ javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
+ scoringType =
+ (String)
+ xPath.evaluate(
+ xPathScoringType,
+ me.getSimpleXmlProcessor().getOriginalDoc(),
+ XPathConstants.STRING);
+ }
+
+ /**
+ * Method to populate clause UUID and displayName.
+ *
+ * @param me - MeasureExport
+ * @throws XPathExpressionException - {@link Exception}
+ */
+ private void generateClauseLogicMap(MeasureExport me) throws XPathExpressionException {
+ String xPath = "/measure/subTreeLookUp/subTree";
+ NodeList subTreeNodeList =
+ me.getSimpleXmlProcessor().findNodeList(me.getSimpleXmlProcessor().getOriginalDoc(), xPath);
+ for (int i = 0; i < subTreeNodeList.getLength(); i++) {
+ String uuid = subTreeNodeList.item(i).getAttributes().getNamedItem(UUID).getNodeValue();
+ Node firstChildNode = subTreeNodeList.item(i).getFirstChild();
+ if (firstChildNode != null) {
+ clauseLogicMap.put(uuid, firstChildNode);
+ }
+ }
+ }
+
+ /**
+ * Method to populate all measure groupings in measureGroupingMap.
+ *
+ * @param me - MeasureExport
+ * @throws XPathExpressionException - {@link Exception}
+ */
+ private void getAllMeasureGroupings(MeasureExport me) throws XPathExpressionException {
+ String xPath = "/measure/measureGrouping/group";
+ NodeList measureGroupings =
+ me.getSimpleXmlProcessor().findNodeList(me.getSimpleXmlProcessor().getOriginalDoc(), xPath);
+ for (int i = 0; i < measureGroupings.getLength(); i++) {
+ String measureGroupingSequence =
+ measureGroupings.item(i).getAttributes().getNamedItem("sequence").getNodeValue();
+ NodeList childNodeList = measureGroupings.item(i).getChildNodes();
+ measureGroupingMap.put(Integer.parseInt(measureGroupingSequence), childNodeList);
+ }
+ }
}
diff --git a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFPopulationLogicGenerator.java b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFPopulationLogicGenerator.java
index ebde8a4..6648c4c 100644
--- a/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFPopulationLogicGenerator.java
+++ b/src/main/java/gov/cms/madie/hqmf/qdm_5_6/HQMFPopulationLogicGenerator.java
@@ -24,611 +24,680 @@
// TODO: Auto-generated Javadoc
-/**
- * The Class HQMFPopulationLogicGenerator.
- */
+/** The Class HQMFPopulationLogicGenerator. */
@Slf4j
public class HQMFPopulationLogicGenerator extends HQMFClauseLogicGenerator {
- private Map measureGroupingMap = new TreeMap<>();
-
- /** The scoring type. */
- private String scoringType;
-
- /** The initial population. */
- private Node initialPopulation;
-
- /* (non-Javadoc)
- * @see mat.server.simplexml.hqmf.HQMFClauseLogicGenerator#generate(mat.model.clause.MeasureExport)
- */
- @Override
- public String generate(MeasureExport me) throws Exception {
- /*1. Fetch all Clause Logic HQMF in MAP.
- 2. Fetch all groupings.
- 3. For Each Grouping :
- 1.Generate component tag.
- 2.Generate populationCriteriaSection tag.
- 3.Generate id tag with root and extension as attributes
- 4. Generate code tag with code and codesystem as attributes.
- 5. Generate title tag with value as attribute.
- 6. Generate text tag with value as attribute defining the populations used in current section.
- 7. For each population used :
- 1.Generate component tag as child of populationCriteriaSection with typeCode COMP.
- 2.Generate for ex : initialPopulationCriteria tag for IP with classCode="OBS" moodCode="EVN" as attributes.
- 3.Generate id tag with root and extension as attributes
- 4. Generate code tag with ccodeSystem="2.16.840.1.113883.5.4" codeSystemName="HL7 Observation Value"
- code="IPOP" as attributes.
- 5.Generate displayName as child tag of code with value = name of population as in Simple Xml.
- 6. Generate precondition tag typeCode="PRCN".
- 7. Based on top AND/OR/ANDNOT/ORNOT generate "AllTrue", "AllFalse", "AtLeastOneTrue" tag. Generate id empty tag inside it.
- 8. Generate precondition tag typeCode="PRCN" for all children inside top Logical Op and add criteriaRef to it with id and extension.
- */
- measureExport = me;
- getMeasureScoringType(me);
- getAllMeasureGroupings(me);
- generatePopulationCriteria(me);
- return null;
- }
-
- /**
- * Method to generate population Criteria.
- * @param me - MeasureExport
- * @throws XPathExpressionException - Exception
- */
- private void generatePopulationCriteria(MeasureExport me) throws XPathExpressionException {
- for (Integer key : measureGroupingMap.keySet()) {
- Node populationCriteriaComponentElement = createPopulationCriteriaSection(key.toString() , me.getHqmfXmlProcessor());
- NodeList groupingChildList = measureGroupingMap.get(key).getPackageClauses();
- log.info("measureGroupingMap: {}", measureGroupingMap);
- log.info("groupingChildList: {}", groupingChildList);
-
- for (int i = 0; i < groupingChildList.getLength(); i++) {
- String popType = groupingChildList.item(i).getAttributes().getNamedItem(TYPE).getNodeValue();
- switch(popType) {
- case "initialPopulation" :
- initialPopulation = groupingChildList.item(i);
- generatePopulationTypeCriteria(groupingChildList.item(i)
- , populationCriteriaComponentElement , me
- , "initialPopulationCriteria", "IPOP");
- break;
- case "denominator" :
- if(checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))){
- generatePopulationTypeCriteria(groupingChildList.item(i)
- , populationCriteriaComponentElement , me
- , "denominatorCriteria", "DENOM");
- }
- break;
- case "denominatorExclusions" :
- // top Logical Op is OR
- if(checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))){
- generatePopulationTypeCriteria(groupingChildList.item(i)
- , populationCriteriaComponentElement , me
- , "denominatorExclusionCriteria", "DENEX");
- }
- break;
- case "denominatorExceptions" :
- // top Logical Op is OR
- if(checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))){
- generatePopulationTypeCriteria(groupingChildList.item(i)
- , populationCriteriaComponentElement , me
- , "denominatorExceptionCriteria", "DENEXCEP");
- }
- break;
- case "numerator" :
- if(checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))){
- generatePopulationTypeCriteria(groupingChildList.item(i)
- , populationCriteriaComponentElement , me
- , "numeratorCriteria", "NUMER");
- }
- break;
- case "numeratorExclusions" :
- // top Logical Op is OR
- if(checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))){
- generatePopulationTypeCriteria(groupingChildList.item(i)
- , populationCriteriaComponentElement , me
- , "numeratorExclusionCriteria", "NUMEX");
- }
- break;
- case "measurePopulation" :
- if(checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))){
- generatePopulationTypeCriteria(groupingChildList.item(i)
- , populationCriteriaComponentElement , me
- , "measurePopulationCriteria", "MSRPOPL");
- }
- break;
- case "measurePopulationExclusions" :
- //If measurePopulationExclusions has no logic added
- //then it should not be included in populationCriteria as per Stan.
- if(checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))){
- generatePopulationTypeCriteria(groupingChildList.item(i)
- , populationCriteriaComponentElement , me
- , "measurePopulationExclusionCriteria", "MSRPOPLEX");
- }
- break;
- case "measureObservation" :
- break;
- case "stratum" :
- if(checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))){
- generatePopulationTypeCriteria(groupingChildList.item(i)
- , populationCriteriaComponentElement, me, "stratifierCriteria", "STRAT");
- }
- break;
- default:
- //do nothing.
- break;
- }
- }
- // for creating SupplementalDataElements Criteria Section
- createSupplementalDataElmStratifier(me,populationCriteriaComponentElement.getFirstChild());
- createRiskAdjustmentStratifier(me, populationCriteriaComponentElement.getFirstChild());
- createScoreUnit(me, populationCriteriaComponentElement.getFirstChild(), measureGroupingMap.get(key).getScoreUnit());
- }
- }
-
- private void createScoreUnit(MeasureExport me, Node populationCriteriaSection, String scoreUnit) {
- if (StringUtils.isBlank(scoreUnit)) {
- // No Score Unit provided in measure group
- return;
- }
- Document doc = me.getHqmfXmlProcessor().getOriginalDoc();
-
- Element componentElement = doc.createElement("component");
- componentElement.setAttribute(TYPE_CODE, "COMP");
- Attr qdmNameSpaceAttr = doc.createAttribute("xmlns:cql-ext");
- qdmNameSpaceAttr.setNodeValue("urn:hhs-cql:hqmf-n1-extensions:v1");
- componentElement.setAttributeNodeNS(qdmNameSpaceAttr);
-
- Element scoreUnitElement = doc.createElement("cql-ext:scoreUnit");
- scoreUnitElement.setAttribute("nullFlavor","DER");
- scoreUnitElement.setAttribute("xsi:type","PQ");
-
- Element unit = doc.createElement("unit");
- unit.setAttribute("value", scoreUnit);
-
- scoreUnitElement.appendChild(unit);
- componentElement.appendChild(scoreUnitElement);
- populationCriteriaSection.appendChild(componentElement);
- }
-
- /**
- * Method to generate default criteriaTag for all population types included in measure grouping.
- * @param item - Node
- * @param populationCriteriaComponentElement - Element
- * @param me - MeasureExport
- * @param criteriaTagName - String.
- * @param criteriaTagCodeName - String code value.
- * @throws XPathExpressionException - Exception
- */
- private void generatePopulationTypeCriteria(Node item, Node populationCriteriaComponentElement
- , MeasureExport me, String criteriaTagName, String criteriaTagCodeName) throws XPathExpressionException {
- String idExtension;
- /*String displayValue = "";*/
- Document doc = populationCriteriaComponentElement.getOwnerDocument();
- Element populationCriteriaElement = (Element) populationCriteriaComponentElement.getFirstChild();
- Element componentElement = doc.createElement("component");
- componentElement.setAttribute(TYPE_CODE, "COMP");
- Element initialPopCriteriaElement = doc.createElement(criteriaTagName);
-
- if(criteriaTagName.equalsIgnoreCase("stratifierCriteria")){
- idExtension = "Stratifiers";
- // displayValue = "Stratification";
- } else {
- initialPopCriteriaElement.setAttribute(CLASS_CODE, "OBS");
- initialPopCriteriaElement.setAttribute(MOOD_CODE, "EVN");
- idExtension = StringUtils.deleteWhitespace(item.getAttributes().getNamedItem(TYPE).getNodeValue());
- //displayValue = item.getAttributes().getNamedItem(TYPE).getNodeValue();
- }
- Element idElement = doc.createElement(ID);
- idElement.setAttribute(ROOT, item.getAttributes().getNamedItem(UUID).getNodeValue());
- idElement.setAttribute("extension", idExtension);
- initialPopCriteriaElement.appendChild(idElement);
- Element codeElem = doc.createElement(CODE);
- codeElem.setAttribute(CODE, criteriaTagCodeName);
- codeElem.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.5.4");
- codeElem.setAttribute(CODE_SYSTEM_NAME, "Act Code");
- // displayName inside not needed for populations as per stan
- /* Element displayNameElement = doc.createElement(DISPLAY_NAME);
- displayNameElement.setAttribute(VALUE, displayValue);
- codeElem.appendChild(displayNameElement);*/
- initialPopCriteriaElement.appendChild(codeElem);
- /*Element preConditionElem = doc.createElement("precondition");
- preConditionElem.setAttribute(TYPE_CODE, "PRCN");*/
- if (item.getChildNodes() != null) {
- for(int i=0;i getRequiredClauses(String type){
- List list = new ArrayList<>();
- if("Cohort".equalsIgnoreCase(type)){
- list.add("initialPopulation");
- }else if("Continuous Variable".equalsIgnoreCase(type)){
- list.add("initialPopulation");
- list.add("measurePopulation");
- list.add("measureObservation");
- }else if("Proportion".equalsIgnoreCase(type) ||
- "Ratio".equalsIgnoreCase(type)){
- list.add("initialPopulation");
- list.add("denominator");
- list.add("numerator");
- }
- return list;
- }
-
- /**
- * Check for required clause by scoring.
- *
- * @param me the me
- * @param popType the pop type
- * @param node the node
- * @return true, if successful
- * @throws XPathExpressionException the x path expression exception
- */
- private static boolean checkForRequiredClauseByScoring(MeasureExport me, String popType, Node node) throws XPathExpressionException{
- boolean isRequiredClause = false;
- Node scoringType = me.getSimpleXmlProcessor().findNode(me.getSimpleXmlProcessor().getOriginalDoc(),
- "/measure/measureDetails/scoring");
- List clauseList = new ArrayList<>();
- clauseList = getRequiredClauses(scoringType.getTextContent());
- if(clauseList.contains(popType)){
- isRequiredClause = true;
- } else {
- isRequiredClause = checkForPackageClauseLogic(node, popType);
- }
- return isRequiredClause;
- }
-
- /**
- * Check for package clause logic.
- *
- * @param node the node
- * @param popType the pop type
- * @return true, if successful
- */
- private static boolean checkForPackageClauseLogic(Node node,
- String popType) {
- switch(popType) {
-
- case "measurePopulation":
- case "numerator":
- case "denominator":
- case "denominatorExclusions":
- case "numeratorExclusions":
- case "measureObservation":
- case "stratum":
- case "denominatorExceptions":
- case "measurePopulationExclusions":
- if(node.hasChildNodes()) {
- return true;
- }
- break;
-
- default: //do Nothing
- break;
-
- }
- return false;
- }
-
- /**
- * Create the risk adjustment components. This will create a create a component tag underneath
- * population critiera section for risk adjustment variables.
- * @param me the measure export
- * @param parentNode the parent node
- * @throws XPathExpressionException
- */
- private void createRiskAdjustmentStratifier(MeasureExport me, Node parentNode) throws XPathExpressionException {
-
- String xPathForRiskAdjustmentVariables = "/measure/riskAdjustmentVariables/cqldefinition";
- XmlProcessor simpleXmlProcessor = me.getSimpleXmlProcessor();
- NodeList riskAdjustmentVariables = simpleXmlProcessor.findNodeList(simpleXmlProcessor.getOriginalDoc(),
- xPathForRiskAdjustmentVariables);
- String xPathForLibraryName = "/measure/cqlLookUp/library";
- Node libraryNode = simpleXmlProcessor.findNode(simpleXmlProcessor.getOriginalDoc(), xPathForLibraryName);
- String libraryName = libraryNode.getTextContent();
-
- String xPathForCQLUUID = "/measure/measureDetails/cqlUUID";
- Node cqluuidNode = simpleXmlProcessor.findNode(simpleXmlProcessor.getOriginalDoc(), xPathForCQLUUID);
- String cqlUUID = cqluuidNode.getTextContent();
-
- for (int i = 0; i < riskAdjustmentVariables.getLength(); i++) {
- Node current = riskAdjustmentVariables.item(i);
- String riskAdjustmentDefName = current.getAttributes().getNamedItem("displayName").getNodeValue();
-
- Element component = createRiskAdjustmentComponentNode(me, cqlUUID, libraryName, riskAdjustmentDefName, "MSRADJ");
- parentNode.appendChild(component);
- }
- }
-
- /**
- * Creates the component for a risk adjustment variable in the hqmf document
- * @param me the measure export
- * @param cqlUUID the cql file uuid
- * @param libraryName the cql library name
- * @param riskAdjustmentDefName the risk adjustment definition name
- * @return the component element
- */
- private Element createRiskAdjustmentComponentNode(MeasureExport me, String cqlUUID, String libraryName, String riskAdjustmentDefName, String type) {
- XmlProcessor processor = me.getHqmfXmlProcessor();
-
- Element component = processor.getOriginalDoc().createElement("component");
- component.setAttribute(TYPE_CODE, "COMP");
-
- Attr qdmNameSpaceAttr = processor.getOriginalDoc().createAttribute("xmlns:cql-ext");
- qdmNameSpaceAttr.setNodeValue("urn:hhs-cql:hqmf-n1-extensions:v1");
- component.setAttributeNodeNS(qdmNameSpaceAttr);
-
- Element stratifierCriteria = processor.getOriginalDoc().createElement("cql-ext:supplementalDataElement");
-
- String extensionStr = "";
- String codeStr = "";
- if(type.equalsIgnoreCase("MSRADJ")){
- extensionStr = "Risk Adjustment Variables";
- codeStr = "MSRADJ";
- } else {
- extensionStr = "Supplemental Data Elements";
- codeStr = "SDE";
- }
-
- Element id = processor.getOriginalDoc().createElement("id");
- id.setAttribute("extension", extensionStr);
- id.setAttribute("root", java.util.UUID.randomUUID().toString());
- stratifierCriteria.appendChild(id);
-
- Element code = processor.getOriginalDoc().createElement("code");
- code.setAttribute("code", codeStr);
- code.setAttribute("codeSystem", "2.16.840.1.113883.5.4");
- code.setAttribute("codeSystemName", "Act Code");
- stratifierCriteria.appendChild(code);
-
- Element precondition = processor.getOriginalDoc().createElement("precondition");
- precondition.setAttribute("typeCode", "PRCN");
- stratifierCriteria.appendChild(precondition);
-
- Element criteriaReference = processor.getOriginalDoc().createElement("criteriaReference");
- criteriaReference.setAttribute("moodCode", "EVN");
- criteriaReference.setAttribute("classCode", "OBS");
- precondition.appendChild(criteriaReference);
-
- Element criteriaReferenceId = processor.getOriginalDoc().createElement("id");
- criteriaReferenceId.setAttribute("root", cqlUUID);
- String extensionString = String.format("%s.\"%s\"", libraryName, riskAdjustmentDefName);
- criteriaReferenceId.setAttribute("extension", extensionString);
- criteriaReference.appendChild(criteriaReferenceId);
- component.appendChild(stratifierCriteria);
-
- return component;
-
- }
- /**
- * Creates Logic for Each Supplemental Data Element Nodes.
- *
- * @param me the me
- * @param parentNode - PopulationCriteria First Child Node.
- * @throws XPathExpressionException the x path expression exception
- */
- private void createSupplementalDataElmStratifier(MeasureExport me, Node parentNode) throws XPathExpressionException {
- String xpathForOtherSupplementalQDMs = "/measure/supplementalDataElements/cqldefinition/@uuid";
- NodeList supplementalDataElements = me.getSimpleXmlProcessor().findNodeList(me.getSimpleXmlProcessor().getOriginalDoc(),
- xpathForOtherSupplementalQDMs);
- String xPathForLibraryName = "/measure/cqlLookUp/library";
- Node libraryNode = me.getSimpleXmlProcessor().findNode(me.getSimpleXmlProcessor().getOriginalDoc(), xPathForLibraryName);
- String libraryName = libraryNode.getTextContent();
-
- String xPathForCQLUUID = "/measure/measureDetails/cqlUUID";
- Node cqluuidNode = me.getSimpleXmlProcessor().findNode(me.getSimpleXmlProcessor().getOriginalDoc(), xPathForCQLUUID);
- String cqlUUID = cqluuidNode.getTextContent();
-
-
- if (supplementalDataElements == null || supplementalDataElements.getLength() < 1) {
- return;
- }
- List supplementalElementRefIds = new ArrayList<>();
- for (int i = 0; i < supplementalDataElements.getLength(); i++) {
- supplementalElementRefIds.add(supplementalDataElements.item(i).getNodeValue());
- }
-
- StringBuilder uuidXPathString = new StringBuilder();
- for (String uuidString: supplementalElementRefIds) {
- uuidXPathString.append("@id = '").append(uuidString).append("' or ");
- }
- uuidXPathString = new StringBuilder(uuidXPathString.substring(0, uuidXPathString.lastIndexOf(" or ")));
- String xpathforOtherSupplementalDataElements = "/measure/cqlLookUp/definitions/definition[" + uuidXPathString + "]";
- NodeList supplementalQDMNodeList = me.getSimpleXmlProcessor().findNodeList(me.getSimpleXmlProcessor().getOriginalDoc(),
- xpathforOtherSupplementalDataElements);
- if (supplementalQDMNodeList.getLength() < 1) {
- return;
- }
-
- for (int i = 0; i < supplementalQDMNodeList.getLength(); i++) {
- Node qdmNode = supplementalQDMNodeList.item(i);
- String qdmName = qdmNode.getAttributes().getNamedItem("name").getNodeValue();
-
- //createRiskAdjustmentComponentNode is good enough for this too.
- Element componentElement = createRiskAdjustmentComponentNode(me, cqlUUID, libraryName, qdmName, "SDE");
- parentNode.appendChild(componentElement);
- }
-
- }
-
- @Data
- @Builder
- static class MeasureGroup {
- private NodeList packageClauses;
- private String scoreUnit;
- private int sequence;
- }
+ private Map measureGroupingMap = new TreeMap<>();
+
+ /** The scoring type. */
+ private String scoringType;
+
+ /** The initial population. */
+ private Node initialPopulation;
+
+ /* (non-Javadoc)
+ * @see mat.server.simplexml.hqmf.HQMFClauseLogicGenerator#generate(mat.model.clause.MeasureExport)
+ */
+ @Override
+ public String generate(MeasureExport me) throws Exception {
+ /*1. Fetch all Clause Logic HQMF in MAP.
+ 2. Fetch all groupings.
+ 3. For Each Grouping :
+ 1.Generate component tag.
+ 2.Generate populationCriteriaSection tag.
+ 3.Generate id tag with root and extension as attributes
+ 4. Generate code tag with code and codesystem as attributes.
+ 5. Generate title tag with value as attribute.
+ 6. Generate text tag with value as attribute defining the populations used in current section.
+ 7. For each population used :
+ 1.Generate component tag as child of populationCriteriaSection with typeCode COMP.
+ 2.Generate for ex : initialPopulationCriteria tag for IP with classCode="OBS" moodCode="EVN" as attributes.
+ 3.Generate id tag with root and extension as attributes
+ 4. Generate code tag with ccodeSystem="2.16.840.1.113883.5.4" codeSystemName="HL7 Observation Value"
+ code="IPOP" as attributes.
+ 5.Generate displayName as child tag of code with value = name of population as in Simple Xml.
+ 6. Generate precondition tag typeCode="PRCN".
+ 7. Based on top AND/OR/ANDNOT/ORNOT generate "AllTrue", "AllFalse", "AtLeastOneTrue" tag. Generate id empty tag inside it.
+ 8. Generate precondition tag typeCode="PRCN" for all children inside top Logical Op and add criteriaRef to it with id and extension.
+ */
+ measureExport = me;
+ getMeasureScoringType(me);
+ getAllMeasureGroupings(me);
+ generatePopulationCriteria(me);
+ return null;
+ }
+
+ /**
+ * Method to generate population Criteria.
+ *
+ * @param me - MeasureExport
+ * @throws XPathExpressionException - Exception
+ */
+ private void generatePopulationCriteria(MeasureExport me) throws XPathExpressionException {
+ for (Integer key : measureGroupingMap.keySet()) {
+ Node populationCriteriaComponentElement =
+ createPopulationCriteriaSection(key.toString(), me.getHqmfXmlProcessor());
+ NodeList groupingChildList = measureGroupingMap.get(key).getPackageClauses();
+ log.info("measureGroupingMap: {}", measureGroupingMap);
+ log.info("groupingChildList: {}", groupingChildList);
+
+ for (int i = 0; i < groupingChildList.getLength(); i++) {
+ String popType =
+ groupingChildList.item(i).getAttributes().getNamedItem(TYPE).getNodeValue();
+ switch (popType) {
+ case "initialPopulation":
+ initialPopulation = groupingChildList.item(i);
+ generatePopulationTypeCriteria(
+ groupingChildList.item(i),
+ populationCriteriaComponentElement,
+ me,
+ "initialPopulationCriteria",
+ "IPOP");
+ break;
+ case "denominator":
+ if (checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))) {
+ generatePopulationTypeCriteria(
+ groupingChildList.item(i),
+ populationCriteriaComponentElement,
+ me,
+ "denominatorCriteria",
+ "DENOM");
+ }
+ break;
+ case "denominatorExclusions":
+ // top Logical Op is OR
+ if (checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))) {
+ generatePopulationTypeCriteria(
+ groupingChildList.item(i),
+ populationCriteriaComponentElement,
+ me,
+ "denominatorExclusionCriteria",
+ "DENEX");
+ }
+ break;
+ case "denominatorExceptions":
+ // top Logical Op is OR
+ if (checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))) {
+ generatePopulationTypeCriteria(
+ groupingChildList.item(i),
+ populationCriteriaComponentElement,
+ me,
+ "denominatorExceptionCriteria",
+ "DENEXCEP");
+ }
+ break;
+ case "numerator":
+ if (checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))) {
+ generatePopulationTypeCriteria(
+ groupingChildList.item(i),
+ populationCriteriaComponentElement,
+ me,
+ "numeratorCriteria",
+ "NUMER");
+ }
+ break;
+ case "numeratorExclusions":
+ // top Logical Op is OR
+ if (checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))) {
+ generatePopulationTypeCriteria(
+ groupingChildList.item(i),
+ populationCriteriaComponentElement,
+ me,
+ "numeratorExclusionCriteria",
+ "NUMEX");
+ }
+ break;
+ case "measurePopulation":
+ if (checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))) {
+ generatePopulationTypeCriteria(
+ groupingChildList.item(i),
+ populationCriteriaComponentElement,
+ me,
+ "measurePopulationCriteria",
+ "MSRPOPL");
+ }
+ break;
+ case "measurePopulationExclusions":
+ // If measurePopulationExclusions has no logic added
+ // then it should not be included in populationCriteria as per Stan.
+ if (checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))) {
+ generatePopulationTypeCriteria(
+ groupingChildList.item(i),
+ populationCriteriaComponentElement,
+ me,
+ "measurePopulationExclusionCriteria",
+ "MSRPOPLEX");
+ }
+ break;
+ case "measureObservation":
+ break;
+ case "stratum":
+ if (checkForRequiredClauseByScoring(me, popType, groupingChildList.item(i))) {
+ generatePopulationTypeCriteria(
+ groupingChildList.item(i),
+ populationCriteriaComponentElement,
+ me,
+ "stratifierCriteria",
+ "STRAT");
+ }
+ break;
+ default:
+ // do nothing.
+ break;
+ }
+ }
+ // for creating SupplementalDataElements Criteria Section
+ createSupplementalDataElmStratifier(me, populationCriteriaComponentElement.getFirstChild());
+ createRiskAdjustmentStratifier(me, populationCriteriaComponentElement.getFirstChild());
+ createScoreUnit(
+ me,
+ populationCriteriaComponentElement.getFirstChild(),
+ measureGroupingMap.get(key).getScoreUnit());
+ }
+ }
+
+ private void createScoreUnit(MeasureExport me, Node populationCriteriaSection, String scoreUnit) {
+ if (StringUtils.isBlank(scoreUnit)) {
+ // No Score Unit provided in measure group
+ return;
+ }
+ Document doc = me.getHqmfXmlProcessor().getOriginalDoc();
+
+ Element componentElement = doc.createElement("component");
+ componentElement.setAttribute(TYPE_CODE, "COMP");
+ Attr qdmNameSpaceAttr = doc.createAttribute("xmlns:cql-ext");
+ qdmNameSpaceAttr.setNodeValue("urn:hhs-cql:hqmf-n1-extensions:v1");
+ componentElement.setAttributeNodeNS(qdmNameSpaceAttr);
+
+ Element scoreUnitElement = doc.createElement("cql-ext:scoreUnit");
+ scoreUnitElement.setAttribute("nullFlavor", "DER");
+ scoreUnitElement.setAttribute("xsi:type", "PQ");
+
+ Element unit = doc.createElement("unit");
+ unit.setAttribute("value", scoreUnit);
+
+ scoreUnitElement.appendChild(unit);
+ componentElement.appendChild(scoreUnitElement);
+ populationCriteriaSection.appendChild(componentElement);
+ }
+
+ /**
+ * Method to generate default criteriaTag for all population types included in measure grouping.
+ *
+ * @param item - Node
+ * @param populationCriteriaComponentElement - Element
+ * @param me - MeasureExport
+ * @param criteriaTagName - String.
+ * @param criteriaTagCodeName - String code value.
+ * @throws XPathExpressionException - Exception
+ */
+ private void generatePopulationTypeCriteria(
+ Node item,
+ Node populationCriteriaComponentElement,
+ MeasureExport me,
+ String criteriaTagName,
+ String criteriaTagCodeName)
+ throws XPathExpressionException {
+ String idExtension;
+ /*String displayValue = "";*/
+ Document doc = populationCriteriaComponentElement.getOwnerDocument();
+ Element populationCriteriaElement =
+ (Element) populationCriteriaComponentElement.getFirstChild();
+ Element componentElement = doc.createElement("component");
+ componentElement.setAttribute(TYPE_CODE, "COMP");
+ Element initialPopCriteriaElement = doc.createElement(criteriaTagName);
+
+ if (criteriaTagName.equalsIgnoreCase("stratifierCriteria")) {
+ idExtension = "Stratifiers";
+ // displayValue = "Stratification";
+ } else {
+ initialPopCriteriaElement.setAttribute(CLASS_CODE, "OBS");
+ initialPopCriteriaElement.setAttribute(MOOD_CODE, "EVN");
+ idExtension =
+ StringUtils.deleteWhitespace(item.getAttributes().getNamedItem(TYPE).getNodeValue());
+ // displayValue = item.getAttributes().getNamedItem(TYPE).getNodeValue();
+ }
+ Element idElement = doc.createElement(ID);
+ idElement.setAttribute(ROOT, item.getAttributes().getNamedItem(UUID).getNodeValue());
+ idElement.setAttribute("extension", idExtension);
+ initialPopCriteriaElement.appendChild(idElement);
+ Element codeElem = doc.createElement(CODE);
+ codeElem.setAttribute(CODE, criteriaTagCodeName);
+ codeElem.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.5.4");
+ codeElem.setAttribute(CODE_SYSTEM_NAME, "Act Code");
+ // displayName inside not needed for populations as per stan
+ /* Element displayNameElement = doc.createElement(DISPLAY_NAME);
+ displayNameElement.setAttribute(VALUE, displayValue);
+ codeElem.appendChild(displayNameElement);*/
+ initialPopCriteriaElement.appendChild(codeElem);
+ /*Element preConditionElem = doc.createElement("precondition");
+ preConditionElem.setAttribute(TYPE_CODE, "PRCN");*/
+ if (item.getChildNodes() != null) {
+ for (int i = 0; i < item.getChildNodes().getLength(); i++) {
+ generatePopulationLogic(initialPopCriteriaElement, item.getChildNodes().item(i), me);
+ }
+ }
+ checkScoringTypeToAssociateIP(initialPopCriteriaElement, item);
+ /*initialPopCriteriaElement.appendChild(preConditionElem);*/
+ componentElement.appendChild(initialPopCriteriaElement);
+ populationCriteriaElement.appendChild(componentElement);
+ }
+
+ /**
+ * Associate IP with Deno in Proportion Measures, With MeasurePopulation In Continous Variable and
+ * based on association in Ratio Measures with Deno and NUm.
+ *
+ * @param populationCritieriaElem the pre condition elem
+ * @param item the item
+ */
+ private void checkScoringTypeToAssociateIP(Element populationCritieriaElem, Node item) {
+ String nodeType = item.getAttributes().getNamedItem(TYPE).getNodeValue();
+ Document mainDocument = populationCritieriaElem.getOwnerDocument();
+ Element preConditionElem = mainDocument.createElement("subject");
+ preConditionElem.setAttribute(TYPE_CODE, "SUBJ");
+
+ if (scoringType.equalsIgnoreCase("Ratio")
+ && (nodeType.equalsIgnoreCase("denominator") || nodeType.equalsIgnoreCase("numerator"))) {
+
+ String associatedIPUUID = initialPopulation.getAttributes().getNamedItem(UUID).getNodeValue();
+
+ if (item.getAttributes().getNamedItem("associatedPopulationUUID") != null) {
+ associatedIPUUID =
+ item.getAttributes().getNamedItem("associatedPopulationUUID").getNodeValue();
+ }
+ Element criteriaRef = mainDocument.createElement("criteriaReference");
+ criteriaRef.setAttribute(CLASS_CODE, "OBS");
+ criteriaRef.setAttribute(MOOD_CODE, "EVN");
+ Element idElement = mainDocument.createElement(ID);
+ idElement.setAttribute(ROOT, associatedIPUUID);
+ idElement.setAttribute("extension", StringUtils.deleteWhitespace("initialPopulation"));
+ criteriaRef.appendChild(idElement);
+ preConditionElem.appendChild(criteriaRef);
+ populationCritieriaElem.appendChild(preConditionElem);
+ }
+ }
+
+ /**
+ * Method to generate tags for logic used inside population.
+ *
+ * @param populationTypeCriteriaElement - Element.
+ * @param me - MeasureExport.
+ * @throws XPathExpressionException - Exception.
+ */
+ private void generatePopulationLogic(
+ Element populationTypeCriteriaElement, Node childNode, MeasureExport me)
+ throws XPathExpressionException {
+
+ String nodeType;
+ if (childNode.getAttributes().getNamedItem(TYPE) != null) {
+ nodeType = childNode.getAttributes().getNamedItem(TYPE).getNodeValue();
+ } else {
+ nodeType = childNode.getNodeName();
+ }
+ Element preConditionElement =
+ populationTypeCriteriaElement.getOwnerDocument().createElement("precondition");
+ preConditionElement.setAttribute(TYPE_CODE, "PRCN");
+ switch (nodeType) {
+ case "cqldefinition":
+ generateCritRefCQLDefine(preConditionElement, childNode, me.getHqmfXmlProcessor());
+ break;
+ case "comment":
+ // skipping comment node as of now.
+ break;
+ case "cqlfunction":
+ break;
+
+ default:
+ break;
+ }
+ if (preConditionElement.hasChildNodes()) {
+ populationTypeCriteriaElement.appendChild(preConditionElement);
+ }
+ }
+
+ /**
+ * Method to generate component and populationCriteria default tags.
+ *
+ * @param sequenceNumber - Measure Grouping sequence number.
+ * @param outputProcessor - XmlProcessor.
+ * @return - Node.
+ */
+ private Node createPopulationCriteriaSection(
+ String sequenceNumber, XmlProcessor outputProcessor) {
+ Element componentElement = outputProcessor.getOriginalDoc().createElement("component");
+ Attr nameSpaceAttr = outputProcessor.getOriginalDoc().createAttribute("xmlns:xsi");
+ nameSpaceAttr.setNodeValue(nameSpace);
+ componentElement.setAttributeNodeNS(nameSpaceAttr);
+ Node popCriteriaElem =
+ outputProcessor.getOriginalDoc().createElement("populationCriteriaSection");
+ Element templateId = outputProcessor.getOriginalDoc().createElement(TEMPLATE_ID);
+ popCriteriaElem.appendChild(templateId);
+ Element itemChild = outputProcessor.getOriginalDoc().createElement(ITEM);
+ itemChild.setAttribute(ROOT, "2.16.840.1.113883.10.20.28.2.7");
+ itemChild.setAttribute("extension", POPULATION_CRITERIA_EXTENSION_CQL);
+ templateId.appendChild(itemChild);
+ Element idElement = outputProcessor.getOriginalDoc().createElement(ID);
+ idElement.setAttribute(ROOT, java.util.UUID.randomUUID().toString());
+ idElement.setAttribute("extension", "PopulationCriteria" + sequenceNumber);
+ popCriteriaElem.appendChild(idElement);
+ Element codeElem = outputProcessor.getOriginalDoc().createElement(CODE);
+ codeElem.setAttribute(CODE, "57026-7");
+ codeElem.setAttribute(CODE_SYSTEM, "2.16.840.1.113883.6.1");
+ popCriteriaElem.appendChild(codeElem);
+ Element titleElem = outputProcessor.getOriginalDoc().createElement(TITLE);
+ titleElem.setAttribute(VALUE, "Population Criteria Section");
+ popCriteriaElem.appendChild(titleElem);
+ // creating text for PopulationCriteria
+ Element textElem = outputProcessor.getOriginalDoc().createElement("text");
+ // textElem.setAttribute(VALUE, "Population Criteria text");
+ popCriteriaElem.appendChild(textElem);
+ componentElement.appendChild(popCriteriaElem);
+ outputProcessor.getOriginalDoc().getDocumentElement().appendChild(componentElement);
+ return componentElement;
+ }
+
+ /**
+ * Get Measure Scoring type.
+ *
+ * @param me - MeasureExport
+ * @return the measure scoring type
+ * @throws XPathExpressionException - {@link Exception}
+ */
+ private void getMeasureScoringType(MeasureExport me) throws XPathExpressionException {
+ String xPathScoringType = "/measure/measureDetails/scoring/text()";
+ javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
+
+ scoringType =
+ (String)
+ xPath.evaluate(
+ xPathScoringType,
+ me.getSimpleXmlProcessor().getOriginalDoc(),
+ XPathConstants.STRING);
+ }
+
+ /**
+ * Method to populate all measure groupings in measureGroupingMap.
+ *
+ * @param me - MeasureExport
+ * @return the all measure groupings
+ * @throws XPathExpressionException - {@link Exception}
+ */
+ private void getAllMeasureGroupings(MeasureExport me) throws XPathExpressionException {
+ String xPath = "/measure/measureGrouping/group";
+ NodeList measureGroupings =
+ me.getSimpleXmlProcessor().findNodeList(me.getSimpleXmlProcessor().getOriginalDoc(), xPath);
+ for (int i = 0; i < measureGroupings.getLength(); i++) {
+ int measureGroupingSequence =
+ Integer.parseInt(
+ measureGroupings.item(i).getAttributes().getNamedItem("sequence").getNodeValue());
+ Node measureGroupNode = measureGroupings.item(i);
+ // Added to remove text nodes with only newlines that make later processing blow up
+ XmlProcessor.clean(measureGroupNode);
+
+ MeasureGroup measureGroup =
+ MeasureGroup.builder()
+ .sequence(measureGroupingSequence)
+ .packageClauses(measureGroupNode.getChildNodes())
+ .build();
+
+ Node ucum = measureGroupings.item(i).getAttributes().getNamedItem("ucum");
+ if (ucum != null && isNotBlank(ucum.getNodeValue().strip())) {
+ measureGroup.setScoreUnit(ucum.getNodeValue().strip());
+ }
+
+ measureGroupingMap.put(measureGroupingSequence, measureGroup);
+ }
+ }
+
+ /**
+ * Gets the required clauses.
+ *
+ * @param type the type
+ * @return the required clauses
+ */
+ private static List getRequiredClauses(String type) {
+ List list = new ArrayList<>();
+ if ("Cohort".equalsIgnoreCase(type)) {
+ list.add("initialPopulation");
+ } else if ("Continuous Variable".equalsIgnoreCase(type)) {
+ list.add("initialPopulation");
+ list.add("measurePopulation");
+ list.add("measureObservation");
+ } else if ("Proportion".equalsIgnoreCase(type) || "Ratio".equalsIgnoreCase(type)) {
+ list.add("initialPopulation");
+ list.add("denominator");
+ list.add("numerator");
+ }
+ return list;
+ }
+
+ /**
+ * Check for required clause by scoring.
+ *
+ * @param me the me
+ * @param popType the pop type
+ * @param node the node
+ * @return true, if successful
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private static boolean checkForRequiredClauseByScoring(
+ MeasureExport me, String popType, Node node) throws XPathExpressionException {
+ boolean isRequiredClause = false;
+ Node scoringType =
+ me.getSimpleXmlProcessor()
+ .findNode(
+ me.getSimpleXmlProcessor().getOriginalDoc(), "/measure/measureDetails/scoring");
+ List clauseList = new ArrayList<>();
+ clauseList = getRequiredClauses(scoringType.getTextContent());
+ if (clauseList.contains(popType)) {
+ isRequiredClause = true;
+ } else {
+ isRequiredClause = checkForPackageClauseLogic(node, popType);
+ }
+ return isRequiredClause;
+ }
+
+ /**
+ * Check for package clause logic.
+ *
+ * @param node the node
+ * @param popType the pop type
+ * @return true, if successful
+ */
+ private static boolean checkForPackageClauseLogic(Node node, String popType) {
+ switch (popType) {
+ case "measurePopulation":
+ case "numerator":
+ case "denominator":
+ case "denominatorExclusions":
+ case "numeratorExclusions":
+ case "measureObservation":
+ case "stratum":
+ case "denominatorExceptions":
+ case "measurePopulationExclusions":
+ if (node.hasChildNodes()) {
+ return true;
+ }
+ break;
+
+ default: // do Nothing
+ break;
+ }
+ return false;
+ }
+
+ /**
+ * Create the risk adjustment components. This will create a create a component tag underneath
+ * population critiera section for risk adjustment variables.
+ *
+ * @param me the measure export
+ * @param parentNode the parent node
+ * @throws XPathExpressionException
+ */
+ private void createRiskAdjustmentStratifier(MeasureExport me, Node parentNode)
+ throws XPathExpressionException {
+
+ String xPathForRiskAdjustmentVariables = "/measure/riskAdjustmentVariables/cqldefinition";
+ XmlProcessor simpleXmlProcessor = me.getSimpleXmlProcessor();
+ NodeList riskAdjustmentVariables =
+ simpleXmlProcessor.findNodeList(
+ simpleXmlProcessor.getOriginalDoc(), xPathForRiskAdjustmentVariables);
+ String xPathForLibraryName = "/measure/cqlLookUp/library";
+ Node libraryNode =
+ simpleXmlProcessor.findNode(simpleXmlProcessor.getOriginalDoc(), xPathForLibraryName);
+ String libraryName = libraryNode.getTextContent();
+
+ String xPathForCQLUUID = "/measure/measureDetails/cqlUUID";
+ Node cqluuidNode =
+ simpleXmlProcessor.findNode(simpleXmlProcessor.getOriginalDoc(), xPathForCQLUUID);
+ String cqlUUID = cqluuidNode.getTextContent();
+
+ for (int i = 0; i < riskAdjustmentVariables.getLength(); i++) {
+ Node current = riskAdjustmentVariables.item(i);
+ String riskAdjustmentDefName =
+ current.getAttributes().getNamedItem("displayName").getNodeValue();
+
+ Element component =
+ createRiskAdjustmentComponentNode(
+ me, cqlUUID, libraryName, riskAdjustmentDefName, "MSRADJ");
+ parentNode.appendChild(component);
+ }
+ }
+
+ /**
+ * Creates the component for a risk adjustment variable in the hqmf document
+ *
+ * @param me the measure export
+ * @param cqlUUID the cql file uuid
+ * @param libraryName the cql library name
+ * @param riskAdjustmentDefName the risk adjustment definition name
+ * @return the component element
+ */
+ private Element createRiskAdjustmentComponentNode(
+ MeasureExport me,
+ String cqlUUID,
+ String libraryName,
+ String riskAdjustmentDefName,
+ String type) {
+ XmlProcessor processor = me.getHqmfXmlProcessor();
+
+ Element component = processor.getOriginalDoc().createElement("component");
+ component.setAttribute(TYPE_CODE, "COMP");
+
+ Attr qdmNameSpaceAttr = processor.getOriginalDoc().createAttribute("xmlns:cql-ext");
+ qdmNameSpaceAttr.setNodeValue("urn:hhs-cql:hqmf-n1-extensions:v1");
+ component.setAttributeNodeNS(qdmNameSpaceAttr);
+
+ Element stratifierCriteria =
+ processor.getOriginalDoc().createElement("cql-ext:supplementalDataElement");
+
+ String extensionStr = "";
+ String codeStr = "";
+ if (type.equalsIgnoreCase("MSRADJ")) {
+ extensionStr = "Risk Adjustment Variables";
+ codeStr = "MSRADJ";
+ } else {
+ extensionStr = "Supplemental Data Elements";
+ codeStr = "SDE";
+ }
+
+ Element id = processor.getOriginalDoc().createElement("id");
+ id.setAttribute("extension", extensionStr);
+ id.setAttribute("root", java.util.UUID.randomUUID().toString());
+ stratifierCriteria.appendChild(id);
+
+ Element code = processor.getOriginalDoc().createElement("code");
+ code.setAttribute("code", codeStr);
+ code.setAttribute("codeSystem", "2.16.840.1.113883.5.4");
+ code.setAttribute("codeSystemName", "Act Code");
+ stratifierCriteria.appendChild(code);
+
+ Element precondition = processor.getOriginalDoc().createElement("precondition");
+ precondition.setAttribute("typeCode", "PRCN");
+ stratifierCriteria.appendChild(precondition);
+
+ Element criteriaReference = processor.getOriginalDoc().createElement("criteriaReference");
+ criteriaReference.setAttribute("moodCode", "EVN");
+ criteriaReference.setAttribute("classCode", "OBS");
+ precondition.appendChild(criteriaReference);
+
+ Element criteriaReferenceId = processor.getOriginalDoc().createElement("id");
+ criteriaReferenceId.setAttribute("root", cqlUUID);
+ String extensionString = String.format("%s.\"%s\"", libraryName, riskAdjustmentDefName);
+ criteriaReferenceId.setAttribute("extension", extensionString);
+ criteriaReference.appendChild(criteriaReferenceId);
+ component.appendChild(stratifierCriteria);
+
+ return component;
+ }
+
+ /**
+ * Creates Logic for Each Supplemental Data Element Nodes.
+ *
+ * @param me the me
+ * @param parentNode - PopulationCriteria First Child Node.
+ * @throws XPathExpressionException the x path expression exception
+ */
+ private void createSupplementalDataElmStratifier(MeasureExport me, Node parentNode)
+ throws XPathExpressionException {
+ String xpathForOtherSupplementalQDMs = "/measure/supplementalDataElements/cqldefinition/@uuid";
+ NodeList supplementalDataElements =
+ me.getSimpleXmlProcessor()
+ .findNodeList(
+ me.getSimpleXmlProcessor().getOriginalDoc(), xpathForOtherSupplementalQDMs);
+ String xPathForLibraryName = "/measure/cqlLookUp/library";
+ Node libraryNode =
+ me.getSimpleXmlProcessor()
+ .findNode(me.getSimpleXmlProcessor().getOriginalDoc(), xPathForLibraryName);
+ String libraryName = libraryNode.getTextContent();
+
+ String xPathForCQLUUID = "/measure/measureDetails/cqlUUID";
+ Node cqluuidNode =
+ me.getSimpleXmlProcessor()
+ .findNode(me.getSimpleXmlProcessor().getOriginalDoc(), xPathForCQLUUID);
+ String cqlUUID = cqluuidNode.getTextContent();
+
+ if (supplementalDataElements == null || supplementalDataElements.getLength() < 1) {
+ return;
+ }
+ List supplementalElementRefIds = new ArrayList<>();
+ for (int i = 0; i < supplementalDataElements.getLength(); i++) {
+ supplementalElementRefIds.add(supplementalDataElements.item(i).getNodeValue());
+ }
+
+ StringBuilder uuidXPathString = new StringBuilder();
+ for (String uuidString : supplementalElementRefIds) {
+ uuidXPathString.append("@id = '").append(uuidString).append("' or ");
+ }
+ uuidXPathString =
+ new StringBuilder(uuidXPathString.substring(0, uuidXPathString.lastIndexOf(" or ")));
+ String xpathforOtherSupplementalDataElements =
+ "/measure/cqlLookUp/definitions/definition[" + uuidXPathString + "]";
+ NodeList supplementalQDMNodeList =
+ me.getSimpleXmlProcessor()
+ .findNodeList(
+ me.getSimpleXmlProcessor().getOriginalDoc(), xpathforOtherSupplementalDataElements);
+ if (supplementalQDMNodeList.getLength() < 1) {
+ return;
+ }
+
+ for (int i = 0; i < supplementalQDMNodeList.getLength(); i++) {
+ Node qdmNode = supplementalQDMNodeList.item(i);
+ String qdmName = qdmNode.getAttributes().getNamedItem("name").getNodeValue();
+
+ // createRiskAdjustmentComponentNode is good enough for this too.
+ Element componentElement =
+ createRiskAdjustmentComponentNode(me, cqlUUID, libraryName, qdmName, "SDE");
+ parentNode.appendChild(componentElement);
+ }
+ }
+
+ @Data
+ @Builder
+ static class MeasureGroup {
+ private NodeList packageClauses;
+ private String scoreUnit;
+ private int sequence;
+ }
}
diff --git a/src/main/java/gov/cms/madie/resources/PackageController.java b/src/main/java/gov/cms/madie/resources/PackageController.java
index 328cbbe..63c8788 100644
--- a/src/main/java/gov/cms/madie/resources/PackageController.java
+++ b/src/main/java/gov/cms/madie/resources/PackageController.java
@@ -3,7 +3,6 @@
import gov.cms.madie.Exceptions.UnsupportedModelException;
import gov.cms.madie.hqmf.Generator;
import gov.cms.madie.hqmf.HQMFGeneratorFactory;
-import gov.cms.madie.hqmf.XmlProcessor;
import gov.cms.madie.hqmf.dto.MeasureExport;
import gov.cms.madie.services.PackagingService;
import gov.cms.madie.models.measure.Measure;
@@ -55,6 +54,7 @@ public String generateHqmf(@RequestBody MeasureExport measureExport) throws Exce
Generator hqmfGenerator = hqmfGeneratorFactory.getHQMFGenerator();
return hqmfGenerator.generate(measureExport);
}
- throw new UnsupportedModelException("Unsupported model type: " + (measure == null ? "NONE" : measure.getModel()));
+ throw new UnsupportedModelException(
+ "Unsupported model type: " + (measure == null ? "NONE" : measure.getModel()));
}
}
diff --git a/src/test/java/gov/cms/madie/hqmf/HQMFGeneratorFactoryTest.java b/src/test/java/gov/cms/madie/hqmf/HQMFGeneratorFactoryTest.java
index c26ec4f..36eabbe 100644
--- a/src/test/java/gov/cms/madie/hqmf/HQMFGeneratorFactoryTest.java
+++ b/src/test/java/gov/cms/madie/hqmf/HQMFGeneratorFactoryTest.java
@@ -14,14 +14,13 @@
@ExtendWith(MockitoExtension.class)
class HQMFGeneratorFactoryTest {
- @Mock
- HQMFGenerator qdm_5_6_generator;
+ @Mock HQMFGenerator qdm_5_6_generator;
- @InjectMocks
- HQMFGeneratorFactory factory;
- @Test
- void getHQMFGenerator() {
- Generator hqmfGenerator = factory.getHQMFGenerator();
- assertThat(hqmfGenerator, is(equalTo(qdm_5_6_generator)));
- }
-}
\ No newline at end of file
+ @InjectMocks HQMFGeneratorFactory factory;
+
+ @Test
+ void getHQMFGenerator() {
+ Generator hqmfGenerator = factory.getHQMFGenerator();
+ assertThat(hqmfGenerator, is(equalTo(qdm_5_6_generator)));
+ }
+}
diff --git a/src/test/java/gov/cms/madie/hqmf/XMLUtilityTest.java b/src/test/java/gov/cms/madie/hqmf/XMLUtilityTest.java
index ea764c1..ac158a2 100644
--- a/src/test/java/gov/cms/madie/hqmf/XMLUtilityTest.java
+++ b/src/test/java/gov/cms/madie/hqmf/XMLUtilityTest.java
@@ -3,7 +3,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
@@ -21,63 +20,55 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyList;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class XMLUtilityTest {
- XMLUtility xmlUtility;
+ XMLUtility xmlUtility;
- @BeforeEach
- public void setup() {
- xmlUtility = XMLUtility.getInstance();
- }
+ @BeforeEach
+ public void setup() {
+ xmlUtility = XMLUtility.getInstance();
+ }
- @Test
- void testGetXmlResource() {
- String xmlResource = xmlUtility.getXMLResource("xsl/qdm_v5_6_measure_details.xsl");
- assertThat(xmlResource, is(notNullValue()));
- }
+ @Test
+ void testGetXmlResource() {
+ String xmlResource = xmlUtility.getXMLResource("xsl/qdm_v5_6_measure_details.xsl");
+ assertThat(xmlResource, is(notNullValue()));
+ }
- @Test
- void testBuildTransformerFactory() {
- TransformerFactory transformerFactory = xmlUtility.buildTransformerFactory();
- assertThat(transformerFactory, is(notNullValue()));
- }
+ @Test
+ void testBuildTransformerFactory() {
+ TransformerFactory transformerFactory = xmlUtility.buildTransformerFactory();
+ assertThat(transformerFactory, is(notNullValue()));
+ }
- @Test
- void testBuildDocumentBuilderFactory() throws ParserConfigurationException {
- DocumentBuilderFactory documentBuilderFactory = xmlUtility.buildDocumentBuilderFactory();
- assertThat(documentBuilderFactory, is(notNullValue()));
- }
+ @Test
+ void testBuildDocumentBuilderFactory() throws ParserConfigurationException {
+ DocumentBuilderFactory documentBuilderFactory = xmlUtility.buildDocumentBuilderFactory();
+ assertThat(documentBuilderFactory, is(notNullValue()));
+ }
- @Test
- void testBuildSaxParserFactory() throws SAXNotSupportedException, SAXNotRecognizedException, ParserConfigurationException {
- SAXParserFactory saxParserFactory = xmlUtility.buildSaxParserFactory();
- assertThat(saxParserFactory, is(notNullValue()));
- }
+ @Test
+ void testBuildSaxParserFactory()
+ throws SAXNotSupportedException, SAXNotRecognizedException, ParserConfigurationException {
+ SAXParserFactory saxParserFactory = xmlUtility.buildSaxParserFactory();
+ assertThat(saxParserFactory, is(notNullValue()));
+ }
- @Test
- void testBuildSchemaFactory() throws SAXNotSupportedException, SAXNotRecognizedException {
- SchemaFactory schemaFactory = xmlUtility.buildSchemaFactory();
- assertThat(schemaFactory, is(notNullValue()));
- }
+ @Test
+ void testBuildSchemaFactory() throws SAXNotSupportedException, SAXNotRecognizedException {
+ SchemaFactory schemaFactory = xmlUtility.buildSchemaFactory();
+ assertThat(schemaFactory, is(notNullValue()));
+ }
- @Test
- void testGetXmlReader() throws SAXException {
- SAXParser parser = mock(SAXParser.class);
- XMLReader reader = mock(XMLReader.class);
- when(parser.getXMLReader()).thenReturn(reader);
- XMLReader xmlReader = xmlUtility.getXMLReader(parser);
- assertThat(xmlReader, is(equalTo(reader)));
- }
-
-}
\ No newline at end of file
+ @Test
+ void testGetXmlReader() throws SAXException {
+ SAXParser parser = mock(SAXParser.class);
+ XMLReader reader = mock(XMLReader.class);
+ when(parser.getXMLReader()).thenReturn(reader);
+ XMLReader xmlReader = xmlUtility.getXMLReader(parser);
+ assertThat(xmlReader, is(equalTo(reader)));
+ }
+}
diff --git a/src/test/java/gov/cms/madie/hqmf/qdm_5_6/HQMFGeneratorTest.java b/src/test/java/gov/cms/madie/hqmf/qdm_5_6/HQMFGeneratorTest.java
index 9fe7ca6..49215e5 100644
--- a/src/test/java/gov/cms/madie/hqmf/qdm_5_6/HQMFGeneratorTest.java
+++ b/src/test/java/gov/cms/madie/hqmf/qdm_5_6/HQMFGeneratorTest.java
@@ -2,39 +2,67 @@
import gov.cms.madie.hqmf.dto.MeasureExport;
import gov.cms.madie.packaging.utils.ResourceFileUtil;
-import org.junit.jupiter.api.BeforeEach;
+import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+@Slf4j
@ExtendWith(MockitoExtension.class)
class HQMFGeneratorTest implements ResourceFileUtil {
- @Mock
- HQMFMeasureDetailsGenerator hqmfMeasureDetailsGenerator;
- @Mock
- HQMFDataCriteriaGenerator hqmfDataCriteriaGenerator;
-
- @InjectMocks
- HQMFGenerator hqmfGenerator;
-
- @Test
- void generate() throws Exception {
- String simpleXml = getStringFromTestResource("/simplexml/BMAT1644A-v0-0-001-QDM-5-6.xml");
- MeasureExport measureExport = MeasureExport.builder()
- .simpleXml(simpleXml)
- .releaseVersion("1.3.1")
- .build();
- String hqmf = hqmfGenerator.generate(measureExport);
- assertThat(hqmf, is(notNullValue()));
- }
-}
\ No newline at end of file
+ @Mock HQMFMeasureDetailsGenerator hqmfMeasureDetailsGenerator;
+ @Mock HQMFDataCriteriaGenerator hqmfDataCriteriaGenerator;
+
+ @InjectMocks HQMFGenerator hqmfGenerator;
+
+ final String baseHqmf =
+ """
+
+
+
+
+
+
+
+
+""";
+
+ final String dataCriteriaXml =
+ """
+
+
+
+
+
+
+
+
+
+
+ """;
+
+ @Test
+ void generate() throws Exception {
+ String simpleXml = getStringFromTestResource("/simplexml/BMAT1644A-v0-0-001-QDM-5-6.xml");
+ MeasureExport measureExport =
+ MeasureExport.builder().simpleXml(simpleXml).releaseVersion("1.3.1").build();
+ when(hqmfMeasureDetailsGenerator.generate(any(MeasureExport.class))).thenReturn(baseHqmf);
+ when(hqmfDataCriteriaGenerator.generate(any(MeasureExport.class))).thenReturn(dataCriteriaXml);
+ String hqmf = hqmfGenerator.generate(measureExport);
+ assertThat(hqmf, is(notNullValue()));
+ assertThat(
+ hqmf.trim().startsWith(""),
+ is(true));
+ assertThat(hqmf.contains(""), is(true));
+ }
+}
diff --git a/src/test/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureDetailsGeneratorTest.java b/src/test/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureDetailsGeneratorTest.java
index 5da53e9..71183bc 100644
--- a/src/test/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureDetailsGeneratorTest.java
+++ b/src/test/java/gov/cms/madie/hqmf/qdm_5_6/HQMFMeasureDetailsGeneratorTest.java
@@ -18,26 +18,27 @@
@Slf4j
@ExtendWith(MockitoExtension.class)
class HQMFMeasureDetailsGeneratorTest implements ResourceFileUtil {
- HQMFMeasureDetailsGenerator hqmfMeasureDetailsGenerator;
+ HQMFMeasureDetailsGenerator hqmfMeasureDetailsGenerator;
- @BeforeEach
- void setUp() {
- hqmfMeasureDetailsGenerator = new HQMFMeasureDetailsGenerator();
- }
+ @BeforeEach
+ void setUp() {
+ hqmfMeasureDetailsGenerator = new HQMFMeasureDetailsGenerator();
+ }
- @Test
- void generate() {
- String simpleXml = getStringFromTestResource("/simplexml/BMAT1644A-v0-0-001-QDM-5-6.xml");
- MeasureExport measureExport = MeasureExport.builder()
- .simpleXml(simpleXml)
- .releaseVersion("1.3.1")
- .build();
- String hqmf = hqmfMeasureDetailsGenerator.generate(measureExport);
- log.info(hqmf);
- assertThat(hqmf, is(notNullValue()));
- assertThat(hqmf, is(not(equalTo(simpleXml))));
- assertThat(hqmf.startsWith("\n" +
- ""), is(true));
- }
-}
\ No newline at end of file
+ @Test
+ void generate() {
+ String simpleXml = getStringFromTestResource("/simplexml/BMAT1644A-v0-0-001-QDM-5-6.xml");
+ MeasureExport measureExport =
+ MeasureExport.builder().simpleXml(simpleXml).releaseVersion("1.3.1").build();
+ String hqmf = hqmfMeasureDetailsGenerator.generate(measureExport);
+ log.info(hqmf);
+ assertThat(hqmf, is(notNullValue()));
+ assertThat(hqmf, is(not(equalTo(simpleXml))));
+ assertThat(
+ hqmf.startsWith(
+ "\n"
+ + ""), is(true));
+ }
+}
diff --git a/src/test/java/gov/cms/madie/resources/PackageControllerTest.java b/src/test/java/gov/cms/madie/resources/PackageControllerTest.java
index 2866038..45fea05 100644
--- a/src/test/java/gov/cms/madie/resources/PackageControllerTest.java
+++ b/src/test/java/gov/cms/madie/resources/PackageControllerTest.java
@@ -13,7 +13,6 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.hamcrest.CoreMatchers.equalTo;
@@ -82,10 +81,10 @@ void testGenerateHqmfForUnsupportedModel() {
MeasureExport measureExport = MeasureExport.builder().measure(measure).build();
String errorMessage = "Unsupported model type: " + measure.getModel();
Exception ex =
- Assertions.assertThrows(
- UnsupportedModelException.class,
- () -> packageController.generateHqmf(measureExport),
- errorMessage);
+ Assertions.assertThrows(
+ UnsupportedModelException.class,
+ () -> packageController.generateHqmf(measureExport),
+ errorMessage);
assertThat(ex.getMessage(), is(equalTo(errorMessage)));
}
@@ -94,21 +93,20 @@ void testGenerateHqmfForUnsupportedModelMissingMeasure() {
MeasureExport measureExport = MeasureExport.builder().build();
String errorMessage = "Unsupported model type: NONE";
Exception ex =
- Assertions.assertThrows(
- UnsupportedModelException.class,
- () -> packageController.generateHqmf(measureExport),
- errorMessage);
+ Assertions.assertThrows(
+ UnsupportedModelException.class,
+ () -> packageController.generateHqmf(measureExport),
+ errorMessage);
assertThat(ex.getMessage(), is(equalTo(errorMessage)));
}
@Test
void testGenerateHqmfReturnsHqmf() throws Exception {
- MeasureExport measureExport = MeasureExport.builder()
- .measure(measure)
- .build();
+ MeasureExport measureExport = MeasureExport.builder().measure(measure).build();
HQMFGenerator generator = mock(HQMFGenerator.class);
when(factory.getHQMFGenerator()).thenReturn(generator);
- when(generator.generate(any(MeasureExport.class))).thenReturn("");
+ when(generator.generate(any(MeasureExport.class)))
+ .thenReturn("");
String hqmf = packageController.generateHqmf(measureExport);
assertThat(hqmf, is(equalTo("")));
}