/*
* $Id$
*
* Authors:
* Jeff Buchbinder <jeff@freemedsoftware.org>
*
* REMITT Electronic Medical Information Translation and Transmission
* Copyright (C) 1999-2014 FreeMED Software Foundation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.remitt.plugin.translation;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.remitt.prototype.PluginInterface;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class FixedFormXml implements PluginInterface {
static final Logger log = Logger.getLogger(FixedFormXml.class);
protected XPath xpath = null;
protected String defaultUsername = "";
@Override
public String getInputFormat() {
return "fixedformxml";
}
public HashMap<String, String> getOptions() {
return null;
}
@Override
public String getOutputFormat() {
return "text";
}
@Override
public String getPluginName() {
return "FixedFormXml";
}
@Override
public Double getPluginVersion() {
return 0.1;
}
@Override
public byte[] render(Integer jobId, byte[] input, String option)
throws Exception {
log.info("Entered Translate for job #" + jobId.toString());
StringBuilder sb = new StringBuilder();
// Attempt to load input stream
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbFactory.newDocumentBuilder();
log.debug("Loading input into XmlDocument");
ByteArrayInputStream inputStream = new ByteArrayInputStream(input);
org.w3c.dom.Document xmlInput = builder.parse(inputStream);
XPathFactory xpFactory = XPathFactory.newInstance();
xpath = xpFactory.newXPath();
Node root = xmlInput.getDocumentElement();
NodeList nodeList = (NodeList) xpath.evaluate("/fixedform/page", root,
XPathConstants.NODESET);
// Loop through all page elements
for (int iter = 0; iter < nodeList.getLength(); iter++) {
sb.append(TranslatePageFromNode(nodeList.item(iter)));
}
log.info("Leaving Translate for job #" + jobId.toString());
return sb.toString().getBytes();
}
private String TranslatePageFromNode(Node page) {
int currentRow = 1;
int currentCol = 1;
StringBuilder sb = new StringBuilder();
// Get elements ...
NodeList elementNodes = ((Element) page)
.getElementsByTagName("element");
// Perform sorting by creating list
ArrayList<Element> elements = new ArrayList<Element>();
for (int iter = 0; iter < elementNodes.getLength(); iter++) {
elements.add((Element) elementNodes.item(iter));
}
// ... then doing sort using delegates
Collections.sort(elements, new Comparator<Element>() {
@Override
public int compare(Element elementA, Element elementB) {
// -1 implies A < B
// 0 implies A = B
// +1 implies A > B
int rowA = 0;
int rowB = 0;
int colA = 0;
int colB = 0;
// --------------------- ElementA -------------------
try {
rowA = Integer.parseInt(elementA
.getElementsByTagName("row").item(0)
.getTextContent());
} catch (Exception ex) {
log.trace(ex.toString());
rowA = 0;
}
try {
colA = Integer.parseInt(elementA.getElementsByTagName(
"column").item(0).getTextContent());
} catch (Exception ex) {
log.trace(ex.toString());
colA = 0;
}
// --------------------- ElementB -------------------
try {
rowB = Integer.parseInt(elementA
.getElementsByTagName("row").item(0)
.getTextContent());
} catch (Exception ex) {
log.trace(ex.toString());
rowB = 0;
}
try {
colB = Integer.parseInt(elementA.getElementsByTagName(
"column").item(0).getTextContent());
} catch (Exception ex) {
log.trace(ex.toString());
colB = 0;
}
// Compare ...
if (rowA < rowB) {
return -1;
}
if (rowA > rowB) {
return 1;
}
if ((rowA == rowB) && (colA < colB)) {
return -1;
}
if ((rowA == rowB) && (colA > colB)) {
return 1;
}
return 0;
}
});
Iterator<Element> eIter = elements.iterator();
while (eIter.hasNext()) {
Element element = eIter.next();
int elementRow;
int elementColumn;
try {
elementRow = Integer.parseInt(((Element) element)
.getElementsByTagName("row").item(0).getTextContent());
} catch (Exception ex) {
if (ex.toString().length() > 1) {
}
elementRow = 0;
}
try {
elementColumn = Integer.parseInt(((Element) element)
.getElementsByTagName("column").item(0)
.getTextContent());
} catch (Exception ex) {
if (ex.toString().length() > 1) {
}
elementColumn = 0;
}
if ((elementRow > 0) && (elementColumn > 0)) {
sb.append(padToPosition(currentRow, currentCol, elementRow,
elementColumn));
currentRow = elementRow;
currentCol = elementColumn;
String elementContents = processElement(element);
sb.append(elementContents);
currentCol += elementContents.length();
} else {
log.debug("Found null element, skipping.");
}
}
// Divine page length from /fixedform/page/format/pagelength element
int pageLength = 0;
try {
pageLength = Integer.parseInt(((Element) ((Element) page)
.getElementsByTagName("format").item(0))
.getElementsByTagName("pagelength").item(0)
.getTextContent());
} catch (Exception ex) {
if (ex.toString().length() > 1) {
}
pageLength = 0;
}
// Move cursor to the end of the page
while (currentRow < pageLength) {
sb.append("\r\n");
currentRow += 1;
currentCol = 1;
}
return sb.toString();
}
/**
* Pad a string from one page position to another.
*
* @param oldRow
* Originating row
* @param oldColumn
* Originating column
* @param newRow
* Desired destination row
* @param newColumn
* Desired destination column
* @return
*/
protected String padToPosition(int oldRow, int oldColumn, int newRow,
int newColumn) {
// Sanity checks
if (oldRow > newRow) {
log.debug("oldRow = " + oldRow + ", newRow = " + newRow);
return "";
}
if ((oldRow == newRow) && (oldColumn > newColumn)) {
log.debug("oldRow = " + oldRow + ", newRow = " + newRow + " ( "
+ oldColumn + " > " + newColumn + " )");
return "";
}
if ((oldRow == newRow) && (oldColumn == newColumn)) {
return "";
}
StringBuilder sb = new StringBuilder();
int currentRow = oldRow;
int currentColumn = oldColumn;
while (currentRow < newRow) {
sb.append("\r\n");
currentRow += 1;
currentColumn = 1;
}
while (currentColumn < newColumn) {
sb.append(" ");
currentColumn += 1;
}
return sb.toString();
}
private String processElement(Node element) {
String elementContent = null;
int elementLength = 0;
try {
elementLength = Integer.parseInt(((Element) element)
.getElementsByTagName("length").item(0).getTextContent());
} catch (Exception ex) {
if (ex.toString().length() > 1) {
}
elementLength = 0;
}
// Make sure null is sent back if there's no length to be had here
if (elementLength == 0) {
return "";
}
try {
elementContent = ((Element) element)
.getElementsByTagName("content").item(0).getTextContent();
} catch (Exception ex) {
if (ex.toString().length() > 1) {
}
elementContent = "";
}
// Chop string if it's too long
if (elementContent.length() > elementLength) {
return elementContent.substring(0, elementLength);
}
// Block to check for right alignment
try {
String alignment = ((Element) element).getElementsByTagName(
"format").item(0).getAttributes().getNamedItem("right")
.getTextContent();
if (Integer.parseInt(alignment) == 1) {
return StringUtils.leftPad(elementContent, elementLength);
}
} catch (Exception ex) {
if (ex.toString().length() > 1) {
}
}
// If formatting doesn't dictate otherwise, return padded output
return StringUtils.rightPad(elementContent, elementLength);
}
@Override
public String[] getPluginConfigurationOptions() {
return null;
}
@Override
public void setDefaultUsername(String username) {
defaultUsername = username;
}
}