alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 *
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
package org.netbeans.tax.io;

import java.lang.reflect.*;

import java.io.Writer;
import java.io.StringWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.PipedWriter;

import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import java.text.MessageFormat;

import org.netbeans.tax.TreeException;
import org.netbeans.tax.TreeDocumentRoot;
import org.netbeans.tax.TreeNode;
import org.netbeans.tax.TreeChild;
import org.netbeans.tax.TreeObjectList;
import org.netbeans.tax.TreeParentNode;

import org.netbeans.tax.TreeAttlistDecl;
import org.netbeans.tax.TreeAttlistDeclAttributeDef;
import org.netbeans.tax.TreeAttribute;
import org.netbeans.tax.TreeCDATASection;
import org.netbeans.tax.TreeCharacterReference;
import org.netbeans.tax.TreeCharacterData;
import org.netbeans.tax.TreeComment;
import org.netbeans.tax.TreeConditionalSection;
import org.netbeans.tax.TreeDocumentFragment;
import org.netbeans.tax.TreeDocument;
import org.netbeans.tax.TreeDocumentType;
import org.netbeans.tax.TreeDTD;
import org.netbeans.tax.TreeElementDecl;
import org.netbeans.tax.TreeElement;
import org.netbeans.tax.TreeEntityDecl;
import org.netbeans.tax.TreeGeneralEntityReference;
import org.netbeans.tax.TreeNotationDecl;
import org.netbeans.tax.TreeParameterEntityReference;
import org.netbeans.tax.TreeProcessingInstruction;
import org.netbeans.tax.TreeText;
import org.netbeans.tax.TreeUtilities;

import org.netbeans.tax.spec.AttlistDecl;
import org.netbeans.tax.spec.Attribute;
import org.netbeans.tax.spec.CDATASection;
import org.netbeans.tax.spec.CharacterReference;
import org.netbeans.tax.spec.Comment;
import org.netbeans.tax.spec.ConditionalSection;
import org.netbeans.tax.spec.DocumentFragment;
import org.netbeans.tax.spec.Document;
import org.netbeans.tax.spec.DocumentType;
import org.netbeans.tax.spec.DTD;
import org.netbeans.tax.spec.ElementDecl;
import org.netbeans.tax.spec.Element;
import org.netbeans.tax.spec.EntityDecl;
import org.netbeans.tax.spec.GeneralEntityReference;
import org.netbeans.tax.spec.NotationDecl;
import org.netbeans.tax.spec.ParameterEntityReference;
import org.netbeans.tax.spec.ProcessingInstruction;
import org.netbeans.tax.spec.Text;

/**
 * We should avoid MessageFormat usage, it is probably the slowest method
 * for constructing output.
 * 

* Fast implementation would write directly to steam/StringBuffer without * construction so many auxiliary Strings. * * @author Libor Kramolis * @version 0.1 */ public class TreeStreamResult implements TreeOutputResult { /** */ private TreeStreamWriter writer; // // init // /** Creates new TreeStreamResult. */ public TreeStreamResult (OutputStream outputStream) { this.writer = new TreeStreamWriter (outputStream); } /** Creates new TreeStreamResult. */ public TreeStreamResult (StringWriter writer) { this.writer = new TreeStreamWriter (writer); } public TreeStreamResult (PipedWriter writer) { this.writer = new TreeStreamWriter (writer); } // // itself // /** */ public final TreeWriter getWriter (TreeDocumentRoot document) { writer.setDocument (document); return writer; } // // Writer // /** * */ public final static class TreeStreamWriter implements TreeWriter, AttlistDecl.Writer, Attribute.Writer, CDATASection.Writer, CharacterReference.Writer, Comment.Writer, ConditionalSection.Writer, DocumentFragment.Writer, Document.Writer, DocumentType.Writer, DTD.Writer, ElementDecl.Writer, Element.Writer, EntityDecl.Writer, GeneralEntityReference.Writer, NotationDecl.Writer, ParameterEntityReference.Writer, ProcessingInstruction.Writer, Text.Writer { private static final char LESS_THAN = '<'; private static final char GREAT_THAN = '>'; private static final char AMPERSAND = '&'; private static final char SEMICOLON = ';'; private static final char APOSTROPHE = '\''; private static final char QUOTE = '"'; private static final char PER_CENT = '%'; private static final char ASSIGN = '='; private static final char BRACKET_LEFT = '['; private static final char SPACE = ' '; private static final String PI_START = ""; // NOI18N private static final String COMMENT_START = ""; // NOI18N private static final String ELEMENT_EMPTY_END = " />"; // NOI18N private static final String ELEMENT_END_START = ""; // NOI18N private static final String DOCTYPE_START = ""; // NOI18N private static final String CHAR_REF_START = "&#"; // NOI18N private static final String CHAR_REF_HEX_START = "&#x"; // NOI18N private static final String ELEMENT_DECL_START = ".Writer // /** */ public void writeAttlistDecl (TreeAttlistDecl attlistDecl) throws TreeException { StringBuffer sb = new StringBuffer (); sb.append (ATTLIST_DECL_START).append (attlistDecl.getElementName ()); List attrdefs = attlistDecl.getAttributeDefs (); Iterator it = attrdefs.iterator (); while (it.hasNext ()) { TreeAttlistDeclAttributeDef attrDef = (TreeAttlistDeclAttributeDef)it.next (); sb.append ("\n\t").append (attrDef.getName ()).append (SPACE); // NOI18N if (attrDef.getType () != attrDef.TYPE_ENUMERATED) { sb.append (attrDef.getTypeName ()).append (SPACE); } if ((attrDef.getType () == TreeAttlistDeclAttributeDef.TYPE_ENUMERATED) || (attrDef.getType () == TreeAttlistDeclAttributeDef.TYPE_NOTATION)) { sb.append (attrDef.getEnumeratedTypeString ()).append (SPACE); } if (attrDef.getDefaultType () != TreeAttlistDeclAttributeDef.DEFAULT_TYPE_NULL) { sb.append (attrDef.getDefaultTypeName ()).append (SPACE); } if ((attrDef.getDefaultType () == TreeAttlistDeclAttributeDef.DEFAULT_TYPE_FIXED) || (attrDef.getDefaultType () == TreeAttlistDeclAttributeDef.DEFAULT_TYPE_NULL)) { sb.append ("\"").append (attrDef.getDefaultValue ()).append ("\""); // NOI18N } } sb.append (GREAT_THAN); write (sb.toString ()); } /** * Write down the attribute if it was specified in document otherwise nothing. */ public void writeAttribute (TreeAttribute attribute) throws TreeException { if (attribute.isSpecified () == false) return; write (createValueString (attribute.getQName (), attribute.getNonNormalizedValue ())); } /** */ public void writeCDATASection (TreeCDATASection cdataSection) throws TreeException { String cdataData = cdataSection.getData (); String cdataString = MessageFormat.format ("", new Object [] { cdataData }); // NOI18N write (cdataString); } /** */ public void writeCharacterReference (TreeCharacterReference characterReference) throws TreeException { String refName = characterReference.getName (); String refString = MessageFormat.format ("&{0};", new Object [] { refName }); // NOI18N write (refString); } /** */ public void writeComment (TreeComment comment) throws TreeException { String comName = comment.getData (); String comString = MessageFormat.format ("", new Object [] { comName }); // NOI18N write (comString); } /** */ public void writeConditionalSection (TreeConditionalSection conditionalSection) throws TreeException { if ( conditionalSection.isInclude () ) { write (""); // NOI18N } /** */ public void writeDocumentFragment (TreeDocumentFragment documentFragment) throws TreeException { StringBuffer sb = new StringBuffer (); StringBuffer header = null; if (documentFragment.getVersion () != null) { if (header == null) header = new StringBuffer (); header.append (createValueString (XML_VERSION, documentFragment.getVersion ())).append (SPACE); } if (documentFragment.getEncoding () != null) { if (header == null) header = new StringBuffer (); header.append (createValueString (XML_ENCODING, documentFragment.getEncoding ())); } if (header != null) { sb.append (XML_HEADER).append (header).append (PI_END); } write (sb.toString () + "\n\n"); // NOI18N indent -= indent_step; writeObjectList (documentFragment); } /** */ public void writeDocument (TreeDocument document) throws TreeException { StringBuffer sb = new StringBuffer (); StringBuffer header = null; if (document.getVersion () != null) { if (header == null) header = new StringBuffer (); header.append (createValueString (XML_VERSION, document.getVersion ())); } if (document.getEncoding () != null) { if (header == null) header = new StringBuffer (); header.append (SPACE).append (createValueString (XML_ENCODING, document.getEncoding ())); } if (document.getStandalone () != null) { if (header == null) header = new StringBuffer (); header.append (SPACE).append (createValueString (XML_STANDALONE, document.getStandalone ())); } if (header != null) { sb.append (XML_HEADER).append (header).append (PI_END); } write (sb.toString () + "\n\n"); // NOI18N indent -= indent_step; writeObjectList (document); } /** */ public void writeDocumentType (TreeDocumentType documentType) throws TreeException { StringBuffer sb = new StringBuffer (); sb.append (DOCTYPE_START).append (documentType.getElementName ()); if (documentType.getPublicId () != null) { sb.append (SPACE).append (PUBLIC); sb.append (createQuoteString (documentType.getPublicId ())).append (SPACE); String systemId = documentType.getSystemId (); sb.append (createQuoteString (systemId == null ? "" : systemId)); // NOI18N } else if (documentType.getSystemId () != null) { sb.append (SPACE).append (SYSTEM); sb.append (createQuoteString (documentType.getSystemId ())); } write (sb.toString ()); if ( documentType.hasChildNodes () ) { write (" ["); // NOI18N //!!! use introspection to get internal DTD try { if (documentType == null) return; Class klass = documentType.getClass (); Field field = klass.getDeclaredField ("internalDTDText"); // NOI18N field.setAccessible (true); String internalDTDText = (String)field.get (documentType); if ( internalDTDText != null ) { write (internalDTDText); } else { // use tradition method instead (however it will resolve refs) write ("\n"); // NOI18N writeObjectList (documentType); } } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { // use tradition method instead (however it will resolve refs) write ("\n"); // NOI18N writeObjectList (documentType); } write ("]"); // NOI18N } write (GREAT_THAN); // NOI18N } /** */ public void writeDTD (TreeDTD dtd) throws TreeException { StringBuffer sb = new StringBuffer (); StringBuffer header = null; if (dtd.getVersion () != null) { if (header == null) header = new StringBuffer (); header.append (createValueString (XML_VERSION, dtd.getVersion ())).append (SPACE); } if (dtd.getEncoding () != null) { if (header == null) header = new StringBuffer (); header.append (createValueString (XML_ENCODING, dtd.getEncoding ())); } if (header != null) { sb.append (XML_HEADER).append (header).append (PI_END); } write (sb.toString () + "\n\n"); // NOI18N indent -= indent_step; writeObjectList (dtd); } /** */ public void writeElementDecl (TreeElementDecl elementDecl) throws TreeException { StringBuffer sb = new StringBuffer (); sb.append (ELEMENT_DECL_START).append (elementDecl.getName ()).append (SPACE); sb.append (elementDecl.getContentType ().toString ()); sb.append (GREAT_THAN); write (sb.toString ()); } /** */ public void writeElement (TreeElement element) throws TreeException { String elemName = element.getQName (); write ("<" + elemName); // NOI18N Iterator it = element.getAttributes ().iterator (); while ( it.hasNext () ) { TreeAttribute attr = (TreeAttribute)it.next (); if (attr.isSpecified ()) { write (SPACE); writeAttribute (attr); } } if (element.isEmpty ()) { write ("/>"); // NOI18N } else { write (">"); // NOI18N // content writeObjectList (element); // startIndent(); String endElemString = MessageFormat.format ("", new Object [] { elemName }); // NOI18N write (endElemString); } } /** */ public void writeEntityDecl (TreeEntityDecl entityDecl) throws TreeException { String entParam = entityDecl.isParameter () ? "% " : ""; // NOI18N String entName = entityDecl.getName (); String entType = ""; // NOI18N switch (entityDecl.getType ()) { case TreeEntityDecl.TYPE_INTERNAL: entType = "\"" + entityDecl.getInternalText () + "\""; // NOI18N break; case TreeEntityDecl.TYPE_EXTERNAL: entType = createExternalIdString (entityDecl.getPublicId (), entityDecl.getSystemId ()); break; case TreeEntityDecl.TYPE_UNPARSED: entType = createExternalIdString (entityDecl.getPublicId (), entityDecl.getSystemId ()) + " NDATA " + entityDecl.getNotationName (); // NOI18N break; } String entString = MessageFormat.format ("", new Object [] { entParam, entName, entType }); // NOI18N write (entString); } /** */ public void writeGeneralEntityReference (TreeGeneralEntityReference generalEntityReference) throws TreeException { String refName = generalEntityReference.getName (); String refString = MessageFormat.format ("&{0};", new Object [] { refName }); // NOI18N write (refString); } /** */ public void writeNotationDecl (TreeNotationDecl notationDecl) throws TreeException { String notName = notationDecl.getName (); String notSysId = notationDecl.getSystemId (); String notPubId = notationDecl.getPublicId (); String notExtId = createExternalIdString (notPubId, notSysId); String notString = MessageFormat.format ("", new Object [] { notName, notExtId }); // NOI18N write (notString); } /** */ public void writeParameterEntityReference (TreeParameterEntityReference parameterEntityReference) throws TreeException { String refName = parameterEntityReference.getName (); String refString = MessageFormat.format ("%{0};", new Object [] { refName }); // NOI18N write (refString); } /** */ public void writeProcessingInstruction (TreeProcessingInstruction processingInstruction) throws TreeException { String piTarget = processingInstruction.getTarget (); String piData = processingInstruction.getData (); String piString = MessageFormat.format ("", new Object [] { piTarget, piData }); // NOI18N write (piString); } /** */ public void writeText (TreeText text) throws TreeException { String textString = text.getData (); write (textString); } // // itself // private void write (String string) throws TreeException { try { writer.write (string); } catch (IOException exc) { throw new TreeException (exc); } } private void write (char ch) throws TreeException { try { writer.write (ch); } catch (IOException exc) { throw new TreeException (exc); } } private void startIndent () throws TreeException { StringBuffer sb = new StringBuffer (); for (int i = 0; i < indent; i++) { sb.append (' '); } try { writer.write (sb.toString ()); } catch (IOException exc) { throw new TreeException (exc); } } private void endIndent () throws TreeException { write ("\n"); // NOI18N } private void writeObjectList (TreeParentNode parentNode) throws TreeException { indent += indent_step; boolean notElementChild = ( parentNode instanceof TreeElement ) == false; boolean documentChild = ( parentNode instanceof TreeDocument ) == true; Iterator it = parentNode.getChildNodes ().iterator (); while ( it.hasNext () ) { TreeNode node = (TreeNode)it.next (); // boolean isNotCharData = ( node instanceof TreeCharacterData ) == false; if ( notElementChild ) { // if ( isNotCharData ) { startIndent (); } writeNode (node); if ( notElementChild ) { // if ( isNotCharData ) { endIndent (); } if ( documentChild ) { endIndent (); } } indent -= indent_step; } /** * Writes name value pair (attribute, encoding, standalone,...) */ private String createValueString (String name, String value) { String valueString = MessageFormat.format ("{0}={1}", new Object [] { name, createQuoteString (value) }); // NOI18N return valueString; } /** * Autodetect quoting char giving highets priority to '"'. */ private String createQuoteString (String value) { Character quote = new Character (QUOTE); if ( value.indexOf (QUOTE) != -1 ) { quote = new Character (APOSTROPHE); } return createQuoteString (value, quote); } /** */ private String createQuoteString (String value, Character quote) { String valueString = MessageFormat.format ("{1}{0}{1}", new Object [] { value, quote }); // NOI18N return valueString; } /** */ private String createExternalIdString (String publicId, String systemId) { String externId; if (publicId == null) { externId = MessageFormat.format ("SYSTEM {0}", new Object [] { createQuoteString (systemId) }); // NOI18N } else if (systemId == null) { externId = MessageFormat.format ("PUBLIC {0}", new Object [] { createQuoteString (publicId) }); // NOI18N } else { externId = MessageFormat.format ("PUBLIC {0} {1}", new Object [] { createQuoteString (publicId), createQuoteString (systemId) }); // NOI18N } return externId; } } // end: class TreeStreamWriter }

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.