//
// Copyright (c)1998-2011 Pearson Education, Inc. or its affiliate(s).
// All rights reserved.
//
package openadk.util;
import java.io.InputStream;
import java.io.Writer;
import java.io.PrintWriter;
import java.io.OutputStream;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.regex.Pattern;
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 org.w3c.dom.Attr;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Node;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.w3c.dom.ls.LSSerializerFilter;
import org.w3c.dom.traversal.NodeFilter;
/**
* A PrintWriter for rendering xml streams
*
* @author Eric Petersen
* @version 1.0
*/
public class XMLWriter extends PrintWriter {
int fIndent = 0;
int fPauseTab = 0;
public XMLWriter(OutputStream out) {
super( out );
}
public XMLWriter(OutputStream out, boolean autoFlush) {
super( out, autoFlush );
}
public XMLWriter(Writer out) {
super( out );
}
public XMLWriter(Writer out, boolean autoFlush) {
super( out, autoFlush );
}
/**
* Increases the indentation by the specified number of tabs. The next call
* the <code>tab</code> will write the proper number of intentation spaces
* to the output stream unless tabbing has been paused.
*/
public void indent(int tabs) {
fIndent += tabs;
if ( fIndent < 0 )
fIndent = 0;
}
/**
* Increases the number of pauses to indentation. For each call to this
* function, the <code>tab</code> will do nothing.
*/
public void pauseTab() {
fPauseTab++;
}
/**
* Writes the proper number of intentation spaces to the output stream
* unless tabbing has been paused.
*/
public void tab() {
if ( fPauseTab > 0 )
fPauseTab--;
else
for ( int i = 0; i < fIndent * 2; i++ )
print( ' ' );
}
public String getAttrString(Dictionary attrs) {
if ( attrs != null ) {
StringBuilder a = new StringBuilder();
String key = null;
for ( Enumeration e = attrs.keys(); e.hasMoreElements(); ) {
key = (String) e.nextElement();
a.append( key );
a.append( "=\"" );
a.append( attrs.get( key ) );
a.append( '\"' );
}
return a.toString();
}
return "";
}
/**
* Encodes the given string for XML and then prints it
*
* @param xmlText
* the string that will be placed in an element or attribute text
*/
public void printXmlText(String xmlText) {
print( xmlEncode( xmlText ) );
}
/**
* Writes an XML DOM Element to the underlying Stream
* @param element
*/
public void write(org.w3c.dom.Element element) {
// try
// {
// TransformerFactory transformerFactory = TransformerFactory.newInstance();
// Transformer transformer = transformerFactory.newTransformer();
// transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
// transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" );
// transformer.transform( new DOMSource( element ), new StreamResult( this ) );
// }
// catch( Exception ex ){
// throw new RuntimeException( "Unable to write XML Element: " + ex.getMessage(), ex );
// }
// For the fun of it, try writing it out
try {
DOMImplementation implementation = DOMImplementationRegistry.newInstance().getDOMImplementation( "XML 3.0" );
DOMImplementationLS feature = (DOMImplementationLS) implementation.getFeature( "LS", "3.0" );
LSSerializer serializer = feature.createLSSerializer();
serializer.getDomConfig().setParameter("xml-declaration", false);
String serializedXml = serializer.writeToString(element);
// This is ugly but I can't see a better way to control this output here without writing our own serializer
// The point is to remove redundant namespace declarations, but leave any others intact.
if ("SIF_ExtendedElement".equals(element.getLocalName())) {
serializedXml = serializedXml.replaceFirst(" xmlns=['\"]" + element.getNamespaceURI() + "['\"]", "");
serializedXml = serializedXml.replaceFirst(" xmlns:xsi=['\"]http://www.w3.org/2001/XMLSchema-instance['\"]", "");
}
println(serializedXml);
} catch ( Exception e ) {
System.err.println( e );
}
}
/**
* Writes an XML DOM Document to the underlying stream
* @param document
*/
public void write( org.w3c.dom.Document document ){
if( document != null ){
write( document.getDocumentElement() );
}
}
/**
* Encodes the given string for XML
*
* @param text
* the string that will be placed in an element or attribute text
* @return An xml encoded string or "" if null
*/
public String xmlEncode(String text) {
if ( text == null ) {
return "";
} else {
return ADKStringUtils.encodeXML( text );
}
}
}