package com.openMap1.mapper.editSupport;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class EditUtil {
//----------------------------------------------------------------------------------------------------------
// support for all methods - XML utilities
//----------------------------------------------------------------------------------------------------------
/**
* return the root Element of an XML file with given location
* @param location
* @return Element the root element, or null if there is any problem
*/
public static Element getRootElement(String location) throws Exception
{
Element root = null;
try {
FileInputStream fi = new FileInputStream(location);
DocumentBuilderFactory builderFac = DocumentBuilderFactory.newInstance();
builderFac.setNamespaceAware(true);
root = builderFac.newDocumentBuilder().parse(fi).getDocumentElement();
}
catch (SAXException ex) {notify(location,ex);}
catch (FileNotFoundException ex) {notify(location,ex);}
catch (IOException ex) {notify(location,ex);}
catch (ParserConfigurationException ex) {notify(location,ex);}
return root;
}
private static void notify(String location, Exception ex) throws Exception
{
throw new Exception ("Exception getting XML root element from "
+ location + "; " + ex.getMessage());
}
public static Element getNamedChild(Element parent, String name)
{
Element child = null;
NodeList nl = parent.getChildNodes();
for (int i = 0; i < nl.getLength(); i++)
{
Node nd = nl.item(i);
if ((nd instanceof Element) && (nd.getLocalName().equals(name))) child = (Element)nd;
}
return child;
}
/**
*
* @param node
* @return the value of any XML node, or the empty string "" if the node is null
*/
public static String getValue(Node node)
{
String val = "";
if (node != null)
{
if (node instanceof Element) {val = node.getTextContent();}
else if (node instanceof Attr) {val = ((Attr)node).getValue();}
else {val = node.getNodeValue();}
}
return val;
}
//----------------------------------------------------------------------------------------------------------
// support for all methods - reading csv files
//----------------------------------------------------------------------------------------------------------
/**
*
* @param relativeLocation
* @return the parsed rows of a csv file
*/
public static Vector<String[]> readCSVRows(String absoluteLocation)
{
// read the lines of the csv file
Vector<String> lines = textLines(absoluteLocation);
// find the number of columns, from the header row
StringTokenizer header = new StringTokenizer(lines.get(0),",");
int columns = header.countTokens();
// parse each row
Vector<String[]> rows = new Vector<String[]>();
for (int i = 0; i < lines.size(); i++) rows.add(parseCSVLine(columns,lines.get(i)));
return rows;
}
/**
*
* @param location an absolute file location
* @return the lines of a text file at the location
* @throws MapperException
*/
public static Vector<String> textLines(String location)
{
Vector<String> lines = new Vector<String>();
FileInputStream fiz = getTextFile(location);
InputStreamReader isr = new InputStreamReader(fiz);
LineNumberReader lnr = new LineNumberReader(isr);
try {
String line = lnr.readLine();
while (line != null)
{
lines.add(line);
line = lnr.readLine();
}
lnr.close();
}
catch (Exception ex) {message("Failure reading read text file at '" + location + "': " + ex.getMessage());}
return lines;
}
/**
* read a text file at an absolute file location
*/
public static FileInputStream getTextFile(String location)
{
FileInputStream fi = null;
try {
fi = new FileInputStream(location);
}
catch (Exception ex) {message("Cannot read text file at '" + location + "': " + ex.getMessage());}
return fi;
}
/**
* read a line of a csv file, expected to have not more than columns separated fields,
* and return a string array of the fields, including "" for and initial ',' or two successive ',',
* or for final fields not supplied.
* FIXME: does not deal with commas within the csv fields.
* @param columns max number of columns allowed
* @param line
* @return String array of field values
* @throws MapperException
*/
public static String[] parseCSVLine(int columns, String line)
{
String[] field = new String[columns];
StringTokenizer st = new StringTokenizer(line,",",true);
int col = 0;
boolean emptyField = true;
while (st.hasMoreTokens())
{
if (col > columns -1) message("Too many columns in csv line '" + line + "'");
String val = st.nextToken();
if (val.equals(","))
{
if (emptyField) // initial ',', or two successive ','
{
field[col]="";
col++;
}
emptyField = true;
}
else // non-empty field
{
field[col] = val;
col++;
emptyField = false;
}
}
// trailing fields not even given ','
if (col < columns)
for (int c = col; c < columns; c++) field[c] = "";
return field;
}
private static void message(String s) {System.out.println(s);}
}