edu.harvard.i2b2.query.data.ModifierData.java Source code

Java tutorial

Introduction

Here is the source code for edu.harvard.i2b2.query.data.ModifierData.java

Source

/*
 * Copyright (c) 2006-2015 Massachusetts General Hospital 
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the i2b2 Software License v2.1 
 * which accompanies this distribution. 
 * 
 * Contributors: 
 *     Wensong Pan
 *     Taowei David Wang
 */

package edu.harvard.i2b2.query.data;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;

//import edu.harvard.i2b2.crcxmljaxb.datavo.psm.query.ItemType.ConstrainByValue;
import edu.harvard.i2b2.crcxmljaxb.datavo.vdo.GetModifierInfoType;
import edu.harvard.i2b2.crcxmljaxb.datavo.vdo.GetTermInfoType;
//import edu.harvard.i2b2.crcxmljaxb.datavo.vdo.GetTermInfoType;
import edu.harvard.i2b2.eclipse.plugins.query.ontologyMessaging.OntServiceDriver;
import edu.harvard.i2b2.eclipse.plugins.querytool.views.MessageUtil;

public class ModifierData extends QueryConceptTreeNodeData {
    private static final Log log = LogFactory.getLog(ModifierData.class);

    protected String modifier_name;
    protected String modifier_key;
    protected String applied_path;

    public ModifierData() {
        super();
        this.isModifier(true);
        valuePropertyData = new ValuePropertyData();
    }

    public ModifierData(QueryConceptTreeNodeData parent, String name, String title, String vAttribute,
            String tooltip, String hLevel, String fullName, String originalXml) {
        super(parent, name, title, vAttribute, tooltip, hLevel, fullName, originalXml);
        this.isModifier(true);
        valuePropertyData = new ValuePropertyData();
    }

    // constructor with 'null' parent
    public ModifierData(String name, String title, String vAttribute, String tooltip, String hLevel,
            String fullName, String originalXml) {
        this(null, name, title, vAttribute, tooltip, hLevel, fullName, originalXml);
    }

    //public boolean hasModifierValue()                   { return hasModifierValue; }
    public void modifier_name(String str) {
        modifier_name = new String(str);
    }

    public String modifier_name() {
        return modifier_name;
    }

    public void modifier_key(String str) {
        modifier_key = new String(str);
    }

    public String modifier_key() {
        return modifier_key;
    }

    public void applied_path(String str) {
        applied_path = new String(str);
    }

    public String applied_path() {
        return applied_path;
    }

    //public ValuePropertyData getModifierValueRestriction()    { return valuePropertyData; }   
    //public boolean          hasModifierValueRestriction()   { return this.hasModifierValueRestriction; }

