/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy 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 3 of the License, or
* (at your option) any later version.
*
* Icy 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 Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.util;
import icy.file.FileUtil;
import icy.network.AuthenticationInfo;
import icy.network.NetworkUtil;
import icy.network.URLUtil;
import icy.system.IcyExceptionHandler;
import icy.type.DataType;
import icy.type.collection.array.ArrayUtil;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* XML utilities class (parse, read, create and write XML documents).
*
* @author Stephane
*/
public class XMLUtil
{
public static final String FILE_EXTENSION = "xml";
public static final String FILE_DOT_EXTENSION = "." + FILE_EXTENSION;
public static final String NODE_ROOT_NAME = "root";
private static final String ATTR_NAME_NAME = "name";
private static final String ATTR_VALUE_NAME = "value";
// static document builder factory
private static DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
// static transformer factory
private static TransformerFactory transformerFactory = TransformerFactory.newInstance();
// static Deflater
// private static Deflater deflater = new Deflater(2, true);
private static Deflater deflater = new Deflater(2);
// static Inflater
// private static Inflater inflater = new Inflater(true);
private static Inflater inflater = new Inflater();
static
{
try
{
docBuilderFactory.setNamespaceAware(false);
docBuilderFactory.setValidating(false);
docBuilderFactory.setFeature("http://xml.org/sax/features/namespaces", false);
docBuilderFactory.setFeature("http://xml.org/sax/features/validation", false);
docBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
docBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
}
catch (Exception e)
{
// ignore this
}
}
// private static synchronized void init()
// {
// // initialize static builder
// if (docBuilder == null)
// docBuilder = createDocumentBuilder();
// // initialize static transformer
// if (transformer == null)
// transformer = createTransformer();
// }
// docBuilder = createDocumentBuilder();
// transformer = createTransformer();
/**
* Create and returns a new DocumentBuilder.
*/
public static DocumentBuilder createDocumentBuilder()
{
try
{
return docBuilderFactory.newDocumentBuilder();
}
catch (ParserConfigurationException e)
{
e.printStackTrace();
return null;
}
}
/**
* Create and returns a new Transformer.
*/
public static Transformer createTransformer()
{
final Transformer result;
try
{
result = transformerFactory.newTransformer();
}
catch (TransformerConfigurationException e)
{
IcyExceptionHandler.showErrorMessage(e, true, true);
return null;
}
result.setOutputProperty(OutputKeys.METHOD, "xml");
result.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
result.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
result.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
result.setOutputProperty(OutputKeys.INDENT, "yes");
return result;
}
/**
* Create and returns a new Transformer.
*/
public static Transformer createTransformerSafe() throws TransformerConfigurationException
{
final Transformer result = transformerFactory.newTransformer();
result.setOutputProperty(OutputKeys.METHOD, "xml");
result.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
result.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
result.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
result.setOutputProperty(OutputKeys.INDENT, "yes");
return result;
}
/**
* Create and return an empty XML Document.
*/
public static Document createDocument(boolean createRoot)
{
final DocumentBuilder docBuilder = createDocumentBuilder();
// an error occurred
if (docBuilder == null)
return null;
// create document
final Document result = docBuilder.newDocument();
// add default "root" element if wanted
if (createRoot)
createRootElement(result);
return result;
}
/**
* Parse the specified string and convert it to XML Document (throw an exception if an error occurred).
*
* @throws IOException
* @throws SAXException
*/
public static Document createDocument(String xmlString) throws SAXException, IOException
{
final DocumentBuilder docBuilder = createDocumentBuilder();
// an error occurred
if (docBuilder == null)
return null;
return docBuilder.parse(new InputSource(new StringReader(filterString(xmlString))));
}
/**
* @deprecated Use {@link #createDocument(String)} instead.
*/
@Deprecated
public static Document getDocument(String xmlString)
{
final DocumentBuilder docBuilder = createDocumentBuilder();
// an error occurred
if (docBuilder == null)
return null;
try
{
return docBuilder.parse(new InputSource(new StringReader(filterString(xmlString))));
}
catch (Exception e)
{
IcyExceptionHandler.showErrorMessage(e, true);
}
// return empty document
return createDocument(false);
}
/**
* @deprecated Use {@link #createDocument(String)} instead.
*/
@Deprecated
public static Document getDocumentSafe(String xmlString) throws SAXException, IOException
{
return createDocument(xmlString);
}
/**
* Load XML Document from specified path.<br>
* Return null if no document can be loaded.
*/
public static Document loadDocument(String path)
{
return loadDocument(path, null, false);
}
/**
* Load XML Document from specified path.<br>
* Return null if no document can be loaded.
*/
public static Document loadDocument(String path, boolean showError)
{
return loadDocument(path, null, showError);
}
/**
* Load XML Document from specified path with specified authentication.<br>
* Return null if no document can be loaded.
*/
public static Document loadDocument(String path, AuthenticationInfo auth, boolean showError)
{
if (StringUtil.isEmpty(path))
{
if (showError)
System.err.println("XMLUtil.loadDocument('" + path + "') error: empty path !");
return null;
}
final URL url = URLUtil.getURL(path);
// load from URL
if (url != null)
return loadDocument(url, auth, showError);
// try to load from file instead (no authentication needed then)
return loadDocument(new File(path), showError);
}
/**
* Load XML Document from specified file.<br>
* Return null if no document can be loaded.
*/
public static Document loadDocument(File f)
{
return loadDocument(f, false);
}
/**
* Load XML Document from specified file.<br>
* Return null if no document can be loaded.
*/
public static Document loadDocument(File f, boolean showError)
{
if ((f == null) || !f.exists())
{
if (showError)
System.err.println("XMLUtil.loadDocument('" + f + "') error: file not found !");
return null;
}
final DocumentBuilder builder = createDocumentBuilder();
if (builder != null)
{
try
{
return builder.parse(f);
}
catch (Exception e)
{
if (showError)
{
System.err.println("XMLUtil.loadDocument('" + f.getPath() + "') error:");
IcyExceptionHandler.showErrorMessage(e, false);
}
}
}
return null;
}
/**
* Load XML Document from specified URL.<br>
* Return null if no document can be loaded.
*/
public static Document loadDocument(URL url)
{
return loadDocument(url, null, false);
}
/**
* Load XML Document from specified URL.<br>
* Return null if no document can be loaded.
*/
public static Document loadDocument(URL url, boolean showError)
{
return loadDocument(url, null, showError);
}
/**
* Load XML Document from specified URL with authentication informations.<br>
* Return null if no document can be loaded.
*/
public static Document loadDocument(URL url, AuthenticationInfo auth, boolean showError)
{
// use file loading if possible
if (URLUtil.isFileURL(url))
{
File f;
try
{
f = new File(url.toURI());
}
catch (URISyntaxException e)
{
f = new File(url.getPath());
}
return loadDocument(f);
}
final DocumentBuilder builder = createDocumentBuilder();
if (builder != null)
{
final InputStream ip = NetworkUtil.getInputStream(url, auth, true, showError);
if (ip != null)
{
try
{
return builder.parse(ip);
}
catch (Exception e)
{
System.err.println("XMLUtil.loadDocument('" + url + "') error :");
IcyExceptionHandler.showErrorMessage(e, false);
}
finally
{
try
{
ip.close();
}
catch (IOException e)
{
// ignore
}
}
}
else if (showError)
System.err.println("XMLUtil.loadDocument('" + url + "') error :");
}
return null;
}
/**
* Save the specified XML Document to specified filename.<br>
* Return false if an error occurred.
*/
public static boolean saveDocument(Document doc, String filename)
{
return saveDocument(doc, FileUtil.createFile(filename));
}
/**
* Save the specified XML Document to specified file.<br>
* Return false if an error occurred.
*/
public static boolean saveDocument(Document doc, File f)
{
if ((doc == null) || (f == null))
{
System.err.println("XMLUtil.saveDocument(...) error: specified document or file is null !");
return false;
}
final Transformer transformer = createTransformer();
// an error occurred
if (transformer == null)
return false;
doc.normalizeDocument();
final DocumentType doctype = doc.getDoctype();
final DOMSource domSource = new DOMSource(doc);
final StreamResult streamResult = new StreamResult(f.getAbsolutePath());
try
{
if (doctype != null)
{
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctype.getPublicId());
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctype.getSystemId());
}
transformer.transform(domSource, streamResult);
return true;
}
catch (Exception e)
{
IcyExceptionHandler.showErrorMessage(e, true);
}
return false;
}
/**
* Return the XML String from the specified document.
*
* @throws TransformerException
*/
public static String getXMLString(Document document) throws TransformerException
{
if (document == null)
return "";
final Transformer transformer = createTransformerSafe();
final StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(document), new StreamResult(writer));
return writer.toString();
}
/**
* Create root element for specified document if it does not already exist and return it
*/
public static Element createRootElement(Document doc)
{
return createRootElement(doc, NODE_ROOT_NAME);
}
/**
* Create root element for specified document if it does not already exist and return it
*/
public static Element createRootElement(Document doc, String name)
{
return getRootElement(doc, true, name);
}
/**
* Return the root element for specified document<br>
* Create if it does not already exist with the specified name
*/
private static Element getRootElement(Document doc, boolean create, String name)
{
if (doc != null)
{
Element result = doc.getDocumentElement();
if ((result == null) && create)
{
result = doc.createElement(name);
doc.appendChild(result);
}
return result;
}
return null;
}
/**
* Return the root element for specified document<br>
* Create if it does not already exist with the default {@link #NODE_ROOT_NAME}
*/
public static Element getRootElement(Document doc, boolean create)
{
return getRootElement(doc, create, NODE_ROOT_NAME);
}
/**
* Return the root element for specified document (null if not found)<br>
*/
public static Element getRootElement(Document doc)
{
return getRootElement(doc, false);
}
/**
* Get parent element of specified element
*/
public static Element getParentElement(Element element)
{
Node parent = element.getParentNode();
while (parent != null)
{
if (parent instanceof Element)
return (Element) parent;
parent = parent.getParentNode();
}
return null;
}
/**
* Get all child node of specified node.
*/
@SuppressWarnings("null")
public static ArrayList<Node> getChildren(Node node)
{
final ArrayList<Node> result = new ArrayList<Node>();
int tries = 3;
RuntimeException exception = null;
// sometime the XML library fails so we make several attempts
while (tries > 0)
{
try
{
final NodeList nodeList = node.getChildNodes();
if (nodeList != null)
{
for (int i = 0; i < nodeList.getLength(); i++)
{
final Node n = nodeList.item(i);
if (n != null)
result.add(n);
}
}
return result;
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* Get the first child node with specified name from node.<br>
* Return null if not found.
*/
@SuppressWarnings("null")
public static Node getChild(Node node, String name)
{
int tries = 3;
RuntimeException exception = null;
// have to make several attempts as sometime XML library fails to correctly retrieve XML data
while (tries > 0)
{
final NodeList nodeList = node.getChildNodes();
try
{
if (nodeList != null)
{
for (int i = 0; i < nodeList.getLength(); i++)
{
final Node n = nodeList.item(i);
if ((n != null) && n.getNodeName().equals(name))
return n;
}
}
return null;
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* Get all child nodes with specified name from node.
*/
@SuppressWarnings("null")
public static ArrayList<Node> getChildren(Node node, String name)
{
final ArrayList<Node> result = new ArrayList<Node>();
int tries = 3;
RuntimeException exception = null;
// have to make several attempts as sometime XML library fails to correctly retrieve XML data
while (tries > 0)
{
final NodeList nodeList = node.getChildNodes();
try
{
if (nodeList != null)
{
for (int i = 0; i < nodeList.getLength(); i++)
{
final Node n = nodeList.item(i);
if ((n != null) && n.getNodeName().equals(name))
result.add(n);
}
}
return result;
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* @deprecated Use {@link #getChildren(Node)} instead.
*/
@Deprecated
public static ArrayList<Node> getSubNodes(Node node)
{
return getChildren(node);
}
/**
* @deprecated Use {@link #getChild(Node, String)} instead.
*/
@Deprecated
public static Node getSubNode(Node node, String name)
{
return getChild(node, name);
}
/**
* @deprecated Use {@link #getChildren(Node, String)} instead.
*/
@Deprecated
public static ArrayList<Node> getSubNodes(Node node, String name)
{
return getChildren(node, name);
}
/**
* Get all child element of specified node.
*/
@SuppressWarnings("null")
public static ArrayList<Element> getElements(Node node)
{
final ArrayList<Element> result = new ArrayList<Element>();
int tries = 3;
RuntimeException exception = null;
// have to make several attempts as sometime XML library fails to correctly retrieve XML data
while (tries > 0)
{
final NodeList nodeList = node.getChildNodes();
try
{
if (nodeList != null)
{
for (int i = 0; i < nodeList.getLength(); i++)
{
final Node n = nodeList.item(i);
if (n instanceof Element)
result.add((Element) n);
}
}
return result;
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* Get the first child element with specified name from node.<br>
* Return null if not found.
*/
@SuppressWarnings("null")
public static Element getElement(Node node, String name)
{
if (node == null)
return null;
final String filteredName = filterString(name);
int tries = 3;
RuntimeException exception = null;
// have to make several attempts as sometime XML library fails to correctly retrieve XML data
while (tries > 0)
{
try
{
final NodeList nodeList = node.getChildNodes();
if (nodeList != null)
{
for (int i = 0; i < nodeList.getLength(); i++)
{
final Node n = nodeList.item(i);
if ((n instanceof Element) && n.getNodeName().equals(filteredName))
return (Element) n;
}
}
return null;
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* Get all child element with specified name of specified node.
*/
@SuppressWarnings("null")
public static ArrayList<Element> getElements(Node node, String name)
{
final ArrayList<Element> result = new ArrayList<Element>();
final String filteredName = filterString(name);
int tries = 3;
RuntimeException exception = null;
// have to make several attempts as sometime XML library fails to correctly retrieve XML data
while (tries > 0)
{
final NodeList nodeList = node.getChildNodes();
try
{
if (nodeList != null)
{
for (int i = 0; i < nodeList.getLength(); i++)
{
final Node n = nodeList.item(i);
if ((n instanceof Element) && n.getNodeName().equals(filteredName))
result.add((Element) n);
}
}
return result;
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* @deprecated Use {@link #getElements(Node)} instead.
*/
@Deprecated
public static ArrayList<Element> getSubElements(Node node)
{
return getElements(node);
}
/**
* @deprecated Use {@link #getElement(Node, String)} instead.
*/
@Deprecated
public static Element getSubElement(Node node, String name)
{
return getElement(node, name);
}
/**
* @deprecated Use {@link #getElements(Node, String)} instead.
*/
@Deprecated
public static ArrayList<Element> getSubElements(Node node, String name)
{
return getElements(node, name);
}
/**
* Get all child element with specified type (name) from specified node.
*/
@SuppressWarnings("null")
public static ArrayList<Element> getGenericElements(Node node, String type)
{
final ArrayList<Element> result = new ArrayList<Element>();
final String filteredType = filterString(type);
int tries = 3;
RuntimeException exception = null;
// have to make several attempts as sometime XML library fails to correctly retrieve XML data
while (tries > 0)
{
final NodeList nodeList = node.getChildNodes();
try
{
if (nodeList != null)
{
for (int i = 0; i < nodeList.getLength(); i++)
{
final Node n = nodeList.item(i);
if ((n instanceof Element) && n.getNodeName().equals(filteredType))
result.add((Element) n);
}
}
return result;
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* Get all child element with specified type (name) and name ('name attribute value')
* from specified node.
*/
@SuppressWarnings("null")
public static ArrayList<Element> getGenericElements(Node node, String type, String name)
{
final ArrayList<Element> result = new ArrayList<Element>();
final String filteredName = filterString(name);
final String filteredType = filterString(type);
int tries = 3;
RuntimeException exception = null;
// have to make several attempts as sometime XML library fails to correctly retrieve XML data
while (tries > 0)
{
final NodeList nodeList = node.getChildNodes();
try
{
if (nodeList != null)
{
for (int i = 0; i < nodeList.getLength(); i++)
{
final Node n = nodeList.item(i);
if ((n instanceof Element) && n.getNodeName().equals(filteredType))
{
final Element element = (Element) n;
if (element.getAttribute(ATTR_NAME_NAME).equals(filteredName))
result.add(element);
}
}
}
return result;
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* @deprecated Use {@link #getGenericElements(Node, String)} instead.
*/
@Deprecated
public static ArrayList<Element> getSubGenericElements(Node node, String type)
{
return getGenericElements(node, type);
}
/**
* @deprecated Use {@link #getGenericElements(Node, String, String)} instead.
*/
@Deprecated
public static ArrayList<Element> getSubGenericElements(Node node, String type, String name)
{
return getGenericElements(node, type, name);
}
/**
* Get child element with specified type (name) and name ('name attribute value')
* from specified node.
*/
@SuppressWarnings("null")
public static Element getGenericElement(Node node, String type, String name)
{
final String filteredName = filterString(name);
final String filteredType = filterString(type);
int tries = 3;
RuntimeException exception = null;
// have to make several attempts as sometime XML library fails to correctly retrieve XML data
while (tries > 0)
{
final NodeList nodeList = node.getChildNodes();
try
{
if (nodeList != null)
{
for (int i = 0; i < nodeList.getLength(); i++)
{
final Node n = nodeList.item(i);
if ((n instanceof Element) && n.getNodeName().equals(filteredType))
{
final Element element = (Element) n;
if (element.getAttribute(ATTR_NAME_NAME).equals(filteredName))
return element;
}
}
}
return null;
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* Get name of specified generic element
*/
public static String getGenericElementName(Element element)
{
if (element != null)
return element.getAttribute(ATTR_NAME_NAME);
return "";
}
/**
* Get value of specified generic element
*/
public static String getGenericElementValue(Element element, String def)
{
return getAttributeValue(element, ATTR_VALUE_NAME, def);
}
/**
* Get all attributes of the specified element
*/
public static ArrayList<Attr> getAllAttributes(Element element)
{
final NamedNodeMap nodeMap = element.getAttributes();
final ArrayList<Attr> result = new ArrayList<Attr>();
for (int i = 0; i < nodeMap.getLength(); i++)
result.add((Attr) nodeMap.item(i));
return result;
}
private static boolean getBoolean(String value, boolean def)
{
return StringUtil.parseBoolean(value, def);
}
private static int getInt(String value, int def)
{
return StringUtil.parseInt(value, def);
}
private static long getLong(String value, long def)
{
return StringUtil.parseLong(value, def);
}
private static float getFloat(String value, float def)
{
return StringUtil.parseFloat(value, def);
}
private static double getDouble(String value, double def)
{
return StringUtil.parseDouble(value, def);
}
private static byte[] getBytes(String value, byte[] def) throws DataFormatException
{
if (value == null)
return def;
// get packed byte data
final byte[] result = (byte[]) ArrayUtil.stringToArray1D(value, DataType.BYTE, true, ":");
synchronized (inflater)
{
// unpack and return
return ZipUtil.unpack(inflater, result);
}
}
private static String toString(boolean value)
{
return StringUtil.toString(value);
}
private static String toString(int value)
{
return StringUtil.toString(value);
}
private static String toString(long value)
{
return StringUtil.toString(value);
}
private static String toString(float value)
{
return StringUtil.toString(value);
}
private static String toString(double value)
{
return StringUtil.toString(value);
}
private static String toString(byte[] value)
{
final byte[] packed;
synchronized (deflater)
{
packed = ZipUtil.pack(deflater, value, -1);
}
// pack data and convert to string
return ArrayUtil.array1DToString(packed, false, true, ":", -1);
}
/**
* Get an attribute from the specified Element
*/
public static Attr getAttribute(Element element, String attribute)
{
if (element != null)
return element.getAttributeNode(attribute);
return null;
}
/**
* Get attribute value from the specified Element.<br>
* If no attribute found 'def' value is returned.
*/
@SuppressWarnings("null")
public static String getAttributeValue(Element element, String attribute, String def)
{
if (element == null)
return def;
final String filteredAttr = filterString(attribute);
int tries = 3;
RuntimeException exception = null;
// sometime the XML library fails so we make several attempts
while (tries > 0)
{
try
{
final Attr attr = element.getAttributeNode(filteredAttr);
if (attr != null)
return attr.getValue();
return def;
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* Get attribute value as Boolean from the specified Element.<br>
* If no attribute found 'def' value is returned.
*/
public static boolean getAttributeBooleanValue(Element element, String attribute, boolean def)
{
return getBoolean(getAttributeValue(element, attribute, ""), def);
}
/**
* Get attribute value as byte array from the specified Element.<br>
* If the attribute is not found 'def' value is returned.<br>
* If an error occurred or if element is <code>null</code> then <code>null</code> is returned.
*/
public static byte[] getAttributeBytesValue(Element element, String attribute, byte[] def)
{
try
{
return getBytes(getAttributeValue(element, attribute, ""), def);
}
catch (Exception e)
{
if (e instanceof RuntimeException)
throw (RuntimeException) e;
IcyExceptionHandler.showErrorMessage(e, true);
return null;
}
}
/**
* Get attribute value as integer from the specified Element.<br>
* If no attribute found 'def' value is returned.
*/
public static int getAttributeIntValue(Element element, String attribute, int def)
{
return getInt(getAttributeValue(element, attribute, ""), def);
}
/**
* Get attribute value as long from the specified Element.<br>
* If no attribute found 'def' value is returned.
*/
public static long getAttributeLongValue(Element element, String attribute, long def)
{
return getLong(getAttributeValue(element, attribute, ""), def);
}
/**
* Get attribute value as float from the specified Element.<br>
* If no attribute found 'def' value is returned.
*/
public static float getAttributeFloatValue(Element element, String attribute, float def)
{
return getFloat(getAttributeValue(element, attribute, ""), def);
}
/**
* Get attribute value as double from the specified Element.<br>
* If no attribute found 'def' value is returned.
*/
public static double getAttributeDoubleValue(Element element, String attribute, double def)
{
return getDouble(getAttributeValue(element, attribute, ""), def);
}
/**
* Get first value (value of first child) from the specified Element.<br>
* If no value found 'def' value is returned.
*/
@SuppressWarnings("null")
public static String getFirstValue(Element element, String def)
{
if (element == null)
return def;
int tries = 3;
RuntimeException exception = null;
// sometime the XML library fails so we make several attempts
while (tries > 0)
{
try
{
final Node child = element.getFirstChild();
if (child != null)
return child.getNodeValue();
return def;
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* Get all values (value of all child) from the specified Element.<br>
* If no value found 'def' value is returned.
*/
@SuppressWarnings("null")
public static String getAllValues(Element element, String def)
{
if (element == null)
return def;
int tries = 3;
RuntimeException exception = null;
// sometime the XML library fails so we make several attempts
while (tries > 0)
{
try
{
final StringBuilder str = new StringBuilder();
Node child = element.getFirstChild();
while (child != null)
{
str.append(child.getNodeValue());
child = child.getNextSibling();
}
return str.toString();
}
catch (RuntimeException e)
{
// try again
exception = e;
tries--;
}
}
throw exception;
}
/**
* Get all values (value of all child) as String from the specified Element.<br>
* If no value found 'def' value is returned.
*/
public static String getValue(Element element, String def)
{
return getAllValues(element, def);
}
/**
* Get all values (value of all child) as Boolean from the specified Element.
*/
public static boolean getBooleanValue(Element element, boolean def)
{
return getBoolean(getFirstValue(element, ""), def);
}
/**
* Get value as integer from the specified Element.<br>
* If no integer value found 'def' value is returned.
*/
public static int getIntValue(Element element, int def)
{
return getInt(getFirstValue(element, ""), def);
}
/**
* Get value as long from the specified Element.<br>
* If no integer value found 'def' value is returned.
*/
public static long getLongValue(Element element, long def)
{
return getLong(getFirstValue(element, ""), def);
}
/**
* Get value as float from the specified Element.<br>
* If no float value found 'def' value is returned.
*/
public static float getFloatValue(Element element, float def)
{
return getFloat(getFirstValue(element, ""), def);
}
/**
* Get value as double from the specified Element.<br>
* If no double value found 'def' value is returned.
*/
public static double getDoubleValue(Element element, double def)
{
return getDouble(getFirstValue(element, ""), def);
}
/**
* Get value as byte array from the specified Element.<br>
* If no byte array value found 'def' value is returned.<br>
* Return <code>null</code> if an error happened.
*/
public static byte[] getBytesValue(Element element, byte[] def)
{
try
{
return getBytes(getFirstValue(element, ""), def);
}
catch (Exception e)
{
if (e instanceof RuntimeException)
throw (RuntimeException) e;
IcyExceptionHandler.showErrorMessage(e, true);
return null;
}
}
/**
* Get first element value from the specified node.<br>
* If no value found 'def' value is returned.
*/
public static String getElementFirstValue(Node node, String name, String def)
{
return getFirstValue(getElement(node, name), def);
}
/**
* Get all element values from the specified node.<br>
* If no value found 'def' value is returned.
*/
public static String getElementAllValues(Node node, String name, String def)
{
return getAllValues(getElement(node, name), def);
}
/**
* Get element value as string from the specified node.<br>
* If no value found 'def' value is returned.
*/
public static String getElementValue(Node node, String name, String def)
{
return getValue(getElement(node, name), def);
}
/**
* Get element value as boolean from the specified node.
*/
public static boolean getElementBooleanValue(Node node, String name, boolean def)
{
return getBoolean(getElementValue(node, name, ""), def);
}
/**
* Get element value as integer from the specified node.<br>
* If no integer value found 'def' value is returned.
*/
public static int getElementIntValue(Node node, String name, int def)
{
return getInt(getElementValue(node, name, ""), def);
}
/**
* Get element value as long from the specified node.<br>
* If no integer value found 'def' value is returned.
*/
public static long getElementLongValue(Node node, String name, long def)
{
return getLong(getElementValue(node, name, ""), def);
}
/**
* Get element value as float from the specified node.<br>
* If no float value found 'def' value is returned.
*/
public static float getElementFloatValue(Node node, String name, float def)
{
return getFloat(getElementValue(node, name, ""), def);
}
/**
* Get element value as double from the specified node.<br>
* If no double value found 'def' value is returned.
*/
public static double getElementDoubleValue(Node node, String name, double def)
{
return getDouble(getElementValue(node, name, ""), def);
}
/**
* Get element value as byte array from the specified node.<br>
* If no byte array value found 'def' value is returned.<br>
* Return <code>null</code> if an error happened.
*/
public static byte[] getElementBytesValue(Node node, String name, byte[] def)
{
try
{
return getBytes(getElementValue(node, name, ""), def);
}
catch (Exception e)
{
if (e instanceof RuntimeException)
throw (RuntimeException) e;
IcyExceptionHandler.showErrorMessage(e, true);
return null;
}
}
/**
* Get value ('value' attribute value) from element with specified type
* and name ('name' attribute value).<br>
* If no value found 'def' value is returned.
*/
public static String getGenericElementValue(Node node, String type, String name, String def)
{
return getGenericElementValue(getGenericElement(node, type, name), def);
}
/**
* Get value ('value' attribute value) as boolean from element with specified type
* and name ('name' attribute value).<br>
* If no byte array value found 'def' value is returned.
*/
public static boolean getGenericElementBooleanValue(Node node, String type, String name, boolean def)
{
return getBoolean(getGenericElementValue(node, type, name, ""), def);
}
/**
* Get value ('value' attribute value) as integer from element with specified type
* and name ('name' attribute value).<br>
* If no integer value found 'def' value is returned.
*/
public static int getGenericElementIntValue(Node node, String type, String name, int def)
{
return getInt(getGenericElementValue(node, type, name, ""), def);
}
/**
* Get value ('value' attribute value) as long from element with specified type
* and name ('name' attribute value).<br>
* If no integer value found 'def' value is returned.
*/
public static long getGenericElementLongValue(Node node, String type, String name, long def)
{
return getLong(getGenericElementValue(node, type, name, ""), def);
}
/**
* Get value ('value' attribute value) as float from element with specified type
* and name ('name' attribute value).<br>
* If no float value found 'def' value is returned.
*/
public static float getGenericElementFloatValue(Node node, String type, String name, float def)
{
return getFloat(getGenericElementValue(node, type, name, ""), def);
}
/**
* Get value ('value' attribute value) as double from element with specified type
* and name ('name' attribute value).<br>
* If no double value found 'def' value is returned.
*/
public static double getGenericElementDoubleValue(Node node, String type, String name, double def)
{
return getDouble(getGenericElementValue(node, type, name, ""), def);
}
/**
* Get value ('value' attribute value) as byte array from element with specified type
* and name ('name' attribute value).<br>
* If no byte array value found 'def' value is returned.<br>
* Return <code>null</code> if an error happened.
*/
public static byte[] getGenericElementBytesValue(Node node, String type, String name, byte[] def)
{
try
{
return getBytes(getElementValue(node, name, ""), def);
}
catch (Exception e)
{
if (e instanceof RuntimeException)
throw (RuntimeException) e;
IcyExceptionHandler.showErrorMessage(e, true);
return null;
}
}
/**
* Add the specified node to specified parent node
*/
public static Node addNode(Node parent, Node node)
{
return parent.appendChild(node);
}
/**
* Add a value to the specified node
*/
public static Node addValue(Node node, String value)
{
final Node newNode;
final String filteredValue = filterString(value);
if (node instanceof Document)
newNode = ((Document) node).createTextNode(filteredValue);
else
newNode = node.getOwnerDocument().createTextNode(filteredValue);
if (newNode != null)
node.appendChild(newNode);
return newNode;
}
/**
* Add a named element to the specified node
*/
public static Element addElement(Node node, String name)
{
final Element element;
final String filteredName = filterString(name);
if (node instanceof Document)
element = ((Document) node).createElement(filteredName);
else
element = node.getOwnerDocument().createElement(filteredName);
node.appendChild(element);
return element;
}
/**
* Add a named element with a value to the specified node
*/
public static Element addElement(Node node, String name, String value)
{
final Element element = addElement(node, name);
if (!StringUtil.isEmpty(value))
addValue(element, value);
return element;
}
/**
* Add a generic element with specified type and name to the specified node
*/
public static Element addGenericElement(Node node, String type, String name)
{
final Element element = addElement(node, type);
setGenericElementName(element, name);
return element;
}
/**
* Add a generic element with specified type, name and value to the specified node
*/
public static Element addGenericElement(Node node, String type, String name, String value)
{
final Element element = addElement(node, type);
setGenericElementName(element, name);
setGenericElementValue(element, value);
return element;
}
/**
* Set name of specified generic element
*/
public static void setGenericElementName(Element element, String name)
{
if (element != null)
element.setAttribute(ATTR_NAME_NAME, filterString(name));
}
/**
* Set value of specified generic element
*/
public static void setGenericElementValue(Element element, String value)
{
if (element != null)
element.setAttribute(ATTR_VALUE_NAME, filterString(value));
}
/**
* Set the specified node to the specified parent node.<br>
* The new node replace the previous existing node with the same name.
*/
public static Node setNode(Node parent, Node node)
{
final String name = node.getNodeName();
XMLUtil.removeNode(parent, name);
return XMLUtil.addNode(parent, node);
}
/**
* Set a element with specified name to specified node.<br>
* If the Element was already existing then it's just returned.
*/
public static Element setElement(Node node, String name)
{
// get element
final Element element = getElement(node, name);
if (element != null)
return element;
return addElement(node, name);
}
/**
* Set a generic element with specified type and name to specified node.<br>
* If the generic element was already existing then it's just returned.
*/
public static Element setGenericElement(Node node, String type, String name)
{
// get generic element
final Element element = getGenericElement(node, type, name);
if (element != null)
return element;
return addGenericElement(node, type, name);
}
/**
* Set an attribute and his value to the specified node
*/
public static void setAttributeValue(Element element, String attribute, String value)
{
element.setAttribute(attribute, filterString(value));
}
/**
* Set an attribute and his value as boolean to the specified node
*/
public static void setAttributeBooleanValue(Element element, String attribute, boolean value)
{
setAttributeValue(element, attribute, toString(value));
}
/**
* Set an attribute and his value as integer to the specified node
*/
public static void setAttributeIntValue(Element element, String attribute, int value)
{
setAttributeValue(element, attribute, toString(value));
}
/**
* Set an attribute and his value as integer to the specified node
*/
public static void setAttributeLongValue(Element element, String attribute, long value)
{
setAttributeValue(element, attribute, toString(value));
}
/**
* Set an attribute and his value as float to the specified node
*/
public static void setAttributeFloatValue(Element element, String attribute, float value)
{
setAttributeValue(element, attribute, toString(value));
}
/**
* Set an attribute and his value as double to the specified node
*/
public static void setAttributeDoubleValue(Element element, String attribute, double value)
{
setAttributeValue(element, attribute, toString(value));
}
/**
* Set an attribute and his value as byte array to the specified node
*/
public static void setAttributeBytesValue(Element element, String attribute, byte[] value)
{
setAttributeValue(element, attribute, toString(value));
}
/**
* Set value to the specified element
*/
public static void setValue(Element element, String value)
{
// remove child nodes
removeAllChildren(element);
// add value
addValue(element, value);
}
/**
* Remove all characters that are valid XML markups.
*/
public static String removeXMLMarkups(String s)
{
final StringBuffer out = new StringBuffer();
for (char c : s.toCharArray())
{
if ((c == '\'') || (c == '<') || (c == '>') || (c == '&') || (c == '\"'))
continue;
out.append(c);
}
return out.toString();
}
/**
* Remove any invalid XML character from the specified string.
*/
public static String removeInvalidXMLCharacters(String text)
{
if (text == null)
return "";
final String xml10pattern = "[^" + "\u0009\r\n" + "\u0020-\uD7FF" + "\uE000-\uFFFD"
+ "\ud800\udc00-\udbff\udfff" + "]";
// final String xml11pattern = "[^" + "\u0001-\uD7FF" + "\uE000-\uFFFD" +
// "\ud800\udc00-\udbff\udfff" + "]+";
// some OME generate incorrect "" sequence so we just replace them with "#"
return text.replaceAll(xml10pattern, "").replaceAll("", "#");
}
/**
* Same as {@link #removeInvalidXMLCharacters(String)}
*/
public static String filterString(String text)
{
return removeInvalidXMLCharacters(text);
}
/**
* Set value as boolean to the specified element
*/
public static void setBooleanValue(Element element, boolean value)
{
setValue(element, toString(value));
}
/**
* Set value as integer to the specified element
*/
public static void setIntValue(Element element, int value)
{
setValue(element, toString(value));
}
/**
* Set value as long to the specified element
*/
public static void setLongValue(Element element, long value)
{
setValue(element, toString(value));
}
/**
* Set value as float to the specified element
*/
public static void setFloatValue(Element element, float value)
{
setValue(element, toString(value));
}
/**
* Set value as double to the specified element
*/
public static void setDoubleValue(Element element, double value)
{
setValue(element, toString(value));
}
/**
* Set value as byte array to the specified element
*/
public static void setBytesValue(Element element, byte[] value)
{
setValue(element, toString(value));
}
/**
* Set an element with specified name and his value to the specified node
*/
public static void setElementValue(Node node, String name, String value)
{
// get element (create it if needed)
final Element element = setElement(node, name);
// set value
setValue(element, value);
}
/**
* Set an element with specified name and his value as boolean to the specified node
*/
public static void setElementBooleanValue(Node node, String name, boolean value)
{
setElementValue(node, name, toString(value));
}
/**
* Set an element with specified name and his value as integer to the specified node
*/
public static void setElementIntValue(Node node, String name, int value)
{
setElementValue(node, name, toString(value));
}
/**
* Set an element with specified name and his value as long to the specified node
*/
public static void setElementLongValue(Node node, String name, long value)
{
setElementValue(node, name, toString(value));
}
/**
* Set an element with specified name and his value as float to the specified node
*/
public static void setElementFloatValue(Node node, String name, float value)
{
setElementValue(node, name, toString(value));
}
/**
* Set an element with specified name and his value as double to the specified node
*/
public static void setElementDoubleValue(Node node, String name, double value)
{
setElementValue(node, name, toString(value));
}
/**
* Set an element with specified name and his value as byte array to the specified node
*/
public static void setElementBytesValue(Node node, String name, byte[] value)
{
setElementValue(node, name, toString(value));
}
/**
* Set a generic element with specified type and name and his value to the specified node
*/
public static void setGenericElementValue(Node node, String type, String name, String value)
{
// get generic element (create it if needed)
final Element element = setGenericElement(node, type, name);
if (element != null)
element.setAttribute(ATTR_VALUE_NAME, value);
}
/**
* Set an element with specified type and name and his value as boolean to the specified node
*/
public static void setGenericElementBooleanValue(Node node, String type, String name, boolean value)
{
setGenericElementValue(node, type, name, toString(value));
}
/**
* Set an element with specified type and name and his value as integer to the specified node
*/
public static void setGenericElementIntValue(Node node, String type, String name, int value)
{
setGenericElementValue(node, type, name, toString(value));
}
/**
* Set an element with specified type and name and his value as long to the specified node
*/
public static void setGenericElementLongValue(Node node, String type, String name, long value)
{
setGenericElementValue(node, type, name, toString(value));
}
/**
* Set an element with specified type and name and his value as float to the specified node
*/
public static void setGenericElementFloatValue(Node node, String type, String name, float value)
{
setGenericElementValue(node, type, name, toString(value));
}
/**
* Set an element with specified type and name and his value as double to the specified node
*/
public static void setGenericElementDoubleValue(Node node, String type, String name, double value)
{
setGenericElementValue(node, type, name, toString(value));
}
/**
* Set an element with specified type and name and his value as byte array to the specified node
*/
public static void setGenericElementBytesValue(Node node, String type, String name, byte[] value)
{
setGenericElementValue(node, type, name, toString(value));
}
/**
* Remove a node with specified name from the specified node
*/
public static boolean removeNode(Node node, String name)
{
final Node subNode = getSubNode(node, name);
if (subNode != null)
return removeNode(node, subNode);
return false;
}
/**
* Remove the specified node from the specified parent node
*/
public static boolean removeNode(Node parent, Node child)
{
int tries = 3;
// RuntimeException exception = null;
// have to make several attempts as sometime XML library fails to correctly retrieve XML data
while (tries > 0)
{
try
{
parent.removeChild(child);
return true;
}
catch (RuntimeException e)
{
// exception = e;
tries--;
}
}
// we just ignore here
return false;
}
/**
* @deprecated Use {@link #removeAllChildren(Node)} instead
*/
@Deprecated
public static void removeAllChilds(Node node)
{
removeAllChildren(node);
}
/**
* Remove all children from the specified node
*/
public static void removeAllChildren(Node node)
{
while (node.hasChildNodes())
node.removeChild(node.getLastChild());
}
/**
* @deprecated Use {@link #removeChildren(Node, String)} instead
*/
@Deprecated
public static void removeChilds(Node node, String name)
{
removeChildren(node, name);
}
/**
* Remove all children with specified name from the specified node
*/
public static void removeChildren(Node node, String name)
{
Node currentChild = node.getFirstChild();
while (currentChild != null)
{
final Node nextChild = currentChild.getNextSibling();
if (currentChild.getNodeName().equals(name))
node.removeChild(currentChild);
currentChild = nextChild;
}
}
/**
* Remove an attribute from the specified element
*/
public static void removeAttribute(Element element, String name)
{
element.removeAttribute(name);
}
/**
* Remove all attribute from the specified element
*/
public static void removeAllAttributes(Element element)
{
final NamedNodeMap nodeMap = element.getAttributes();
for (int i = 0; i < nodeMap.getLength(); i++)
element.removeAttribute(nodeMap.item(i).getNodeName());
}
}