package com.dbxml.xml.text;
/*
* dbXML - Native XML Database
* Copyright (c) 1999-2006 The dbXML Group, L.L.C.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* $Id: TextProducer.java,v 1.8 2006/02/02 19:04:46 bradford Exp $
*/
import com.dbxml.xml.dtsm.*;
import com.dbxml.util.UTF8;
import com.dbxml.xml.QName;
import com.dbxml.xml.SymbolTable;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
/**
* TextProducer
*/
public final class TextProducer extends Producer implements Consumer {
private PrintWriter writer;
private boolean omitPrefix;
public TextProducer(DocumentTable table, boolean omitPrefix) {
this(table);
this.omitPrefix = omitPrefix;
}
public TextProducer(DocumentTable table) {
setDocumentTable(table);
}
public static String toString(DocumentTable table) throws Exception {
TextProducer p = new TextProducer(table);
int size = (table.getEntryCount() * Constants.DOC_ENTRY_SIZE)
+ (table.getValueCount() * Constants.VAL_ENTRY_SIZE)
+ (table.getValueCount() * 64);
StringWriter w = new StringWriter(size);
p.setWriter(w);
p.process();
return w.getBuffer().toString();
}
public static void toWriter(DocumentTable table, Writer writer) throws Exception {
TextProducer p = new TextProducer(table);
p.setWriter(writer);
p.process();
writer.flush();
}
public void setWriter(PrintWriter writer) {
this.writer = writer;
}
public void setWriter(Writer writer) {
this.writer = new PrintWriter(writer);
}
public void beginDocument(DocumentTableEntry entry) throws Exception {
if ( !omitPrefix )
writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
}
public void endDocument(DocumentTableEntry entry) throws Exception {
}
public void beginElement(DocumentTableEntry entry) throws Exception {
int symID = entry.getValID();
QName qname = symbols.getQName(symID);
writer.print('<');
writer.print(qname.getName());
while ( processor.peek().getTypeID() == Constants.OBJ_BEGIN_ATTRIBUTE )
attribute(processor.next());
if ( processor.peek().getTypeID() == Constants.OBJ_END_ELEMENT ) {
processor.next();
writer.print("/>");
}
else
writer.print('>');
}
public void endElement(DocumentTableEntry entry) throws Exception {
int symID = entry.getValID();
QName qname = symbols.getQName(symID);
writer.print("</");
writer.print(qname.getName());
writer.print('>');
}
public void attribute(DocumentTableEntry entry) throws Exception {
int symID = entry.getValID();
QName qname = symbols.getQName(symID);
String uri = qname.getURI();
writer.print(' ');
writer.print(qname.getName());
writer.print("=\"");
do {
entry = processor.next();
if ( entry.getTypeID() == Constants.OBJ_TEXT ) {
int valID = entry.getValID();
writeEscapedText(UTF8.toCharArray(table.getValue(valID)));
}
}
while ( entry.getTypeID() != Constants.OBJ_END_ATTRIBUTE );
writer.print('\"');
}
public void procInst(DocumentTableEntry entry) throws Exception {
int symID = entry.getValID();
QName qname = symbols.getQName(symID);
entry = processor.next();
int valID = entry.getValID();
processor.next(); // Eat the OBJ_END_PROCINST
writer.print("<?");
writer.print(qname.getName());
writer.print(' ');
UTF8.toWriter(table.getValue(valID), writer);
writer.println("?>");
}
public void text(DocumentTableEntry entry) throws Exception {
int valID = entry.getValID();
writeEscapedText(UTF8.toCharArray(table.getValue(valID)));
}
public void cdata(DocumentTableEntry entry) throws Exception {
int valID = entry.getValID();
writer.print("<![CDATA[");
UTF8.toWriter(table.getValue(valID), writer);
writer.print("]]>");
}
public void comment(DocumentTableEntry entry) throws Exception {
int valID = entry.getValID();
writer.print("<!--");
UTF8.toWriter(table.getValue(valID), writer);
writer.print("-->");
}
public void docType(DocumentTableEntry entry) {
processor.next(); // Eat the OBJ_END_DOCTYPE
}
public void entity(DocumentTableEntry entry) {
int symID = entry.getValID();
String name = symbols.getQName(symID).getName();
entry = processor.next(); // Get Public ID
int valID = entry.getValID();
String publicID = table.getValue(valID).toString();
entry = processor.next(); // Get System ID
valID = entry.getValID();
String systemID = table.getValue(valID).toString();
entry = processor.next(); // Get Notation Name
valID = entry.getValID();
String notation = table.getValue(valID).toString();
processor.next(); // Eat the OBJ_END_ENTITY
/** @todo Figure out how to create an Entity node with Text */
}
public void entityRef(DocumentTableEntry entry) {
/** @todo This */
}
public void notation(DocumentTableEntry entry) {
int symID = entry.getValID();
String name = symbols.getQName(symID).getName();
entry = processor.next(); // Get Public ID
int valID = entry.getValID();
String publicID = table.getValue(valID).toString();
entry = processor.next(); // Get System ID
valID = entry.getValID();
String systemID = table.getValue(valID).toString();
processor.next(); // Eat the OBJ_END_NOTATION
writer.print("<!NOTATION ");
writer.print(name);
if ( publicID != null && publicID.length() > 0 ) {
writer.print(" PUBLIC ");
writer.print(publicID);
if ( systemID != null && systemID.length() > 0 ) {
writer.print(' ');
writer.print(systemID);
}
}
else if ( systemID != null && systemID.length() > 0 ) {
writer.print(" SYSTEM ");
writer.print(systemID);
}
writer.print('>');
}
private void writeEscapedText(char[] value) throws Exception {
String outval = null;
int start = 0;
int len = 0;
for ( int i = 0; i < value.length; i++ ) {
char c = value[i];
switch ( c ) {
case '&':
outval = "&";
break;
case '\'':
outval = "'";
break;
case '\"':
outval = """;
break;
case '<':
outval = "<";
break;
case '>':
outval = ">";
break;
case ' ':
case '\n':
case '\r':
case '\t':
len++;
continue;
default:
if ( c < ' ' || c == 127 ) {
outval = "&#x" + Integer.toHexString(c) + ";";
break;
}
else {
len++;
continue;
}
}
if ( outval != null ) {
if ( len > 0 )
writer.write(value, start, len);
writer.write(outval);
start = i + 1;
len = 0;
outval = null;
}
}
if ( len > 0 )
writer.write(value, start, len);
}
}