    /* incompleteDoc is an XML document that has the <dnd:plugin_drag_drop> <concepts> <concept> tags. 
     *       The <concpet> tag contains the incomplete XML for the concept.
     *       We need to make the ontology call to ONT, grab the metadataXML in the form of
     *          <message_body> <ont:modifiers> <ont:modifier>, and stick the <ont:modifier> tag and its
     *          content as a child of the <concept> tag in incompleteXMLDoc
     */
    @Override
    public Document retrieveMetadataXMLfromONTAndSetOriginalXML(Document incompleteXMLDoc) {
        try {
            // call ONT service to get the full XML for the modifier         
            GetModifierInfoType vocab = new GetModifierInfoType();
            vocab.setHiddens(true);
            vocab.setSynonyms(false);
            vocab.setMax(200);
            vocab.setType("default");
            vocab.setBlob(true);
            vocab.setAppliedPath(applied_path);
            vocab.setSelf(modifier_key);
            String xmlContent = OntServiceDriver.getModifierInfo(vocab, "");

            // parse the XML and build a DOM
            java.io.StringReader xmlStringReader = new StringReader(xmlContent);
            SAXBuilder parser = new SAXBuilder();
            Document conceptDoc = parser.build(xmlStringReader);

            //bugbug: printouts
            System.err.println("Modifier XML from ONT"); // bugbug:
            System.err.println(MessageUtil.prettyFormat(xmlContent, 5)); // bugbug:

            // work with DOM to extract the <ont:concepts> node
            Element elementMsgBody = conceptDoc.getRootElement().getChild(MESSAGE_BODY);
            Element modifiersTag = (Element) elementMsgBody.getChild(MODIFIERS,
                    Namespace.getNamespace(ONT_NAMESPACE)); // get a copy of the <concepts> tag
            Element modifierTag = (Element) ((Element) modifiersTag.getContent(DataUtils.makeTagFilter(MODIFIER))
                    .get(0)).clone(); // we expect only 1 modifier, so we grab the first one         
            modifierTag.detach();

            // add the modifierXML as a child to the <concpet> element in incompleteXMLDoc
            Element dndTag = (Element) incompleteXMLDoc.getContent(DataUtils.DRAG_AND_DROP_TAG_FILTER).get(0);
            Element conceptsTag = (Element) dndTag.getContent(DataUtils.CONCEPTS_TAG_FILTER).get(0);
            Element conceptTag = (Element) conceptsTag.getContent(DataUtils.makeTagFilter(CONCEPT)).get(0);
            conceptTag.removeChild(MODIFIER); // remove the incomplete modifier tag if it exists         
            conceptTag.addContent(modifierTag); // add the complete version
            //conceptTag.removeChild( QueryConceptTreeNodeData.TAG_IS_XML_COMPLETE ); // remove <isXMLComplete> if it exists

            // find the <ont:concept> node and set its supplemental <isXMLComplete> tag to "true"
            Element isXMLCoompleteTag = new Element(QueryConceptTreeNodeData.TAG_IS_XML_COMPLETE); // mark the concept as having a complete XML, add the supplemental tag
            isXMLCoompleteTag.setText(DataConst.TRUE);
            conceptTag.addContent(isXMLCoompleteTag);

            // get a String representation of the XML and set it as the originalXML for this node.
            StringWriter strWriter = new StringWriter();
            DataUtils.prettyPrintXMLDoc(incompleteXMLDoc, strWriter);
            this.finalizeOriginalXML(strWriter.toString()); // set and finalize originalXML

            System.err.println("Completed Modifier  XML: "); // bugbug:
            System.err.println(strWriter.toString()); // bugbug:         
            //System.err.println("Updated ModifierData ");

            strWriter.close();

            // return the DOM document for good measure.
            return incompleteXMLDoc;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Document retrieveFullConceptXMLFromONTandSetOriginalXML() {
        try {
            // retrieve concept XML by calling helper method in super class
            Document incompleteXMLDoc = super.doRetrieveMetadataXMLfromONTAsDoc();

            // bugbug: prints
            System.err.println("ModifierData: ConceptDoc:");
            DataUtils.prettyPrintXMLDoc(incompleteXMLDoc, System.err);

            // extract a clone of <ont:concepts> from conceptXMLDoc
            //Element conceptsTag = (Element)((Element)((Element)conceptXMLDoc.getContent( DataConst.DRAG_AND_DROP_TAG_FILTER ).get(0)).getContent().get(0)).clone();
            //Element elementMsgBody    = conceptXMLDoc.getRootElement().getChild( DataConst.DRAG_AND_DROP ); 
            //Element conceptsTag    = (Element)elementMsgBody.getChild( CONCEPTS , Namespace.getNamespace( ONT_NAMESPACE )).clone(); // get a copy of the <concepts> tag 
            //conceptsTag.detach();

            // create an empty XML Doc and attach the cloned <ont:conepts> to it
            //Document incompleteXMLDoc    = DataUtils.makeEmptyDNDXMLDocument();         
            //Element dndTag            = (Element)incompleteXMLDoc.getContent( DataUtils.DRAG_AND_DROP_TAG_FILTER ).get(0);
            //dndTag.addContent( conceptsTag );

            // bugbug: prints
            //System.err.println("ModifierData: ConceptDoc with Metadata:");
            //DataUtils.prettyPrintXMLDoc( incompleteXMLDoc, System.err );

            retrieveMetadataXMLfromONTAndSetOriginalXML(incompleteXMLDoc);

            return incompleteXMLDoc;

            //Element elementMsgBody = conceptDoc.getRootElement().getChild("message_body");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void parseOriginalXMLAndSetValuePropertySchema() throws JDOMException, IOException {
        StringReader xmlStringReader = new StringReader(this.originalXML);
        SAXBuilder parser = new SAXBuilder();
        Document conceptDoc = parser.build(xmlStringReader);

        Element conceptsTag = conceptDoc.getRootElement().getChild(CONCEPTS, Namespace.getNamespace(ONT_NAMESPACE));

        Element conceptTag = (Element) conceptsTag.getChildren().get(0); // get the only Concept
        Element modifierTag = (Element) conceptTag.getContent(DataUtils.makeTagFilter(DataUtils.MODIFIER)).get(0);
        titleName(modifierTag.getChild(NAME).getText());

        Element metadataAttribs = modifierTag.getChild(METADATA_XML);
        Element valuedataAttribs = null;
        if (metadataAttribs != null)
            valuedataAttribs = metadataAttribs.getChild(VALUE_METADATA);

        if ((metadataAttribs != null) && (valuedataAttribs != null)) {
            this.hasValue(true);
            Element dataTypeElement = valuedataAttribs.getChild(DATA_TYPE);
            if (dataTypeElement != null && dataTypeElement.getTextTrim().equalsIgnoreCase(ENUM)) {
                // add text values to node data
                valuePropertyData.hasEnumValue(true);
                Element enumElement = valuedataAttribs.getChild(ENUM_VALUES);
                for (int i = 0; i < enumElement.getChildren().size(); i++) {
                    Element valElement = (Element) enumElement.getChildren().get(i);
                    String valString = new String(valElement.getTextTrim());
                    valuePropertyData.enumValues.add(valString);
                }
            } else if (dataTypeElement != null && (dataTypeElement.getTextTrim().equalsIgnoreCase(STRING)
                    || dataTypeElement.getTextTrim().equalsIgnoreCase(LARGE_STRING))) {
                // add text values to node data
                valuePropertyData.hasStringValue(true);
                Element maxLengthElement = valuedataAttribs.getChild(MAX_STRING_LENGTH);
                String valString = new String(maxLengthElement.getTextTrim());
                if (!valString.equalsIgnoreCase(""))
                    valuePropertyData.searchStrLength(Integer.parseInt(valString));
                if (dataTypeElement.getTextTrim().equalsIgnoreCase(LARGE_STRING))
                    valuePropertyData.isLongText(true);
            }

            if (valuedataAttribs.getChild(OK_TO_USE_VALUES) != null
                    && valuedataAttribs.getChild(OK_TO_USE_VALUES).getText().equalsIgnoreCase("Y"))
                valuePropertyData.okToUseValue(true);

            if (valuedataAttribs.getChild(FLAGS_TO_USE) == null
                    || valuedataAttribs.getChild(FLAGS_TO_USE).getText().equalsIgnoreCase(""))
                valuePropertyData.okToUseValueFlag(false);

            Element unitElement = valuedataAttribs.getChild(UNIT_VALUES);
            if (unitElement != null) {
                for (int i = 0; i < unitElement.getChildren().size(); i++) {
                    Element element = (Element) unitElement.getChildren().get(i);
                    if (element.getName().equalsIgnoreCase(NORMAL_VALUES)
                            || element.getName().equalsIgnoreCase(EQUAL_UNITS)) {
                        String unitString = new String(element.getTextTrim());
                        valuePropertyData.units.add(new UnitsData(unitString, 1, false));
                    } else if (element.getName().equalsIgnoreCase(CONVERTING_UNITS)) {
                        Element cunitElement = element.getChild(UNITS);
                        String unitString = new String(cunitElement.getTextTrim());
                        Element mfElement = element.getChild(MULTIPLYING_FACTOR);
                        if (mfElement != null && !mfElement.getTextTrim().equalsIgnoreCase("")) {
                            double mf = Double.parseDouble(mfElement.getTextTrim());
                            valuePropertyData.units.add(new UnitsData(unitString, mf, true));
                        }
                    }
                }
            }
        }

    }

    @Override /* Copyable method */
    public ModifierData makeCopy() {
        ModifierData md = new ModifierData(this.myParent, this.name, this.titleName, this.visualAttribute,
                this.tooltip, this.hlevel, this.fullname, this.originalXML);
        md.valueName = this.valueName;
        md.hasValue = this.hasValue;
        md.valuePropertyData = this.valuePropertyData.makeCopy();

        md.modifier_name = this.modifier_name;
        md.modifier_key = this.modifier_key;
        md.applied_path = this.applied_path;

        for (QueryConceptTreeNodeData node : this.myChildren) {
            QueryConceptTreeNodeData newNode = node.makeCopy();
            newNode.myParent = md;
            md.myChildren.add(newNode);
        }
        return md;
    }

    /*
    public ConstrainByModifier writeModifierConstraint() 
    {      
       ConstrainByModifier modifierConstraint = new ConstrainByModifier();
       modifierConstraint.setAppliedPath(applied_path);
       modifierConstraint.setModifierKey(modifier_key);
       modifierConstraint.setModifierName(modifier_name);      
       // handle value constraint
       if (!modifierValuePropertyData.noValue()) {
     ConstrainByModifier.ConstrainByValue valueConstrain = modifierValuePropertyData.writeModifierValueConstrain();
     modifierConstraint.getConstrainByValue().add(valueConstrain);
       }      
       return modifierConstraint;
    }
    */

    /* bugbug: unused so commented out
    public void setModifierValueConstraint(List<ConstrainByModifier.ConstrainByValue> list) 
    {
       if (list != null && list.size() > 0) 
       {
     hasValue(true);
     ConstrainByModifier.ConstrainByValue cons = list.get(0);
     if (cons.getValueConstraint() == null) 
     {
        // hasValue(false);
        return;
     }
     if (cons.getValueType().equals(ConstrainValueType.NUMBER)) 
        this.modifierValuePropertyData().useNumericValue(true);
     else if (cons.getValueType().equals(ConstrainValueType.TEXT) || cons.getValueType().equals(ConstrainValueType.LARGETEXT)) 
        this.modifierValuePropertyData().useTextValue(true);
     else if (cons.getValueType().equals(ConstrainValueType.FLAG))
        this.modifierValuePropertyData().useValueFlag(true);
         
     updateModifierMetaDataXML();
     if(this.modifierValuePropertyData().hasStringValue() && this.modifierValuePropertyData().useTextValue()) 
     {
        this.modifierValuePropertyData().useStringValue(true);
        this.modifierValuePropertyData().useTextValue(false);
     }
        
     this.modifierValuePropertyData().noValue(false);
     this.modifierValuePropertyData().value(cons.getValueConstraint());
         
     for (int i = 0; i < modifierValuePropertyData.enumValues.size(); i++) 
     {
        String eval = modifierValuePropertyData.enumValues.get(i);
        String teval = "'"+eval+"'";
        if (modifierValuePropertyData().value().indexOf(teval)>=0)
           modifierValuePropertyData().selectedValues.add(eval);
     }
         
     if (cons.getValueUnitOfMeasure() != null)
        this.modifierValuePropertyData().unit(cons.getValueUnitOfMeasure());
     if (cons.getValueOperator() != null) 
     {
        this.modifierValuePropertyData().operator( cons.getValueOperator().value());
        // deal with between...
        if (this.modifierValuePropertyData().operator().equalsIgnoreCase("between")) {
           String[] result = cons.getValueConstraint().split(" and ");
           if (result != null && result.length == 2)
           {
              this.modifierValuePropertyData().lowValue(result[0]);
              this.modifierValuePropertyData().highValue(result[1]);
           }
        }
        
     }
     this.modifierValuePropertyData().okToUseValue(true);
       } 
       else 
       {
     hasValue(false);
       }
    }
    */

    @Override
    public String toString() {
        String valuePropertyString = this.valuePropertyData.toString();
        if (valuePropertyString.isEmpty())
            return name() + " [" + this.modifier_name() + "]";
        else
            return name() + " [" + this.modifier_name() + " " + valuePropertyString + "]";
    }
}