Java tutorial
/*********************************************************** Copyright (C) 2004 VeriSign, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA http://www.verisign.com/nds/naming/namestore/techdocs.html ***********************************************************/ package com.verisign.epp.codec.gen; import com.verisign.epp.util.EPPCatFactory; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import org.apache.xerces.dom.DocumentImpl; import org.w3c.dom.*; import javax.xml.bind.DatatypeConverter; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.ByteArrayOutputStream; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.*; /** * Provides a set of utility static methods for use by the EPP Codec classes. */ public class EPPUtil { /** Default format used for the XML Schema <code>dateTime</code> data type */ public static final String DEFAULT_TIME_INSTANT_FORMAT = "yyyy-MM-dd'T'HH':'mm':'ss'.'SSS'Z'"; /** * Format used for the XML Schema <code>dateTime</code> data type in the * {@link #encodeTimeInstant(Date) and #encodeTimeInstant(Document, Element, * Date, String, String)} methods supported by the {@link SimpleDateFormat}. */ private static String timeInstantFormat = DEFAULT_TIME_INSTANT_FORMAT; /** Format used for the XML Schema date data type. */ public static final String DATE_FORMAT = "yyyy-MM-dd"; /** Log4j category for logging */ private static Logger cat = Logger.getLogger(EPPUtil.class.getName(), EPPCatFactory.getInstance().getFactory()); /** * Used to format decimal values according to the US locale to remove locale * specific impacts when encoding decimal values. */ private static DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(Locale.US); /** * Gets the XML Schema <code>timeDate</code> format used * in {@link #encodeTimeInstant(Date) and #encodeTimeInstant(Document, Element, * Date, String, String)}. The defauLt format is defined by the constant * {@link #DEFAULT_TIME_INSTANT_FORMAT} and it can be overridden using * the {@link #setTimeInstantFormat(String)} method. * * @return XML Schema <code>timeDate</code> format used * in {@link #encodeTimeInstant(Date) and #encodeTimeInstant(Document, Element, * Date, String, String)}. */ public static String getTimeInstantFormat() { return timeInstantFormat; } /** * Sets the XML Schema <code>timeDate</code> format used * in {@link #encodeTimeInstant(Date) and #encodeTimeInstant(Document, Element, * Date, String, String)}. The format must follow the format * supported by {@link SimpleDateFormat}. * * @param aTimeInstantFormat XML Schema <code>timeDate</code> format * supported by {@link SimpleDateFormat}. */ public static void setTimeInstantFormat(String aTimeInstantFormat) { timeInstantFormat = aTimeInstantFormat; } /** * Appends the children Nodes of <code>aSource</code> as children nodes of * <code>aDest</code>. * * @param aSource * Source Element tree to get children from * @param aDest * Destination Element to append <code>aSource</code> children. */ public static void appendChildren(Element aSource, Element aDest) { NodeList children = aSource.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { aDest.appendChild(children.item(i).cloneNode(true)); } } // End EPPUtil.encodeDate(Date) /** * Decode <code>BigDecimal</code>, by XML namespace and tag name, from an * XML Element. The children elements of <code>aElement</code> will be * searched for the specified <code>aNS</code> namespace URI and the * specified <code>aTagName</code>. The first XML element found will be * decoded and returned. If no element is found, <code>null</code> is * returned. * * @param aElement * XML Element to scan. For example, the element could be * <domain:create> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name is * "domain:name". * @return <code>BigDecimal</code> value if found; <code>null</code> * otherwise. * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static BigDecimal decodeBigDecimal(Element aElement, String aNS, String aTagName) throws EPPDecodeException { Element theElm = EPPUtil.getElementByTagNameNS(aElement, aNS, aTagName); BigDecimal retBigDecimal = null; if (theElm != null) { Node textNode = theElm.getFirstChild(); // Element does have a text node? if (textNode != null) { String doubleValStr = textNode.getNodeValue(); try { Double tempDouble = Double.valueOf(doubleValStr); retBigDecimal = new BigDecimal(tempDouble.doubleValue()); retBigDecimal = retBigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP); } catch (NumberFormatException e) { throw new EPPDecodeException("Can't convert value to Double: " + doubleValStr + e); } } else { throw new EPPDecodeException("Can't decode numeric value from non-existant text node"); } } return retBigDecimal; } // End EPPUtil.decodeDate(String) /** * Decode <code>Boolean</code>, by XML namespace and tag name, from an XML * Element. The children elements of <code>aElement</code> will be searched * for the specified <code>aNS</code> namespace URI and the specified * <code>aTagName</code>. The first XML element found will be decoded and * returned. If no element is found, <code>null</code> is returned. * * @param aElement * XML Element to scan. For example, the element could be * <domain:create> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name is * "domain:name". * @return <code>Boolean</code> value if found; <code>null</code> otherwise. * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static Boolean decodeBoolean(Element aElement, String aNS, String aTagName) throws EPPDecodeException { Boolean retVal = null; String theVal = null; Element theElm = EPPUtil.getElementByTagNameNS(aElement, aNS, aTagName); if (theElm != null) { Node textNode = theElm.getFirstChild(); // Element does have a text node? if (textNode != null) { theVal = textNode.getNodeValue(); if (theVal.equalsIgnoreCase("true") || theVal.equals("1")) { retVal = new Boolean(true); } else { retVal = new Boolean(false); } } else { retVal = null; } } return retVal; } // End EPPUtil.encodeTimeInstant(Date) /** * Decodes a boolean attribute value given the <code>Element</code> and * attribute name. * * @param aElement * Element with the attribute to look for * @param aAttr * Attribute name * @return Decoded boolean value * @exception EPPDecodeException * Cound not find attribute or the attribute value is not a * valid boolean value */ public static boolean decodeBooleanAttr(Element aElement, String aAttr) throws EPPDecodeException { boolean theRet = false; String theAttrVal = aElement.getAttribute(aAttr); if (theAttrVal == null) { throw new EPPDecodeException("EPPUtil.decodeBooleanAttr: Could not find attr " + aAttr); } if (theAttrVal.equals("1") || theAttrVal.equals("true")) { theRet = true; } else if (theAttrVal.equals("0") || theAttrVal.equals("false")) { theRet = false; } else { throw new EPPDecodeException( "EPPUtil.decodeBooleanAttr: Invalid boolean attr " + aAttr + " value of " + theAttrVal); } return theRet; } // End EPPUtil.decodeTimeInstant(String) /** * Decode a <code>EPPCodecComponent</code>, by XML namespace and tag name, * from an XML Element. The children elements of <code>aElement</code> will * be searched for the specified <code>aNS</code> namespace URI and the * specified <code>aTagName</code>. There first XML element found will be * used to initial and instance of <code>aClass</code>. * * @param aElement * XML Element to scan. For example, the element could be * <domain:update> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name servers * is "domain:server". * @param aClass * Class to instantiate for a found XML element. This must be a * class that implements <code>EPPCodecComponent</code> * @return Instance of <code>aClass</code> that represents the found XML * elements if found; <code>null</code> otherwise. * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static EPPCodecComponent decodeComp(Element aElement, String aNS, String aTagName, Class aClass) throws EPPDecodeException { EPPCodecComponent retVal = null; try { Element theElm = EPPUtil.getElementByTagNameNS(aElement, aNS, aTagName); if (theElm != null) { retVal = (EPPCodecComponent) aClass.newInstance(); retVal.decode(theElm); } } catch (IllegalAccessException e) { throw new EPPDecodeException("EPPUtil.decodeComp(), IllegalAccessException: " + e); } catch (InstantiationException e) { throw new EPPDecodeException("EPPUtil.decodeComp(), InstantiationException: " + e); } return retVal; } /** * Decode a <code>List</code> of <code>EPPCodecComponent</code>'s, by XML * namespace and tag name, from an XML Element. The children elements of * <code>aElement</code> will be searched for the specified <code>aNS</code> * namespace URI and the specified <code>aTagName</code>. Each XML element * found will result in the instantiation of <code>aClass</code>, which will * decode the associated XML element and added to the returned * <code>List</code>. * * @param aElement * XML Element to scan. For example, the element could be * <domain:add> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the contact elements of * >domain:add> is "domain:contact". * @param aClass * Class to instantiate for each found XML element. This must be * a class that implements <code>EPPCodecComponent</code> * @return <code>List</code> of <code>EPPCodecComponent</code> elements * representing the found XML elements. * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static List decodeCompList(Element aElement, String aNS, String aTagName, Class aClass) throws EPPDecodeException { List retVal = new ArrayList(); try { Vector theChildren = EPPUtil.getElementsByTagNameNS(aElement, aNS, aTagName); // For each element for (int i = 0; i < theChildren.size(); i++) { EPPCodecComponent currComp = (EPPCodecComponent) aClass.newInstance(); currComp.decode((Element) theChildren.elementAt(i)); retVal.add(currComp); } // end for each element } catch (IllegalAccessException e) { throw new EPPDecodeException("EPPUtil.decodeCompList(), IllegalAccessException: " + e); } catch (InstantiationException e) { throw new EPPDecodeException("EPPUtil.decodeCompList(), InstantiationException: " + e); } return retVal; } /** * Decode a <code>Vector</code> of <code>EPPCodecComponent</code>'s, by XML * namespace and tag name, from an XML Element. The children elements of * <code>aElement</code> will be searched for the specified <code>aNS</code> * namespace URI and the specified <code>aTagName</code>. Each XML element * found will result in the instantiation of <code>aClass</code>, which will * decode the associated XML element and added to the returned * <code>Vector</code>. * * @param aElement * XML Element to scan. For example, the element could be * <domain:add> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the contact elements of * >domain:add> is "domain:contact". * @param aClass * Class to instantiate for each found XML element. This must be * a class that implements <code>EPPCodecComponent</code> * @return <code>Vector</code> of <code>EPPCodecComponent</code> elements * representing the found XML elements. * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static Vector decodeCompVector(Element aElement, String aNS, String aTagName, Class aClass) throws EPPDecodeException { Vector retVal = new Vector(); try { Vector theChildren = EPPUtil.getElementsByTagNameNS(aElement, aNS, aTagName); // For each element for (int i = 0; i < theChildren.size(); i++) { EPPCodecComponent currComp = (EPPCodecComponent) aClass.newInstance(); currComp.decode((Element) theChildren.elementAt(i)); retVal.addElement(currComp); } // end for each element } catch (IllegalAccessException e) { throw new EPPDecodeException("EPPUtil.decodeCompVector(), IllegalAccessException: " + e); } catch (InstantiationException e) { throw new EPPDecodeException("EPPUtil.decodeCompVector(), InstantiationException: " + e); } return retVal; } /** * Decode <code>Date</code>, by XML namespace and tag name, from an XML * Element. The children elements of <code>aElement</code> will be searched * for the specified <code>aNS</code> namespace URI and the specified * <code>aTagName</code>. The first XML element found will be decoded and * returned. If no element is found, <code>null</code> is returned. The * format used for decoding the date is defined by the constant * <code>EPPUtil.DATE_FORMAT</code>. * * @param aElement * XML Element to scan. For example, the element could be * <trans-id> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:epp". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the transaction Id date * is "date". * @return <code>Date</code> value if found; <code>null</code> otherwise. * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static Date decodeDate(Element aElement, String aNS, String aTagName) throws EPPDecodeException { Date retVal = null; Element theElm = EPPUtil.getElementByTagNameNS(aElement, aNS, aTagName); if (theElm != null) { retVal = EPPUtil.decodeDate(theElm.getFirstChild().getNodeValue()); } return retVal; } /** * Decode an XML Schema date data type (YYYY-MM-DD) to a Java Date object. * * @param aDateValue * XML Schema date data type string (YYYY-MM-DD). * @return Java Date object. */ public static Date decodeDate(String aDateValue) { SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT); // Set to UTC with no time element Calendar theCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); theCal.set(Calendar.HOUR_OF_DAY, 0); theCal.set(Calendar.MINUTE, 0); theCal.set(Calendar.SECOND, 0); theCal.set(Calendar.MILLISECOND, 0); formatter.setCalendar(theCal); Date theDate = formatter.parse(aDateValue, new ParsePosition(0)); return theDate; } /** * Decode <code>Integer</code>, by XML namespace and tag name, from an XML * Element. The children elements of <code>aElement</code> will be searched * for the specified <code>aNS</code> namespace URI and the specified * <code>aTagName</code>. The first XML element found will be decoded and * returned. If no element is found, <code>null</code> is returned. * * @param aElement * XML Element to scan. For example, the element could be * <domain:create> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name is * "domain:name". * @return <code>Integer</code> value if found; <code>null</code> otherwise. * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static Integer decodeInteger(Element aElement, String aNS, String aTagName) throws EPPDecodeException { Element theElm = EPPUtil.getElementByTagNameNS(aElement, aNS, aTagName); Integer retInteger = null; if (theElm != null) { Node textNode = theElm.getFirstChild(); // Element does have a text node? if (textNode != null) { String intValStr = textNode.getNodeValue(); try { retInteger = Integer.valueOf(intValStr); } catch (NumberFormatException e) { throw new EPPDecodeException("Can't convert value to Integer: " + intValStr + e); } } else { throw new EPPDecodeException("Can't decode numeric value from non-existant text node"); } } return retInteger; } /** * Decode a <code>List</code> of <code>String</code>'s by XML namespace and * tag name, from an XML Element. The children elements of * <code>aElement</code> will be searched for the specified <code>aNS</code> * namespace URI and the specified <code>aTagName</code>. Each XML element * found will be decoded and added to the returned <code>List</code>. Empty * child elements, will result in empty string ("") return <code>List</code> * elements. * * @param aElement * XML Element to scan. For example, the element could be * <domain:update> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name servers * is "domain:server". * @return <code>List</code> of <code>String</code> elements representing * the text nodes of the found XML elements. * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static List decodeList(Element aElement, String aNS, String aTagName) throws EPPDecodeException { List retVal = new ArrayList(); Vector theChildren = EPPUtil.getElementsByTagNameNS(aElement, aNS, aTagName); for (int i = 0; i < theChildren.size(); i++) { Element currChild = (Element) theChildren.elementAt(i); Text currVal = (Text) currChild.getFirstChild(); // Element has text? if (currVal != null) { retVal.add(currVal.getNodeValue()); } else { // No text in element. retVal.add(""); } } return retVal; } // End EPPUtil.decodeList(Element, String, String) /** * Decode <code>String</code>, by XML namespace and tag name, from an XML * Element. The children elements of <code>aElement</code> will be searched * for the specified <code>aNS</code> namespace URI and the specified * <code>aTagName</code>. The first XML element found will be decoded and * returned. If no element is found, <code>null</code> is returned. * * @param aElement * XML Element to scan. For example, the element could be * <domain:create> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name is * "domain:name". * @return <code>String</code> value if found; <code>null</code> otherwise. * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static String decodeString(Element aElement, String aNS, String aTagName) throws EPPDecodeException { String retVal = null; Element theElm = EPPUtil.getElementByTagNameNS(aElement, aNS, aTagName); if (theElm != null) { Node textNode = theElm.getFirstChild(); // Element does have a text node? if (textNode != null) { retVal = textNode.getNodeValue(); } else { retVal = ""; } } // end if (currElm != null) return retVal; } /** * Decode <code>Date</code>, as date and time, by XML namespace and tag * name, from an XML Element. The children elements of <code>aElement</code> * will be searched for the specified <code>aNS</code> namespace URI and the * specified <code>aTagName</code>. The first XML element found will be * decoded and returned. If no element is found, <code>null</code> is * returned. The format used for decoding the date is defined by the * constant <code>EPPUtil.TIME_INSTANT_FORMAT</code>. * * @param aElement * XML Element to scan. For example, the element could be * <trans-id> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:epp". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the transaction Id date * is "date". * @return <code>Date</code> value as date and time if found; * <code>null</code> otherwise. * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static Date decodeTimeInstant(Element aElement, String aNS, String aTagName) throws EPPDecodeException { Date retVal = null; Element theElm = EPPUtil.getElementByTagNameNS(aElement, aNS, aTagName); if (theElm != null) { retVal = EPPUtil.decodeTimeInstant(theElm.getFirstChild().getNodeValue()); } return retVal; } /** * Decode an XML Schema timeInstant data type to a Java Date object. * * @param aTimeInstant * XML Schema timeInstant data type string. * @return Java Date object if <code>aTimeInstant</code> format is valid; * <code>null</code> otherwise */ public static Date decodeTimeInstant(String aTimeInstant) { Date theDate = null; try { theDate = DatatypeConverter.parseDateTime(aTimeInstant).getTime(); } catch (IllegalArgumentException ex) { cat.error("Exception decoding dataTime: " + ex); theDate = null; } return theDate; } /** * Decode a <code>Vector</code> of <code>String</code>'s by XML namespace * and tag name, from an XML Element. The children elements of * <code>aElement</code> will be searched for the specified <code>aNS</code> * namespace URI and the specified <code>aTagName</code>. Each XML element * found will be decoded and added to the returned <code>Vector</code>. * Empty child elements, will result in empty string ("") return * <code>Vector</code> elements. * * @param aElement * XML Element to scan. For example, the element could be * <domain:update> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name servers * is "domain:server". * @return <code>Vector</code> of <code>String</code> elements representing * the text nodes of the found XML elements. * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static <X> Vector<X> decodeVector(Element aElement, String aNS, String aTagName) throws EPPDecodeException { Vector retVal = new Vector(); Vector theChildren = EPPUtil.getElementsByTagNameNS(aElement, aNS, aTagName); for (int i = 0; i < theChildren.size(); i++) { Element currChild = (Element) theChildren.elementAt(i); Text currVal = (Text) currChild.getFirstChild(); // Element has text? if (currVal != null) { retVal.addElement(currVal.getNodeValue()); } else { // No text in element. retVal.addElement(""); } } return retVal; } // End EPPUtil.decodeVector(Element, String, String) /** * Encode a <code>Double</code> in XML with a given XML namespace and tag * name. Takes an optional argument for the format of the Double, if not * provided then it uses #0.00 which formats the double to 2 decimal places. * * @param aDocument * DOM Document of <code>aRoot</code>. This parameter also acts * as a factory for XML elements. * @param aRoot * XML Element to add children nodes to. For example, the root * node could be <domain:update> * @param aBigDecimal * <code>Double</code> to add. * @param aNS * XML namespace of the element. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name is * "domain:name". * @exception EPPEncodeException * Error encoding the <code>Double</code>. */ public static void encodeBigDecimal(Document aDocument, Element aRoot, BigDecimal aBigDecimal, String aNS, String aTagName, String aFormat) throws EPPEncodeException { if (aBigDecimal != null) { String format = aFormat != null ? aFormat : "#0.00"; DecimalFormat decFormat = new DecimalFormat(format, decimalFormatSymbols); String numberStr = decFormat.format(aBigDecimal); EPPUtil.encodeString(aDocument, aRoot, numberStr, aNS, aTagName); } } /** * Encode a <code>Boolean</code> in XML with a given XML namespace and tag * name. If aBoolean is <code>null</code> an element is not added. * * @param aDocument * DOM Document of <code>aRoot</code>. This parameter also acts * as a factory for XML elements. * @param aRoot * XML Element to add children nodes to. For example, the root * node could be <domain:update> * @param aBoolean * <code>Boolean</code> to add. * @param aNS * XML namespace of the element. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name is * "domain:name". * @exception EPPEncodeException * Error encoding the <code>Boolean</code>. */ public static void encodeBoolean(Document aDocument, Element aRoot, Boolean aBoolean, String aNS, String aTagName) throws EPPEncodeException { if (aBoolean != null) { Element currElm = aDocument.createElementNS(aNS, aTagName); String xmlValue; if (aBoolean.booleanValue()) { xmlValue = "1"; } else { xmlValue = "0"; } Text currVal = aDocument.createTextNode(xmlValue); currElm.appendChild(currVal); aRoot.appendChild(currElm); } } /** * Encodes a boolean <code>Element</code> attribute value. The attribute is * set to "1" with a value of <code>true</code> and is set to * "0" with a value of <code>false</code>. * * @param aElement * Element to add attribute to * @param aAttr * Attribute name * @param aVal * Attribute boolean value */ public static void encodeBooleanAttr(Element aElement, String aAttr, boolean aVal) { if (aVal) { aElement.setAttribute(aAttr, "1"); } else { aElement.setAttribute(aAttr, "0"); } } // End EPPUtil.encodeComp(Document, Element, EPPCodecComponent) /** * Encode a <code>EPPCodecComponent</code> instance in XML. The component is * first checked for not being <code>null</code>, than it will be appended * as a child of <code>aRoot</code>. * * @param aDocument * DOM Document of <code>aRoot</code>. This parameter also acts * as a factory for XML elements. * @param aRoot * XML Element to add to. For example, the root node could be * <domain:update> * @param aComp * <code>EPPCodecComponent's</code> to add. * @exception EPPEncodeException * Error encoding <code>EPPCodecComponent</code>. */ public static void encodeComp(Document aDocument, Element aRoot, EPPCodecComponent aComp) throws EPPEncodeException { if (aComp != null) { aRoot.appendChild(aComp.encode(aDocument)); } } // End EPPUtil.decodeComp(Element, String, String, Class) /** * Encode a <code>List</code> of <code>EPPCodecComponent</code>'s in XML. * Each <code>aList</code> element will be encoded and added to * <code>aRoot</code>. * * @param aDocument * DOM Document of <code>aRoot</code>. This parameter also acts * as a factory for XML elements. * @param aRoot * XML Element to add children nodes to. For example, the root * node could be <domain:update> * @param aList * <code>List</code> of <code>EPPCodecComponent's</code> to add. * @exception EPPEncodeException * Error encoding the <code>List</code> of * <code>EPPCodecComponent</code>'s. */ public static void encodeCompList(Document aDocument, Element aRoot, List aList) throws EPPEncodeException { if (aList != null) { Iterator elms = aList.iterator(); while (elms.hasNext()) { EPPCodecComponent currComp = (EPPCodecComponent) elms.next(); aRoot.appendChild(currComp.encode(aDocument)); } // End while (elms.hasMoreElements()) } } // End EPPUtil.encodeCompList(Document,Element, List) // End EPPUtil.encodeString(Document, Element, String, String, String) /** * Encode a <code>Vector</code> of <code>EPPCodecComponent</code>'s in XML. * Each <code>aVector</code> element will be encoded and added to * <code>aRoot</code>. * * @param aDocument * DOM Document of <code>aRoot</code>. This parameter also acts * as a factory for XML elements. * @param aRoot * XML Element to add children nodes to. For example, the root * node could be <domain:update> * @param aVector * <code>Vector</code> of <code>EPPCodecComponent's</code> to add. * @exception EPPEncodeException * Error encoding the <code>Vector</code> of * <code>EPPCodecComponent</code>'s. */ public static void encodeCompVector(Document aDocument, Element aRoot, Vector aVector) throws EPPEncodeException { if (aVector != null) { Enumeration elms = aVector.elements(); while (elms.hasMoreElements()) { EPPCodecComponent currComp = (EPPCodecComponent) elms.nextElement(); aRoot.appendChild(currComp.encode(aDocument)); } // End while (elms.hasMoreElements()) } } // End EPPUtil.encodeVector(Document,Element, Vector) // End EPPUtil.decodeString(Element, String, String) /** * Encode a Java Date into an XML Schema date data type string. * * @param aDate * Java Date to encode into a XML Schema date data type string. * @return Encoded XML Schema date data type string. */ public static String encodeDate(Date aDate) { TimeZone utcTimeZone = TimeZone.getTimeZone("UTC"); SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT); formatter.setTimeZone(utcTimeZone); return formatter.format(aDate); } // End EPPUtil.encodeBoolean(Document, Element, Boolean, String, String) /** * Encode a <code>Date</code> in XML with a given XML namespace and tag * name. The format used for encoding the date is defined by the constant * <code>EPPUtil.DATE_FORMAT</code>. * * @param aDocument * DOM Document of <code>aRoot</code>. This parameter also acts * as a factory for XML elements. * @param aRoot * XML Element to add children nodes to. For example, the root * node could be <domain:update> * @param aDate * <code>Date</code> to add. * @param aNS * XML namespace of the element. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name is * "domain:name". * @exception EPPEncodeException * Error encoding <code>Date</code>. */ public static void encodeDate(Document aDocument, Element aRoot, Date aDate, String aNS, String aTagName) throws EPPEncodeException { if (aDate != null) { encodeString(aDocument, aRoot, EPPUtil.encodeDate(aDate), aNS, aTagName); } } // End EPPUtil.decodeBoolean(Element, String, String) /** * Encode a <code>List</code> of <code>String</code>'s in XML with a given * XML namespace and tag name. * * @param aDocument * DOM Document of <code>aRoot</code>. This parameter also acts * as a factory for XML elements. * @param aRoot * XML Element to add children nodes to. For example, the root * node could be <domain:update> * @param aList * <code>List</code> of <code>String's</code> to add. * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name servers * is "domain:server". * @exception EPPEncodeException * Error encoding the <code>List</code> of * <code>String</code>'s. */ public static void encodeList(Document aDocument, Element aRoot, List aList, String aNS, String aTagName) throws EPPEncodeException { Element currElm; Text currVal; if (aList != null) { Iterator elms = aList.iterator(); while (elms.hasNext()) { currElm = aDocument.createElementNS(aNS, aTagName); currVal = aDocument.createTextNode(elms.next().toString()); currElm.appendChild(currVal); aRoot.appendChild(currElm); } // end while (elms.hasMoreElements()) } // end if (aList != null) } // End EPPUtil.encodeList(Document,Element, List, String, String) /** * DOCUMENT ME! * * @param aDocument * DOCUMENT ME! * @param aRoot * DOCUMENT ME! * @param aNS * DOCUMENT ME! * @param aTagName * DOCUMENT ME! * @throws EPPEncodeException * DOCUMENT ME! */ public static void encodeNill(Document aDocument, Element aRoot, String aNS, String aTagName) throws EPPEncodeException { Element localElement = aDocument.createElementNS(aNS, aTagName); localElement.setAttribute("xsi:nil", "true"); aRoot.appendChild(localElement); } /** * Encode a <code>String</code> in XML with a given XML namespace and tag * name. * * @param aDocument * DOM Document of <code>aRoot</code>. This parameter also acts * as a factory for XML elements. * @param aRoot * XML Element to add children nodes to. For example, the root * node could be <domain:update> * @param aString * <code>String</code> to add. * @param aNS * XML namespace of the element. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name is * "domain:name". * @exception EPPEncodeException * Error encoding the <code>String</code>. */ public static void encodeString(Document aDocument, Element aRoot, String aString, String aNS, String aTagName) throws EPPEncodeException { if (aString != null) { Element currElm = aDocument.createElementNS(aNS, aTagName); Text currVal = aDocument.createTextNode(aString); currElm.appendChild(currVal); aRoot.appendChild(currElm); } } // End EPPUtil.encodeDate(Document, Element, Date, String, String) public static void encodeStringList(Document aDocument, Element aRoot, List aList, String aNS, String aTagName) { String aString; Element aElement; Text aValue; if (aList != null) { Iterator elms = aList.iterator(); while (elms.hasNext()) { aString = (String) elms.next(); aElement = aDocument.createElementNS(aNS, aTagName); aValue = aDocument.createTextNode(aString); aElement.appendChild(aValue); aRoot.appendChild(aElement); } } } // End EPPUtil.decodeDate(Element, String, String) /** * Encode a Java Date into an XML Schema timeInstant data type string. The * XML Schema timeInstant data type string has the following format: * CCYY-MM-DDThh:mm:ss.ssss can be followed by a Z to indicate Coordinated * Universal Time * * @param aDate * Java Date to encode into a XML Schema timeInstant data type * string. * @return Encoded XML Schema timeInstant data type string. */ public static String encodeTimeInstant(Date aDate) { TimeZone utcTimeZone = TimeZone.getTimeZone("UTC"); SimpleDateFormat formatter = new SimpleDateFormat(timeInstantFormat); formatter.setTimeZone(utcTimeZone); return formatter.format(aDate); } // End EPPUtil.encodeTimeInstance(Document, Element, Date, String, String) /** * Encode a <code>Date</code>, as date and time, in XML with a given XML * namespace and tag name. The format used for encoding the date is defined * by the constant <code>EPPUtil.TIME_INSTANT_FORMAT</code>. * * @param aDocument * DOM Document of <code>aRoot</code>. This parameter also acts * as a factory for XML elements. * @param aRoot * XML Element to add children nodes to. For example, the root * node could be <domain:expire-data> * @param aDate * <code>Date</code> as date and time to add. * @param aNS * XML namespace of the element. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain expiration * date and time is "domain:expiration-date". * @exception EPPEncodeException * Error encoding <code>Date</code>. */ public static void encodeTimeInstant(Document aDocument, Element aRoot, Date aDate, String aNS, String aTagName) throws EPPEncodeException { if (aDate != null) { encodeString(aDocument, aRoot, EPPUtil.encodeTimeInstant(aDate), aNS, aTagName); } } /** * Encode a <code>Vector</code> of <code>String</code>'s in XML with a given * XML namespace and tag name. * * @param aDocument * DOM Document of <code>aRoot</code>. This parameter also acts * as a factory for XML elements. * @param aRoot * XML Element to add children nodes to. For example, the root * node could be <domain:update> * @param aVector * <code>Vector</code> of <code>String's</code> to add. * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name servers * is "domain:server". * @exception EPPEncodeException * Error encoding the <code>Vector</code> of * <code>String</code>'s. */ public static void encodeVector(Document aDocument, Element aRoot, Vector aVector, String aNS, String aTagName) throws EPPEncodeException { Element currElm; Text currVal; if (aVector != null) { Enumeration elms = aVector.elements(); while (elms.hasMoreElements()) { currElm = aDocument.createElementNS(aNS, aTagName); currVal = aDocument.createTextNode(elms.nextElement().toString()); currElm.appendChild(currVal); aRoot.appendChild(currElm); } // end while (elms.hasMoreElements()) } // end if (aVector != null) } // End EPPUtil.encodeVector(Document,Element, Vector, String, String) // End EPPUtil.decodeTimeInstance(Element, String, String) /** * compares two <code>List</code> instances. The Java 1.1 <code>List</code> * class does not implement the <code>equals</code> methods, so * <code>equalLists</code> was written to implement <code>equals</code> of * two <code>Lists</code> (aV1 and aV2). This method is not need for Java 2. * * @param aV1 * First List instance to compare. * @param aV2 * Second List instance to compare. * @return <code>true</code> if List's are equal; <code>false</code> * otherwise. */ public static boolean equalLists(List aV1, List aV2) { if ((aV1 == null) && (aV2 == null)) { return true; } else if ((aV1 != null) && (aV2 != null)) { if (aV1.size() != aV2.size()) { return false; } Iterator v1Iter = aV1.iterator(); Iterator v2Iter = aV2.iterator(); for (int i = 0; i < aV1.size(); i++) { Object elm1 = v1Iter.next(); Object elm2 = v2Iter.next(); if (!((elm1 == null) ? (elm2 == null) : elm1.equals(elm2))) { return false; } } return true; } else { return false; } } // End EPPUtil.equalLists(List, List) // End EPPUtil.getFirstElementChild(Element) /** * compares two <code>Vector</code> instances. The Java 1.1 * <code>Vector</code> class does not implement the <code>equals</code> * methods, so <code>equalVectors</code> was written to implement * <code>equals</code> of two <code>Vectors</code> (aV1 and aV2). This * method is not need for Java 2. * * @param aV1 * First Vector instance to compare. * @param aV2 * Second Vector instance to compare. * @return <code>true</code> if Vector's are equal; <code>false</code> * otherwise. */ public static boolean equalVectors(Vector aV1, Vector aV2) { if ((aV1 == null) && (aV2 == null)) { return true; } else if ((aV1 != null) && (aV2 != null)) { if (aV1.size() != aV2.size()) { return false; } for (int i = 0; i < aV1.size(); i++) { Object elm1 = aV1.elementAt(i); Object elm2 = aV2.elementAt(i); if (!((elm1 == null) ? (elm2 == null) : elm1.equals(elm2))) { return false; } } return true; } else { return false; } } // End EPPUtil.equalVectors(Vector, Vector) // End EPPUtil.getNextElementSibling(Element) /** * Gets the first direct child element with a given tag name and XML * namespace. * * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name to scan for. * @return Matching <code>Element</code> if found; <code>null</code> * otherwise. */ public static Element getElementByTagNameNS(Element aElement, String aNS, String aTagName) { Element retElm = null; aTagName = EPPUtil.getLocalName(aTagName); NodeList theNodes = aElement.getChildNodes(); // Found matching nodes? if (theNodes != null) { for (int i = 0; (i < theNodes.getLength()) && retElm == null; i++) { if (theNodes.item(i).getNodeType() == Node.ELEMENT_NODE) { Element currElm = (Element) theNodes.item(i); if (currElm.getNamespaceURI().equals(aNS) && currElm.getLocalName().equals(aTagName)) { retElm = currElm; } } } } return retElm; } /** * Gets all of the direct child element with a given tag name and XML * namespace. * * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name to scan for. * @return <code>Vector</code> of <code>Node</code> instances that are * elements and have the specified tag name and XML namespace. */ public static Vector getElementsByTagNameNS(Element aElement, String aNS, String aTagName) { Vector retVal = new Vector(); aTagName = EPPUtil.getLocalName(aTagName); NodeList theNodes = aElement.getChildNodes(); if (theNodes != null) { for (int i = 0; i < theNodes.getLength(); i++) { if (theNodes.item(i).getNodeType() == Node.ELEMENT_NODE) { Element currElm = (Element) theNodes.item(i); if (currElm.getNamespaceURI().equals(aNS) && currElm.getLocalName().equals(aTagName)) { retVal.add(theNodes.item(i)); } } } } return retVal; } /** * Gets the local name given the qualified element name. If the local name * is passed, it will be simply returned back.R * * @param aQualifiedName * Qualified name of the element like <code>domain:name</code>. A * localhost like <code>name</code> can be passed without error. * @return Localname of the qualified name */ public static String getLocalName(String aQualifiedName) { if (aQualifiedName.indexOf(':') != -1) { aQualifiedName = aQualifiedName.substring(aQualifiedName.indexOf(':') + 1); } return aQualifiedName; } /** * Gets the namespace prefix given a qualified name. If no prefix is found, * empty string is returned. * * @param aQualifiedName * Qualified name of the element like <code>domain:name</code>. * @return Namespace prefix of the qualified name if found; empty string * ("") if not found. */ public static String getPrefix(String aQualifiedName) { String prefix = ""; if (aQualifiedName.indexOf(':') != -1) { prefix = aQualifiedName.substring(0, aQualifiedName.indexOf(':')); } return prefix; } /** * Gets the first DOM Element Node of the <code>aElement</code> DOM Element. * * @param aElement * Element to scan for the first element. * @return Found DOM Element Node if found; <code>null</code> otherwise. */ public static Element getFirstElementChild(Element aElement) { NodeList children = aElement.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { if (children.item(i).getNodeType() == Node.ELEMENT_NODE) { return (Element) children.item(i); } } return null; } /** * Gets the next sibling Element of a provided Element. * * @param aElement * Element to start scan for the next Element. * @return Found DOM Element Node if found; <code>null</code> otherwise. */ public static Element getNextElementSibling(Element aElement) { Element theSibling = null; Node theCurrNode = aElement; while ((theCurrNode != null) && (theSibling == null)) { theCurrNode = theCurrNode.getNextSibling(); if ((theCurrNode != null) && (theCurrNode.getNodeType() == Node.ELEMENT_NODE)) { theSibling = (Element) theCurrNode; } } return theSibling; } /** * A pass-thru to the getTextContent() method using a default value of false * for the required flag. */ static public String getTextContent(Node node) throws EPPDecodeException { return getTextContent(node, false); } /** * Return the text data within an XML tag.<br> * <id>12345</id> yields the String "12345"<br> * If the node==null, child==null, value==null, or value=="" => Exception<br> * UNLESS allowEmpty, in which case return "" * <p> * For reference:<br> * <tag></tag> => child is null<br> * <tag/> => child is null<br> * <tag> </tag> => value is empty */ static public String getTextContent(Node node, boolean allowEmpty) throws EPPDecodeException { if (node != null) { Node child = node.getFirstChild(); if (child != null) { String value = child.getNodeValue(); if (value != null) { value = value.trim(); if (value.length() > 0) { return value; } } } } if (allowEmpty) return ""; throw new EPPDecodeException("Empty tag encountered during decode"); } /** * Determines if one <code>List</code> is a subset of another * <code>List</code>. If every element in <code>aV1</code> is in * <code>aV2</code> return <code>true</code>; otherwise return * <code>false</code>. * * @param aV1 * Subset <code>List</code> to compare against <code>aV2</code> * @param aV2 * Superset <code>List</code> to compare against <code>aV1</code> * @return <code>true</code> if <code>aV1</code> is a subset of * <code>aV2</code>; <code>false</code> otherwise. */ public static boolean listSubset(List aV1, List aV2) { Iterator v1Iter = aV1.iterator(); while (v1Iter.hasNext()) { if (!aV2.contains(v1Iter.next())) { return false; } } return true; } // End EPPUtil.listSubset(List, List) /** * Converts an <code>EPPCodecComponent</code> to a <code>String</code> for * printing. Each <code>EPPCodecComponent</code> can use this utility method * to implement <code>Object.toString()</code>. * * @param aComponent * a concrete <code>EPPCodecComponent</code> instance * @return <code>String</code> representation of * <code>EPPCodecComponent</code> if successful; "ERROR" * <code>String</code> otherwise. */ public static String toString(EPPCodecComponent aComponent) { String ret = "ERROR"; try { Document document = new DocumentImpl(); Element elm = aComponent.encode(document); ret = toString(elm); } catch (Exception ex) { ex.printStackTrace(); } return ret; } /** * Converts an <code>aElement</code> to a <code>String</code> for printing. * * @param aElement * <code>Element</code> to print * @return <code>String</code> representation of <code>Element</code> if * successful; "ERROR" <code>String</code> otherwise. */ public static String toString(Element aElement) { String ret = "ERROR"; ByteArrayOutputStream theBuffer = new ByteArrayOutputStream(); // Serialize DOM Document to stream try { TransformerFactory transFac = TransformerFactory.newInstance(); Transformer trans = transFac.newTransformer(); trans.setOutputProperty(OutputKeys.INDENT, "yes"); trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); trans.transform(new DOMSource(aElement), new StreamResult(theBuffer)); theBuffer.close(); ret = new String(theBuffer.toByteArray()); } catch (Exception ex) { ex.printStackTrace(); } return ret; } /** * Converts an <code>aElement</code> to a <code>String</code> for printing * without pretty printing. * * @param aElement * <code>Element</code> to print * @return <code>String</code> representation of <code>Element</code> if * successful; "ERROR" <code>String</code> otherwise. */ public static String toStringNoIndent(Element aElement) { String ret = "ERROR"; ByteArrayOutputStream theBuffer = new ByteArrayOutputStream(); // Serialize DOM Document to stream try { TransformerFactory transFac = TransformerFactory.newInstance(); Transformer trans = transFac.newTransformer(); trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); trans.transform(new DOMSource(aElement), new StreamResult(theBuffer)); theBuffer.close(); ret = new String(theBuffer.toByteArray()); } catch (Exception ex) { ex.printStackTrace(); } return ret; } /** * Determines if one <code>Vector</code> is a subset of another * <code>Vector</code>. If every element in <code>aV1</code> is in * <code>aV2</code> return <code>true</code>; otherwise return * <code>false</code>. * * @param aV1 * Subset <code>Vector</code> to compare against <code>aV2</code> * @param aV2 * Superset <code>Vector</code> to compare against * <code>aV1</code> * @return <code>true</code> if <code>aV1</code> is a subset of * <code>aV2</code>; <code>false</code> otherwise. */ public static boolean vectorSubset(Vector aV1, Vector aV2) { Enumeration v1Enum = aV1.elements(); while (v1Enum.hasMoreElements()) { if (!aV2.contains(v1Enum.nextElement())) { return false; } } return true; } // End EPPUtil.vectorSubset(Vector, Vector) /** * Decode a <code>List</code> of <code>Integer</code>'s by XML namespace and * tag name, from an XML Element. The children elements of * <code>aElement</code> will be searched for the specified <code>aNS</code> * namespace URI and the specified <code>aTagName</code>. Each XML element * found will be decoded and added to the returned <code>List</code>. Empty * child elements, will result in an <code>EPPDecodeException</code>. * * @param aElement * XML Element to scan. For example, the element could be * <domain:update> * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name servers * is "domain:server". * * @return <code>List</code> of <code>Integer</code> elements representing * the text nodes of the found XML elements. * * @exception EPPDecodeException * Error decoding <code>aElement</code>. */ public static List decodeIntegerList(Element aElement, String aNS, String aTagName) throws EPPDecodeException { List retVal = new ArrayList(); Vector theChildren = EPPUtil.getElementsByTagNameNS(aElement, aNS, aTagName); for (int i = 0; i < theChildren.size(); i++) { Element currChild = (Element) theChildren.elementAt(i); Integer retInteger = null; Node textNode = currChild.getFirstChild(); // Element does have a text node? if (textNode != null) { String intValStr = textNode.getNodeValue(); try { retInteger = Integer.valueOf(intValStr); } catch (NumberFormatException e) { throw new EPPDecodeException( "EPPUtil.decodeIntegerList Can't convert value to Integer: " + intValStr + e); } } else { throw new EPPDecodeException( "EPPUtil.decodeIntegerList Can't decode numeric value from non-existant text node"); } retVal.add(retInteger); } return retVal; } // End EPPUtil.decodeIntegerList(Element, String, String) /** * Encode a <code>List</code> of <code>Integer</code>'s in XML with a given * XML namespace and tag name. * * @param aDocument * DOM Document of <code>aRoot</code>. This parameter also acts * as a factory for XML elements. * @param aRoot * XML Element to add children nodes to. For example, the root * node could be <domain:update> * @param aList * <code>List</code> of <code>Integer</code>'s to add. * @param aNS * XML namespace of the elements. For example, for domain element * this is "urn:iana:xmlns:domain". * @param aTagName * Tag name of the element including an optional namespace * prefix. For example, the tag name for the domain name servers * is "domain:server". * * @exception EPPEncodeException * Error encoding the <code>List</code> of * <code>Integer</code>'s. */ public static void encodeIntegerList(Document aDocument, Element aRoot, List aList, String aNS, String aTagName) throws EPPEncodeException { Element currElm; Text currVal; if (aList != null) { Iterator elms = aList.iterator(); while (elms.hasNext()) { currElm = aDocument.createElementNS(aNS, aTagName); currVal = aDocument.createTextNode(elms.next().toString()); currElm.appendChild(currVal); aRoot.appendChild(currElm); } // end while (elms.hasNext()) } // end if (aList != null) } // End EPPUtil.encodeIntegerList(Document,Element, List, String, String) /** * Collapse Whitespace, which means that all leading and trailing whitespace * will be stripped, and all internal whitespace collapsed to single space * characters. Intended to emulate XML Schema whitespace (collapse) * constraining facet: http://www.w3.org/TR/xmlschema-2/#rf-whiteSpace * * @param inString * <code>String</code> to be collapsed * @return <code>String</code> with whitespace collapsed, or null when * result is empty */ public static String collapseWhitespace(String inString) { if (inString == null) { return null; } String s = inString.trim(); // remove leading and trailing whitespace StringBuffer sb = new StringBuffer(); int len = s.length(); boolean prevWhitespace = true; for (int i = 0; i < len; i++) { char c = s.charAt(i); if (Character.isWhitespace(c) == false) { sb.append(c); // maintain all non-whitespace characters prevWhitespace = false; } else { if (prevWhitespace == false) { sb.append(' '); // replace each sequence of whitespace with // a single space prevWhitespace = true; } } } if (sb.length() == 0) { return null; // return null string when result is empty } else { return sb.toString(); // return collapsed string } } /** * Remove Whitespace, which means that all whitespace will be stripped. * * @param inString * <code>String</code> from which to remove whitespace * @return <code>String</code> with whitespace removed, or null when result * is empty */ public static String removeWhitespace(String inString) { if (inString == null) { return null; } StringBuffer sb = new StringBuffer(); int len = inString.length(); for (int i = 0; i < len; i++) { char c = inString.charAt(i); if (Character.isWhitespace(c) == false) { sb.append(c); // maintain all non-whitespace characters } } if (sb.length() == 0) { return null; // return null string when result is empty } else { return sb.toString(); // return result string } } /** * Base64 encode the XML <code>Element</code> tree. * * @param aElement Root element to encode in Base64 * @return Base64 encoded value of the XML <code>Element</code> tree. * @throws Exception Error encoding the <code>Element</code> */ public static String encodeBase64(Element aElement) throws Exception { ByteArrayOutputStream ostream = new ByteArrayOutputStream(); TransformerFactory transFac = TransformerFactory.newInstance(); Transformer trans = transFac.newTransformer(); trans.transform(new DOMSource(aElement), new StreamResult(ostream)); return (new String(Base64.encodeBase64(ostream.toByteArray(), true))); } }