All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.empire.xml.XMLWriter Maven / Gradle / Ivy

There is a newer version: 3.2.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.empire.xml;

// Java
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * This class prints out a XML-DOM-Tree to an output stream.
 * 

* * */ public class XMLWriter { // Logger protected static final Logger log = LoggerFactory.getLogger(XMLWriter.class); /** Print writer. */ protected PrintWriter out; /** Canonical output. */ protected boolean canonical; /** xmlWriterRoot for debugToFile function */ private static String xmlWriterRoot = null; /** Default Encoding */ private String charsetEncoding = "utf-8"; /** * Prints out the DOM-Tree on System.out for debugging purposes. * * @param doc The XML-Document to print */ public static void debug(Document doc) { XMLWriter dbg = new XMLWriter(System.out); dbg.print(doc); } /** * Prints out the DOM-Tree to a file for debugging purposes. * The file will be truncated if it exists or created if if does * not exist. * * @param doc The XML-Document to print * @param filename The name of the file to write the XML-Document to */ public static void debugToFile(Document doc, String filename) { String styleSheet = "../" + filename.substring(0, filename.length() - 3) + "xslt"; FileOutputStream fileOutputStream = null; try { File file = new File(xmlWriterRoot, filename); if (file.exists() == true) { file.delete(); } // do wen need this? file.createNewFile(); fileOutputStream = new FileOutputStream(file); // write xml XMLWriter dbg = new XMLWriter(fileOutputStream); dbg.print(doc, styleSheet); } catch (IOException ioe) { log.error("Error: Could not write XML to file: " + filename + " in directory: " + xmlWriterRoot); } finally { try { if (fileOutputStream != null) { fileOutputStream.close(); } } catch (IOException ioe) { log.error("Cannot write Document file", ioe); /* Ignore IOExceptions */ } } } /** * Prints out the DOM-Tree. The file will be truncated if it * exists or created if if does not exist. * * @param doc The XML-Document to print * @param filename The name of the file to write the XML-Document to */ public static void saveAsFile(Document doc, String filename) { try { File file = new File(filename); if (file.exists() == true) { file.delete(); } DOMSource domSource = new DOMSource(doc); StreamResult streamResult = new StreamResult(file); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer trf = transformerFactory.newTransformer(); trf.transform(domSource, streamResult); } catch (Exception ex) { log.error("Error: Could not write XML to file: " + filename); } } public static void setXmlWriterDebugPath(String path) { xmlWriterRoot = path; } /** * Creates a XML Writer object. * * @param writer a writer to the output stream * @param charsetEncoding encoding type (i.e. utf-8) */ public XMLWriter(Writer writer, String charsetEncoding) { this.out = new PrintWriter(writer); this.charsetEncoding = charsetEncoding; this.canonical = false; } /** * Creates a XML Writer object. * * @param outStream the output stream * @param charsetEncoding The name of a supported * {@link java.nio.charset.Charset charset} * * @throws UnsupportedEncodingException If the named encoding is not supported */ public XMLWriter(OutputStream outStream, String charsetEncoding) throws UnsupportedEncodingException { // Set Debug Level this(new OutputStreamWriter(outStream, charsetEncoding), charsetEncoding); } /** * Constructor * * @param outStream the output stream */ public XMLWriter(OutputStream outStream) { try { this.charsetEncoding = "utf-8"; this.out = new PrintWriter(new OutputStreamWriter(outStream, charsetEncoding)); this.canonical = false; } catch (UnsupportedEncodingException e) { log.error("The encoding \"" + this.charsetEncoding + "\" is not supported!", e); } } /** * Prints the specified node recursively * * @param node the current node to print * @param level the nesting level used for indenting the output * @return the node type of this node */ public int print(Node node, int level) { // is there anything to do? if (node == null) { return 0; } int type = node.getNodeType(); switch (type) { // print document case Node.DOCUMENT_NODE: { // Sound not come here print(((Document) node).getDocumentElement(), 0); } break; // print element with attributes case Node.ELEMENT_NODE: { // out out.print('<'); out.print(node.getNodeName()); Attr attrs[] = sortAttributes(node.getAttributes()); for (int i = 0; i < attrs.length; i++) { Attr attr = attrs[i]; out.print(' '); out.print(attr.getNodeName()); out.print("=\""); out.print(normalize(attr.getNodeValue())); out.print('"'); } // children NodeList children = node.getChildNodes(); if (children != null) { // close-tag int len = children.getLength(); if (len > 0 && children.item(0).getNodeType() != Node.TEXT_NODE) out.println('>'); else out.print('>'); // Print all Children int prevType = 0; for (int i = 0; i < len; i++) { if (i > 0 || children.item(i).getNodeType() != Node.TEXT_NODE) { // Indent next Line for (int s = 0; s < level; s++) out.print(" "); } // Print a child prevType = print(children.item(i), level + 1); } // Endtag if (len > 0 && prevType != Node.TEXT_NODE) { // padding for (int s = 1; s < level; s++) out.print(" "); } out.print("'); } else out.println("/>"); break; } // handle entity reference nodes case Node.ENTITY_REFERENCE_NODE: { if (canonical) { NodeList children = node.getChildNodes(); if (children != null) { int len = children.getLength(); for (int i = 0; i < len; i++) { print(children.item(i), level + 1); } } } else { out.print('&'); out.print(node.getNodeName()); out.print(';'); } break; } // print cdata sections case Node.CDATA_SECTION_NODE: { if (canonical == false) { out.print(""); } else out.print(normalize(node.getNodeValue())); break; } // print text case Node.TEXT_NODE: { // Text out.print(normalize(node.getNodeValue())); break; } // print processing instruction case Node.PROCESSING_INSTRUCTION_NODE: { out.print(" 0) { out.print(' '); out.print(data); } out.println("?>"); break; } } out.flush(); return type; } // print(Node) /** * Prints the specified document. * * @param doc the XML-DOM-Document to print */ public void print(Document doc) { print(doc, null); } /** * Prints the specified document. * * @param doc the XML-DOM-Document to print * @param styleSheet the XML-DOM-Document to print */ public void print(Document doc, String styleSheet) { if (!canonical) { out.println(""); } if (styleSheet != null) { //20040427 Marco: xml stylesheet document specification changed from ""); } // Print the Document print(doc.getDocumentElement(), 0); out.flush(); } /** * Sorts attributes by name. * * @param attrs the unsorted list of attributes * @return the sorted list of attributes */ protected Attr[] sortAttributes(NamedNodeMap attrs) { int len = (attrs != null) ? attrs.getLength() : 0; Attr array[] = new Attr[len]; for (int i = 0; i < len; i++) { array[i] = (Attr) attrs.item(i); } for (int i = 0; i < len - 1; i++) { String name = array[i].getNodeName(); int index = i; for (int j = i + 1; j < len; j++) { String curName = array[j].getNodeName(); if (curName.compareTo(name) < 0) { name = curName; index = j; } } if (index != i) { Attr temp = array[i]; array[i] = array[index]; array[index] = temp; } } return (array); } // sortAttributes(NamedNodeMap):Attr[] /** * Converts a string to valid XML-Syntax replacing XML entities. * * @param s the string to normalize */ protected String normalize(String s) { return normalize(s, canonical); } static public String normalize(String s, boolean canonical) { StringBuilder str = new StringBuilder(); int len = (s != null) ? s.length() : 0; for (int i = 0; i < len; i++) { char ch = s.charAt(i); switch (ch) { case '<': { str.append("<"); break; } case '>': { str.append(">"); break; } case '&': { str.append("&"); break; } case '"': { str.append("""); break; } case '\r': case '\n': { if (canonical) { str.append("&#"); str.append(Integer.toString(ch)); str.append(';'); break; } // else, default append char } default: { str.append(ch); } } } return (str.toString()); } // normalize(String):String }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy