
org.enhydra.xml.dom.DOMInfoPrinter Maven / Gradle / Ivy
The newest version!
/*
* Enhydra Java Application Server Project
*
* The contents of this file are subject to the Enhydra Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License on
* the Enhydra web site ( http://www.enhydra.org/ ).
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific terms governing rights and limitations
* under the License.
*
* The Initial Developer of the Enhydra Application Server is Lutris
* Technologies, Inc. The Enhydra Application Server and portions created
* by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
* All Rights Reserved.
*
* Contributor(s):
*
* $Id: DOMInfoPrinter.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
*/
package org.enhydra.xml.dom;
import java.io.PrintWriter;
import org.enhydra.xml.xmlc.codegen.JavaLang;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Entity;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Notation;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
/**
* DOMTraversal handler for DOMInfo, using only generic DOM interfaces.
*/
public class DOMInfoPrinter implements DOMTraversal.Handler {
/** Size to truncate text to */
private static final int TEXT_TRUNCATE_SIZE = 12;
/** Writer for output. */
protected PrintWriter fOut;
/** Print lines breaks as \n and \r */
private boolean fSymbolicLineBreaks;
/** Should text strings be truncated? */
private boolean fTruncateText;
/** Control attribute formatting. */
protected boolean fVerboseAttributes;
/** Should all attributes, or only specified ones be printed? */
protected boolean fAllAttributes;
/**
* Flag to indicate that nothing should be printed, just nodes counted.
* Use to implement terse attribute printing, nonly need be checked on
* thinks that can be children of attributes.
*/
protected boolean fAttrSkipPrint;
/**
* DOM traversal object.
*/
private DOMTraversal fTraverser;
/**
* Indent level.
*/
protected int level;
/**
* Constructor.
*/
protected DOMInfoPrinter(int options,
DOMTraversal traverser,
PrintWriter out) {
fOut = out;
fSymbolicLineBreaks = ((options & DOMInfo.SYM_TEXT_LINEBREAKS) != 0);
fTruncateText = ((options & DOMInfo.TRUNCATE_TEXT) != 0);
fVerboseAttributes = ((options & DOMInfo.PRINT_ATTR_DETAILS) != 0);
fAllAttributes = ((options & DOMInfo.ALL_ATTRS) != 0);
fTraverser = traverser;
traverser.setHandler(this);
}
/**
* Print indentation.
*/
protected void printIndent() {
for (int i = 0; i < level + 1; i++) {
fOut.print(" ");
}
}
/**
* Determine if a character should be printed as is.
*/
private boolean isPrintable(char ch) {
return ((ch <= 0x7f)
&& (Character.isWhitespace(ch) || !Character.isISOControl(ch)));
}
/**
* Print a block of text, encoding non-ASCII or ISO control
* charcters using the \u0000 convention.
*/
private void printString(String text) {
int len = text.length();
for (int idx = 0; idx < len; idx++) {
char ch = text.charAt(idx);
if (fSymbolicLineBreaks && ((ch == '\n') || (ch == '\r'))) {
fOut.write((ch == '\n') ? "\\n" : "\\r");
} else if (isPrintable(ch)) {
fOut.write(ch);
} else {
String hex = Integer.toHexString(ch);
fOut.write("\\u");
for (int cnt = hex.length(); cnt < 4; cnt++) {
fOut.write('0');
}
fOut.write(hex);
}
}
}
/*
* Print a label and value if the value is not null or empty.
*/
private void printLabelValue(String label,
String value) {
if ((value != null) && (value.length() > 0)) {
fOut.print(" ");
fOut.print(label);
fOut.print("=");
printString(value);
}
}
/**
* Print a name, with a space in front of it, if not null.
*/
private void printName(String name) {
if (name != null) {
fOut.print(" ");
fOut.print(name);
}
}
/**
* Print node name (override to add additional information).
*/
protected void printNodeName(Node node) {
fOut.print(JavaLang.simpleClassName(node.getClass().getName()));
}
/**
* Print the basic information displayed about every node.
*/
private void printNodeInfo(Node node) {
// Print node class name without package.
printIndent();
printNodeName(node);
fOut.print(':');
String namespaceURI = node.getNamespaceURI();
if ((namespaceURI != null) && (namespaceURI.length() > 0)) {
printLabelValue("NS", namespaceURI);
fOut.print(":");
}
}
/**
* Process children.
*/
private void processChildren(Node node) {
level++;
fTraverser.processChildren(node);
level--;
}
/**
* Determine if an element has attributes that are to be printed.
*/
protected boolean hasPrintAttributes(Element element) {
NamedNodeMap attrs = element.getAttributes();
if (attrs == null) {
return false;
}
if (fAllAttributes) {
return attrs.getLength() > 0;
}
// Check for specified attributes.
for (int i = 0; i < attrs.getLength(); i++) {
if (((Attr)attrs.item(i)).getSpecified()) {
return true;
}
}
return false;
}
/**
* Handler called for Document nodes.
*/
public void handleDocument(Document document) {
printNodeInfo(document);
fOut.println();
level++;
fTraverser.processDocumentType(document);
level--;
processChildren(document);
}
/**
* Handler called for DocumentType nodes.
*/
public void handleDocumentType(DocumentType documentType) {
printNodeInfo(documentType);
printLabelValue("name", documentType.getNodeName());
fOut.println();
String internalSubset = documentType.getInternalSubset();
if ((internalSubset != null) && (internalSubset.length() > 0)) {
printIndent();
printLabelValue("internalSubset", internalSubset);
fOut.println();
}
level++;
fTraverser.processDocumentTypeContents(documentType);
// It is non-standard to have children of a document type,
// however Xerces uses this for grammar.
processChildren(documentType);
level--;
}
/**
* Handler called for DocumentFragment nodes.
*/
public void handleDocumentFragment(DocumentFragment documentFragment) {
printNodeInfo(documentFragment);
printLabelValue("name", documentFragment.getNodeName());
fOut.println();
processChildren(documentFragment);
}
/**
* Print an attribute in a terse manner.
*/
private void printTerseAttrInfo(Node attr) {
printName(attr.getNodeName());
fOut.print("=\"");
printString(attr.getNodeValue());
fOut.print("\"");
}
/**
* Print an attribute in a verbose manner.
*/
private void printVerboseAttrInfo(Node attr) {
printNodeInfo(attr);
printName(attr.getNodeName());
if (!((Attr)attr).getSpecified()) {
fOut.print(" (unspecified)");
}
fOut.println();
}
/**
* Handler called for Attr nodes.
*/
public void handleAttr(Attr attr) {
if (fVerboseAttributes) {
printVerboseAttrInfo(attr);
} else {
printTerseAttrInfo(attr);
}
fAttrSkipPrint = !fVerboseAttributes;
processChildren(attr);
fAttrSkipPrint = false;
}
/**
* Handler called for Entity nodes.
*/
public void handleEntity(Entity entity) {
printNodeInfo(entity);
printLabelValue("name", entity.getNodeName());
printLabelValue("notationName", entity.getNotationName());
printLabelValue("systemId", entity.getPublicId());
printLabelValue("publicId", entity.getPublicId());
fOut.println();
processChildren(entity);
}
/**
* Handler called for EntityReference nodes.
*/
public void handleEntityReference(EntityReference entityRef) {
if (!fAttrSkipPrint) {
printNodeInfo(entityRef);
printLabelValue("name", entityRef.getNodeName());
fOut.println();
}
processChildren(entityRef);
}
/**
* Process an element's attributes.
*/
private void processAttributes(Element element) {
if (fVerboseAttributes) {
fOut.println();
if (hasPrintAttributes(element)) {
level++;
printIndent();
fOut.println("Attributes:");
level++;
fTraverser.processAttributes(element);
level -= 2;
}
} else {
if (hasPrintAttributes(element)) {
fOut.print(":");
fTraverser.processAttributes(element);
}
fOut.println();
}
}
/**
* Handler called for Element nodes.
*/
public void handleElement(Element element) {
printNodeInfo(element);
printName(element.getNodeName());
processAttributes(element);
processChildren(element);
}
/**
* Handler called for Notation nodes.
*/
public void handleNotation(Notation notation) {
if (!fAttrSkipPrint) {
printNodeInfo(notation);
printLabelValue("systemId", notation.getSystemId());
printLabelValue("publicId", notation.getPublicId());
}
}
/**
* Handler called for ProcessingInstruction nodes.
*/
public void handleProcessingInstruction(ProcessingInstruction pi) {
if (!fAttrSkipPrint) {
printNodeInfo(pi);
printLabelValue("target", pi.getTarget());
printLabelValue("data", pi.getData());
fOut.println();
}
}
/**
* Print information about any of the CharacterData nodes.
*/
private void printCharacterDataInfo(CharacterData charData) {
if (!fAttrSkipPrint) {
printNodeInfo(charData);
fOut.print(" ");
String data = charData.getData();
if (fTruncateText && (data.length() > TEXT_TRUNCATE_SIZE)) {
data = data.substring(0, TEXT_TRUNCATE_SIZE);
}
printString(data);
fOut.println();
}
}
/**
* Handler called for CDATASection nodes.
*/
public void handleCDATASection(CDATASection cdata) {
printCharacterDataInfo(cdata);
}
/**
* Handler called for Comment nodes.
*/
public void handleComment(Comment comment) {
printCharacterDataInfo(comment);
}
/**
* Handler called for Text nodes.
*/
public void handleText(Text text) {
printCharacterDataInfo(text);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy