/******************************************************************************* * Copyright (c) 2010 Yadu. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public * License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors: Yadu - initial API * and implementation ******************************************************************************/ package code.google.restclient.parse; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import org.apache.log4j.Logger; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; /** * @author Yaduvendra.Singh */ public class Formatter { private static final Logger LOG = Logger.getLogger(Formatter.class); private static final boolean DEBUG_ENABLED = LOG.isDebugEnabled(); private static final String NEW_LINE = "\n"; public static String getIndentedJson(String jsonStr, int indentCount) { try { JSONObject jsonObj = new JSONObject(jsonStr); return jsonObj.toString(indentCount); } catch ( JSONException e ) { LOG.warn("getPrettyJson() - Json string is not properly formatted", e); return ""; } } public static String getIndentedXml(String xmlStr, int indentFactor) { if ( xmlStr != null && !"".equals(xmlStr) ) { InputStream is = new ByteArrayInputStream(xmlStr.getBytes()); String prettyXml = getIndentedXml(is, indentFactor); return prettyXml; } else { LOG.warn("getPrettyXml() - XML string passed is null!"); } return ""; } public static String getIndentedXml(InputStream xmlStream, int indentFactor) { int tagsCount = 0; if ( xmlStream == null ) { if ( DEBUG_ENABLED ) LOG.debug("getPrettyXml() - XML input stream passed is null!"); return null; } else { if ( DEBUG_ENABLED ) LOG.debug("getPrettyXml() - Starting transformation ..."); } StringWriter strWriter = new StringWriter(); XMLStreamReader xsr = null; XMLStreamWriter xsw = null; try { XMLInputFactory xif = XMLInputFactory.newInstance(); xsr = xif.createXMLStreamReader(xmlStream); XMLOutputFactory xof = XMLOutputFactory.newInstance(); xsw = xof.createXMLStreamWriter(strWriter); xsw.writeStartDocument(); int prevEvent = -1; while ( xsr.hasNext() ) { int event = xsr.next(); if ( event == XMLStreamConstants.START_ELEMENT ) { // start tag if ( DEBUG_ENABLED ) LOG.debug("START_ELEMENT: " + xsr.getLocalName()); addXmlIndent(xsw, indentFactor, tagsCount); xsw.writeStartElement(xsr.getLocalName()); tagsCount++; for ( int i = 0; i < xsr.getAttributeCount(); i++ ) { // tag's attributes if ( DEBUG_ENABLED ) LOG.debug("@attribute: " + xsr.getAttributeLocalName(i) + "=" + xsr.getAttributeValue(i)); xsw.writeAttribute(xsr.getAttributeLocalName(i), xsr.getAttributeValue(i)); } } if ( event == XMLStreamConstants.CHARACTERS ) { // tag's text value if ( DEBUG_ENABLED ) LOG.debug("#text: " + xsr.getText()); if ( !xsr.isWhiteSpace() ) xsw.writeCharacters(xsr.getText()); } if ( event == XMLStreamConstants.CDATA ) { // cdata if ( DEBUG_ENABLED ) LOG.debug("[CDATA]: " + xsr.getText()); if ( !xsr.isWhiteSpace() ) xsw.writeCData(xsr.getText()); } if ( event == XMLStreamConstants.END_ELEMENT ) { // end tag if ( DEBUG_ENABLED ) LOG.debug("END_ELEMENT: " + xsr.getLocalName()); if ( tagsCount > 0 ) { if ( prevEvent == event ) addXmlIndent(xsw, indentFactor, tagsCount - 1); xsw.writeEndElement(); tagsCount--; } else { if ( DEBUG_ENABLED ) { LOG.debug("getPrettyXml() - Invalid xml data! Opening tags not equal to closing tags." + " Even then continuing ..."); } } } prevEvent = event; } xsw.writeEndDocument(); } catch ( XMLStreamException xse ) { LOG.warn("getPrettyXml() - Error while handling xml stream -> " + xse); return ""; // return blank string in case of parsing error } finally { try { if ( xsr != null ) xsr.close(); if ( xsw != null ) xsw.close(); if ( strWriter != null ) strWriter.close(); } catch ( XMLStreamException xse ) { LOG.error("getPrettyXml() - Error while closing xml stream reader/writer -> " + xse); } catch ( IOException ioe ) { LOG.error("getPrettyXml() - Error closing strWriter (string writer) -> " + ioe); } } if ( DEBUG_ENABLED ) LOG.debug("getPrettyXml() - json output =>\n" + strWriter.toString()); return strWriter.toString(); } private static void addXmlIndent(XMLStreamWriter xsw, int indentFactor, int indentCount) throws XMLStreamException { xsw.writeCharacters(getIndent(indentFactor, indentCount)); } private static String getIndent(int indentFactor, int indentCount) { StringBuilder sb = new StringBuilder(); sb.append(NEW_LINE); while ( indentCount >= 1 ) { sb.append(getIndentSize(indentFactor)); indentCount--; } return sb.toString(); } private static String getIndentSize(int indentFactor) { StringBuilder indent = new StringBuilder(); String ws = " "; if ( indentFactor == 0 ) ws = ""; else { while ( indentFactor >= 1 ) { indent.append(ws); indentFactor--; } } return indent.toString(); } /* public static void main(String[] args) { String xmlStr = "<root>" + "<item id=\"1\" type=\"video & "me"\" > check video1 & video </item>" + " <field id=\"1\"><![CDATA[In XML you need elements which have a starting tag <song> and end tag </song>]]></field>" + "<field id=\"2\"> <A></A> <B> </B></field>" + "<field id=\"3\"></field>" + "</root>"; String prettyXml = getIndentedXml(xmlStr, 2); System.out.println("Pretty Xml: \n" + prettyXml); } */ }