Java tutorial
/** * Copyright (C) 2011-2012 Barchart, Inc. <http://www.barchart.com/> * * All rights reserved. Licensed under the OSI BSD License. * * http://www.opensource.org/licenses/bsd-license.php */ package com.barchart.feed.ddf.util; import static com.barchart.feed.ddf.util.HelperDDF.DDF_CLEAR; import static com.barchart.feed.ddf.util.HelperDDF.DDF_EMPTY; import static com.barchart.feed.ddf.util.HelperDDF.byteAsString; import static com.barchart.feed.ddf.util.HelperDDF.fromBinaryToDecimal; import static com.barchart.feed.ddf.util.HelperDDF.fromDecimalToBinary; import static com.barchart.feed.ddf.util.HelperDDF.longDecode; import static com.barchart.feed.ddf.util.HelperDDF.longEncode; import static com.barchart.feed.ddf.util.HelperDDF.priceDecode; import static com.barchart.feed.ddf.util.HelperDDF.priceEncode; import static com.barchart.feed.ddf.util.HelperDDF.timeDecode; import static com.barchart.feed.ddf.util.HelperDDF.timeEncode; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.Attributes; import com.barchart.feed.base.values.api.PriceValue; import com.barchart.feed.base.values.provider.ValueBuilder; import com.barchart.feed.base.values.provider.ValueConst; import com.barchart.feed.ddf.util.enums.DDF_Fraction; import com.barchart.util.common.ascii.ASCII; import com.barchart.util.value.ValueFactoryImpl; import com.barchart.util.value.api.ValueFactory; import com.barchart.util.value.api.Time; // TODO: Auto-generated Javadoc /** * The Class HelperXML. */ public final class HelperXML { static final ValueFactory factory = ValueFactoryImpl.instance; private static Logger log = LoggerFactory.getLogger(HelperXML.class); /** throw exceptions on mandatory xml fields, stops parsing. */ public static final boolean XML_STOP = true; /** no exceptions on optional xml fields, return default instead. */ public static final boolean XML_PASS = !XML_STOP; private HelperXML() { } private static final ThreadLocal<DocumentBuilder> XML_BUILDER = new ThreadLocal<DocumentBuilder>() { @Override protected DocumentBuilder initialValue() { try { final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); return builder; } catch (final Exception e) { throw new RuntimeException(e); } } }; private static final ThreadLocal<Transformer> XML_XFORMER = new ThreadLocal<Transformer>() { @Override protected Transformer initialValue() { try { final Transformer xformer = TransformerFactory.newInstance().newTransformer(); xformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); xformer.setOutputProperty(OutputKeys.INDENT, "no"); return xformer; } catch (final Exception e) { throw new RuntimeException(e); } } }; /** * Xml first child. * * @param parent * the parent * @param childName * the child name * @param isThrow * the is throw * @return the element */ public static final Element xmlFirstChild(final Element parent, final String childName, final boolean isThrow) { final NodeList nodeList = parent.getChildNodes(); if (nodeList == null) { if (isThrow) { throw new IllegalArgumentException("nodeList == null"); } return null; } final int size = nodeList.getLength(); for (int k = 0; k < size; k++) { final Node child = nodeList.item(k); if (child.getNodeName().equalsIgnoreCase(childName)) { return (Element) child; } } if (isThrow) { throw new IllegalArgumentException("child node not found"); } return null; } /** * Xml document decode. * * @param xmlURI * the xml uri * @return the element * @throws Exception * the exception */ public static final Element xmlDocumentDecode(final String xmlURI) throws Exception { return XML_BUILDER.get().parse(xmlURI).getDocumentElement(); } /** * Xml dodument decode. * * @param array * the array * @param start * the start * @param finish * the finish * @param isThrow * the is throw * @return the element */ public static final Element xmlDocumentDecode(final byte[] array, final int start, final int finish, final boolean isThrow) { final InputStream stream = new ByteArrayInputStream(array, start, finish); try { final Document document = XML_BUILDER.get().parse(stream); return document.getDocumentElement(); } catch (final Exception e) { // will return/throw below } if (isThrow) { throw new RuntimeException("can not decode : \n" + new String(array)); } return null; } /** * Xml document encode. * * @param root * the root * @param isThrow * the is throw * @return the byte[] */ public static final byte[] xmlDocumentEncode(final Element root, final boolean isThrow) { final Source source = new DOMSource(root); final StringWriter stream = new StringWriter(); final Result result = new StreamResult(stream); try { XML_XFORMER.get().transform(source, result); final String string = stream.toString(); if (ValueBuilder.isPureAscii(string)) { return string.getBytes(ASCII.ASCII_CHARSET); } } catch (final Exception e) { // will return/throw below } if (isThrow) { throw new RuntimeException("can not encode"); } return null; } /** * Xml string decode. * * @param tag * the tag * @param attribute * the attribute * @param isThrow * the is throw * @return the string */ public static final String xmlStringDecode(final Element tag, final String attribute, final boolean isThrow) { final String string = tag.getAttribute(attribute); if (string.length() > 0) { return string; } if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } return ""; } /** * Xml string decode. * * @param atr * the atr * @param attribute * the attribute * @param isThrow * the is throw * @return the string */ public static final String xmlStringDecode(final Attributes atr, final String attribute, final boolean isThrow) { final String string = atr.getValue(attribute); if (string != null && string.length() > 0) { return string; } if (isThrow) { throw new IllegalArgumentException("String decode - attribute not valid : " + attribute); } return ""; } /** * Xml string encode. * * @param string * the string * @param tag * the tag * @param attribute * the attribute */ public static final void xmlStringEncode(final String string, final Element tag, final String attribute) { tag.setAttribute(attribute, string); } /** * Xml text encode. * * @param text * the text * @param tag * the tag * @param attribute * the attribute */ public static final void xmlTextEncode(final StringBuilder text, final Element tag, final String attribute) { tag.setAttribute(attribute, text.toString()); } /** * Xml new document. * * @param tagName * the tag name * @return the element */ public static final Element xmlNewDocument(final String tagName) { final Document doc = XML_BUILDER.get().newDocument(); final Element tag = doc.createElement(tagName); return tag; } /** * Xml new element. * * @param root * the root * @param tagName * the tag name * @return the element */ public static final Element xmlNewElement(final Element root, final String tagName) { final Document doc = root.getOwnerDocument(); final Element tag = doc.createElement(tagName); return tag; } /** * Xml check tag name. * * @param tag * the tag * @param name * the name */ public static final void xmlCheckTagName(final Element tag, final String name) { final String tagName = tag.getNodeName(); if (!name.equalsIgnoreCase(tagName)) { throw new IllegalArgumentException("no match;" + " actual=" + tagName + " expected=" + name); } } /** * Checks if is xml name match. * * @param root * the root * @param tag * the tag * @return true, if is xml name match */ public static final boolean isXmlNameMatch(final Element root, final String tag) { final String name = root.getNodeName(); return tag.equalsIgnoreCase(name); } /** * Xml integer decode. * * @param tag * the tag * @param attribute * the attribute * @param isThrow * the is throw * @return the int */ public static final int xmlIntegerDecode(final Element tag, final String attribute, final boolean isThrow) { final String string = tag.getAttribute(attribute); if (string.length() > 0) { try { return Integer.parseInt(string); } catch (final Exception e) { // will throw/return below } } if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } return 0; } /** * Xml integer encode. * * @param value * the value * @param tag * the tag * @param attribute * the attribute */ public static final void xmlIntegerEncode(final int value, final Element tag, final String attribute) { final String string = Integer.toString(value); tag.setAttribute(attribute, string); } /** * Xml price decode. * * @param tag * the tag * @param attribute * the attribute * @param isThrow * the is throw * @return the price value */ public static final PriceValue xmlPriceDecode(final Element tag, final String attribute, final boolean isThrow) { try { final String string = tag.getAttribute(attribute); return priceDecode(string); } catch (final Exception e) { // will return/throw below } if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } return ValueConst.NULL_PRICE; } /** * Xml price decode. * * @param ats * the ats * @param attribute * the attribute * @param isThrow * the is throw * @return the price value */ public static final PriceValue xmlPriceDecode(final Attributes ats, final String attribute, final boolean isThrow) { try { final String string = ats.getValue(attribute); return priceDecode(string); } catch (final Exception e) { // will return/throw below } if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } return ValueConst.NULL_PRICE; } /** * Xml price encode. * * @param price * the price * @param tag * the tag * @param attribute * the attribute */ public static final void xmlPriceEncode(final PriceValue price, final Element tag, final String attribute) { final String string = priceEncode(price); tag.setAttribute(attribute, string); } /** * Xml byte decode. * * @param tag * the tag * @param attribute * the attribute * @param isThrow * the is throw * @return the byte */ public static final byte xmlByteDecode(final Element tag, final String attribute, final boolean isThrow) { final String string = tag.getAttribute(attribute); if (string.length() > 0 && string.length() == 1) { return (byte) string.charAt(0); } if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } return ASCII.NUL; } /** * Xml byte decode. * * @param atr * the atr * @param attribute * the attribute * @param isThrow * the is throw * @return the byte */ public static final byte xmlByteDecode(final Attributes atr, final String attribute, final boolean isThrow) { final String string = atr.getValue(attribute); if (string.length() > 0 && string.length() == 1) { return (byte) string.charAt(0); } if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } return ASCII.NUL; } // decimal array /** * Xml decimal array decode. * * @param tag * the tag * @param attribute * the attribute * @param marker * the marker * @param frac * the frac * @param isThrow * the is throw * @return the long[] */ public static final long[] xmlDecimalArrayDecode(final Element tag, final String attribute, final byte marker, final DDF_Fraction frac, final boolean isThrow) { final long[] array = HelperXML.xmlLongArrayDecode(tag, attribute, marker, isThrow); final int size = array.length; if (frac.isBinary) { for (int k = 0; k < size; k++) { array[k] = fromBinaryToDecimal(array[k], frac); } } return array; } // long array /** * Xml long array decode. * * @param tag * the tag * @param attribute * the attribute * @param marker * the marker * @param isThrow * the is throw * @return the long[] */ public static final long[] xmlLongArrayDecode(final Element tag, final String attribute, final byte marker, final boolean isThrow) { final String string = tag.getAttribute(attribute); if (string.length() > 0) { try { final String[] source = string.split(HelperDDF.byteAsString(marker)); final int size = source.length; final long[] target = new long[size]; for (int k = 0; k < size; k++) { target[k] = longDecode(source[k]); } return target; } catch (final Exception e) { // will throw/return below } } if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } return null; } /** * Xml ascii decode. * * @param tag * the tag * @param attribute * the attribute * @param isThrow * the is throw * @return the byte[] */ public static final byte[] xmlAsciiDecode(final Element tag, final String attribute, final boolean isThrow) { final String string = tag.getAttribute(attribute); if (string.length() > 0) { return string.getBytes(ASCII.ASCII_CHARSET); } if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } return null; } /** * Xml ascii encode. * * @param array * the array * @param tag * the tag * @param attribute * the attribute */ public static final void xmlAsciiEncode(final byte[] array, final Element tag, final String attribute) { if (array == null) { return; } tag.setAttribute(attribute, new String(array, ASCII.ASCII_CHARSET)); } /** * Xml byte encode. * * @param code * the code * @param tag * the tag * @param attribute * the attribute */ public static final void xmlByteEncode(final byte code, final Element tag, final String attribute) { final String string = byteAsString(code); tag.setAttribute(attribute, string); } /** * Xml time decode. * * @param tag * the tag * @param attribute * the attribute * @param isThrow * the is throw * @return the time value */ public static final Time xmlTimeDecode(final Element tag, final String attribute, final boolean isThrow) { final String timeValue = xmlStringDecode(tag, attribute, isThrow); if (timeValue == null || timeValue.length() == 0) { return Time.NULL; } try { final DateTime dateTime = new DateTime(timeValue); return factory.newTime(dateTime.getMillis(), ""); } catch (final Exception e) { if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } else { return Time.NULL; } } } /** * Xml time decode. * * @param atr * the atr * @param attribute * the attribute * @param isThrow * the is throw * @return the time value */ public static final Time xmlTimeDecode(final Attributes atr, final String attribute, final boolean isThrow) { final String timeValue = xmlStringDecode(atr, attribute, isThrow); if (timeValue == null || timeValue.length() == 0) { return Time.NULL; } try { final DateTime dateTime = new DateTime(timeValue); return factory.newTime(dateTime.getMillis(), ""); } catch (final Exception e) { if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } else { return Time.NULL; } } } /** * Xml time decode. * * @param zone * the zone * @param tag * the tag * @param attribute * the attribute * @param isThrow * the is throw * @return the long */ public static final long xmlTimeDecode(final DateTimeZone zone, final Element tag, final String attribute, final boolean isThrow) { final long timeValue = xmlLongDecode(tag, attribute, isThrow); if (timeValue == DDF_EMPTY || timeValue == DDF_CLEAR) { return timeValue; } return timeDecode(timeValue, zone); } /** * Xml time encode. * * @param millisUTC * the millis utc * @param zone * the zone * @param tag * the tag * @param attribute * the attribute */ public static final void xmlTimeEncode(final long millisUTC, final DateTimeZone zone, final Element tag, final String attribute) { if (millisUTC == DDF_EMPTY || millisUTC == DDF_CLEAR) { xmlLongEncode(millisUTC, tag, attribute); return; } final long timeValue = timeEncode(millisUTC, zone); xmlLongEncode(timeValue, tag, attribute); } /** * Xml long decode. * * @param tag * the tag * @param attribute * the attribute * @param isThrow * the is throw * @return the long */ public static final long xmlLongDecode(final Element tag, final String attribute, final boolean isThrow) { final String string = tag.getAttribute(attribute); if (string.length() > 0) { try { // will return DDF_CLEAR for STRING_DASH return longDecode(string); } catch (final Exception e) { // will throw/return below } } if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } return DDF_EMPTY; } /** * Xml long decode. * * @param ats * the ats * @param attribute * the attribute * @param isThrow * the is throw * @return the long */ public static final long xmlLongDecode(final Attributes ats, final String attribute, final boolean isThrow) { final String string = ats.getValue(attribute); if (string.length() > 0) { try { // will return DDF_CLEAR for STRING_DASH return longDecode(string); } catch (final Exception e) { // will throw/return below } } if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } return DDF_EMPTY; } /** * Xml long encode. * * @param value * the value * @param tag * the tag * @param attribute * the attribute */ public static final void xmlLongEncode(final long value, final Element tag, final String attribute) { if (value == DDF_EMPTY) { // skip attribute return; } if (value == DDF_CLEAR) { tag.setAttribute(attribute, ASCII.STRING_DASH); return; } final String string = longEncode(value); tag.setAttribute(attribute, string); } /** * Xml decimal decode. * * @param frac * the frac * @param tag * the tag * @param attribute * the attribute * @param isThrow * the is throw * @return the long */ public static final long xmlDecimalDecode(final DDF_Fraction frac, final Element tag, final String attribute, final boolean isThrow) { long mantissa = xmlLongDecode(tag, attribute, isThrow); mantissa = fromBinaryToDecimal(mantissa, frac); return mantissa; } /** * Xml decimal decode. * * @param frac * the frac * @param ats * the ats * @param attribute * the attribute * @param isThrow * the is throw * @return the long */ public static final long xmlDecimalDecode(final DDF_Fraction frac, final Attributes ats, final String attribute, final boolean isThrow) { long mantissa = xmlLongDecode(ats, attribute, isThrow); mantissa = fromBinaryToDecimal(mantissa, frac); return mantissa; } /** * Xml decimal encode. * * @param mantissa * the mantissa * @param frac * the frac * @param tag * the tag * @param attribute * the attribute */ public static final void xmlDecimalEncode(/* local */long mantissa, final DDF_Fraction frac, final Element tag, final String attribute) { mantissa = fromDecimalToBinary(mantissa, frac); xmlLongEncode(mantissa, tag, attribute); } /** * Xml integer array decode. * * @param tag * the tag * @param attribute * the attribute * @param marker * the marker * @param isThrow * the is throw * @return the int[] */ public static final int[] xmlIntegerArrayDecode(final Element tag, final String attribute, final byte marker, final boolean isThrow) { final String string = tag.getAttribute(attribute); if (string.length() > 0) { try { final String[] source = string.split(HelperDDF.byteAsString(marker)); final int size = source.length; final int[] target = new int[size]; for (int k = 0; k < size; k++) { target[k] = Integer.parseInt(source[k]); } return target; } catch (final Exception e) { // will throw/return below } } if (isThrow) { throw new IllegalArgumentException("attribute not valid : " + attribute); } return null; } /** * Log. * * @param attributes * the attributes */ public static void log(final Attributes attributes) { final int size = attributes.getLength(); for (int index = 0; index < size; index++) { final String name = attributes.getLocalName(index); final String value = attributes.getValue(index); log.debug("attribute : {}={}", name, value); } } }