package com.openMap1.mapper.converters;
import java.util.Hashtable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.openMap1.mapper.MappedStructure;
import com.openMap1.mapper.core.MapperException;
import com.openMap1.mapper.structures.MapperWrapper;
import com.openMap1.mapper.util.XMLUtil;
/**
*
* @author Robert
* The only functions of this wrapper class are:
*
* As an input wrapper, to extract subtrees below <text> nodes
* and index them by string keys in the Hashtable keptSubtrees.
*
* As an output wrapper, to use the string content of <text> nodes
* as keys into a Hashtable (set up by the input wrapper class) to
* recover the subtrees below the <text> nodes
*/
public class NHS_Simplified_CDA extends AbstractMapperWrapper implements MapperWrapper{
/**
* @param ms set of mappings which uses this wrapper transform
* @param spare used to provide the input reader,
*/
public NHS_Simplified_CDA(MappedStructure ms, Object spare) throws MapperException
{
super(ms,spare);
}
/**
* @return the type of document transformed to and from;
* see static constants in class AbstractMapperWrapper.
*/
public int transformType() {return AbstractMapperWrapper.XML_TYPE;}
/**
*
* @return the file extension of the outer document, with initial '*.'
*/
public String fileExtension() {return "*.xml";}
//--------------------------------------------------------------------------------------------
// Transform methods in the MapperWrapper Interface
//--------------------------------------------------------------------------------------------
/**
*
* @param incoming; must be of class Element or InputStream
* @return the result of the in wrapper transform
*/
public Document transformIn(Object incoming) throws MapperException
{
// initialise the table of xml subtrees to pass to the output, and the key for that table
keptSubtrees = new Hashtable<String,Element>();
keyIndex = 0;
if (!(incoming instanceof Element)) throw new MapperException("Document root is not an Element");
Element mappingRoot = (Element)incoming;
String mappingRootPath = "/ClinicalDocument";
inResultDoc = XMLUtil.makeOutDoc();
// see override of scanDocument below
Element inRoot = scanDocument(mappingRoot, mappingRootPath, AbstractMapperWrapper.IN_TRANSFORM);
inResultDoc.appendChild(inRoot);
return inResultDoc;
}
/**
* @param outgoing the root element produced by the XMLWriter when
* writing out from a class model instance (seen through an objectGetter)
* @return the result of the out wrapper transform;
* must be of class Document or OutputStream
*/
public Object transformOut(Element outgoing) throws MapperException
{
String mappingRootPath = "/ClinicalDocument";
outResultDoc = XMLUtil.makeOutDoc();
// see override of scanDocument below
Element outRoot = scanDocument(outgoing, mappingRootPath, AbstractMapperWrapper.OUT_TRANSFORM);
outResultDoc.appendChild(outRoot);
return outResultDoc;
}
/**
* recursive scan of document,
* making changes only at <text> nodes
*/
protected Element scanDocument(Element el, String path, int scanType) throws MapperException
{
String tagName = XMLUtil.getLocalName(el); // el.getLocalName() gives null here in the out transform
/* <text> node in input; retain the subtree in a Hashtable, and do not pass the subtree to
* the in-wrapped document. Pass only the text key. */
if ((tagName != null) && (tagName.equals("text")) && (scanType == AbstractMapperWrapper.IN_TRANSFORM))
{
return saveInputTextSubtree(el);
}
/* <text> node in output; look up the subtree in the input Hashtable, and pass it to
* the out-wrapped document */
else if ((tagName != null) && (tagName.equals("text")) && (scanType == AbstractMapperWrapper.OUT_TRANSFORM))
{
return recoverInputTextSubtree(el,path);
}
// all other nodes; carry on recursion which makes no change
else return super.scanDocument(el, path, scanType);
}
}