
org.apache.ws.jaxme.impl.XMLWriterImpl Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2003, 2004 The Apache Software Foundation
*
* Licensed 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.ws.jaxme.impl;
import org.apache.ws.jaxme.XMLWriter;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.Writer;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBException;
/** A simple serializer for XML documents.
*
* @author Jochen Wiedmann
*/
public class XMLWriterImpl implements XMLWriter {
private JMMarshallerImpl m;
private Writer w;
private Locator l;
private java.util.Map delayedPrefixes;
int curIndent = 0;
private static final int STATE_OUTSIDE = 0;
private static final int STATE_IN_START_ELEMENT = 1;
private static final int STATE_IN_ELEMENT = 2;
private int state;
/** Creates a new JaxbXmlSerializer */
public XMLWriterImpl() {}
/** Sets the JaxbXMLSerializers Marshaller.
*/
public void init(JMMarshallerImpl pMarshaller) throws JAXBException {
m = pMarshaller;
}
/** Returns the JaxbXMLSerializers Marshaller.
*/
public JMMarshallerImpl getMarshaller() {
return m;
}
/** Sets the JaxbXMLSerializers Writer.
*/
public void setWriter(Writer pWriter) throws JAXBException {
w = pWriter;
}
/** Returns the JaxbXMLSerializers Writer.
*/
public Writer getWriter() {
return w;
}
/** Sets the locator.
*
* @param pLocator A locator for use in case of errors
* @see #getDocumentLocator
*/
public void setDocumentLocator(Locator pLocator) { l = pLocator; }
/** Returns the locator
* @return A locator previously set with setDocumentLocator or null.
* @see #setDocumentLocator
*/
public Locator getDocumentLocator() { return l; }
/**
* Starts use of a namespace prefix.
*
* @param namespaceURI The namespace URI
* @param prefix The prefix
* @throws SAXException Not actually thrown, just for compliance to the interface specification.
*/
public void startPrefixMapping(String prefix, String namespaceURI)
throws SAXException {
if (delayedPrefixes == null) {
delayedPrefixes = new java.util.HashMap();
}
if ("".equals(prefix)) {
if (namespaceURI.equals(prefix)) {
return;
}
prefix = XMLConstants.XMLNS_ATTRIBUTE;
} else {
prefix = XMLConstants.XMLNS_ATTRIBUTE + ":" + prefix;
}
delayedPrefixes.put(prefix, namespaceURI);
}
/** Terminates use of a namespace prefix.
*
* @param prefix The prefix being abandoned.
* @throws SAXException Not actually thrown, just for compliance to the interface specification.
*/
public void endPrefixMapping(String prefix) throws SAXException {
if (delayedPrefixes != null) {
if ("".equals(prefix)) {
prefix = XMLConstants.XMLNS_ATTRIBUTE;
} else {
prefix = XMLConstants.XMLNS_ATTRIBUTE + ":" + prefix;
}
delayedPrefixes.remove(prefix);
}
}
/** Starts a document.
* @throws SAXException Not actually thrown, just for compliance to the interface specification.
*/
public void startDocument() throws SAXException {
if (delayedPrefixes != null) {
delayedPrefixes.clear();
}
state = STATE_OUTSIDE;
curIndent = 0;
}
/** This method finishs the handlers action. After calling endDocument you
* may start a new action by calling startDocument again.
*
* @throws SAXException Not actually thrown, just for compliance to the
* interface specification.
*/
public void endDocument() throws SAXException {}
/** Calls the character method with the same arguments.
* @param ch A string of whitespace characters being inserted into the document.
* @param start The index of the first character.
* @param length The number of characters.
* @throws SAXException Thrown in case of an IOException.
*/
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
characters(ch, start, length);
}
private void stopTerminator() throws java.io.IOException {
if (state == STATE_IN_START_ELEMENT) {
if (w != null) {
w.write('>');
}
state = STATE_IN_ELEMENT;
}
}
/** Inserts a string of characters into the document.
* @param ch The characters being inserted. A substring, to be precise.
* @param start Index of the first character
* @param length Number of characters being inserted
* @throws SAXException Thrown in case of an IOException
*/
public void characters(char[] ch, int start, int length) throws SAXException {
try {
stopTerminator();
if (w == null) return;
int end = start+length;
for (int i = start; i < end; i++) {
char c = ch[i];
switch (c) {
case '&': w.write("&"); break;
case '<': w.write("<"); break;
case '>': w.write(">"); break;
case '\n':
case '\r':
case '\t':
w.write(c); break;
default:
if (canEncode(c)) {
w.write(c);
} else {
w.write("");
w.write(Integer.toString(c));
w.write(";");
}
break;
}
}
} catch (IOException e) {
throw new SAXException(e);
}
}
public boolean canEncode(char c) {
return c > 31 && c < 127;
}
/** Terminates an element.
*
* @param namespaceURI The namespace URI, if any, or null
* @param localName The local name, without prefix, or null
* @param qName The qualified name, including a prefix, or null
* @throws SAXException Thrown in case of an IOException.
*/
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (m != null && m. getIndentation()) {
--curIndent;
}
if (w != null) {
try {
if (state == STATE_IN_START_ELEMENT) {
w.write("/>");
state = STATE_OUTSIDE;
} else {
if (state == STATE_OUTSIDE) {
indentMe();
}
w.write("");
w.write(qName);
w.write('>');
}
state = STATE_OUTSIDE;
} catch (java.io.IOException e) {
throw new SAXException(e);
}
}
}
private void indentMe() throws java.io.IOException {
if (w != null) {
if (m != null && m.getIndentation()) {
String s = m.getIndentationSeparator();
if (s != null) {
w.write(s);
}
s = m.getIndentationString();
for (int i = 0; i < curIndent; i++) {
w.write(s);
}
}
}
}
private void writeCData(String v) throws java.io.IOException {
int len = v.length();
for (int j = 0; j < len; j++) {
char c = v.charAt(j);
switch (c) {
case '&': w.write("&"); break;
case '<': w.write("<"); break;
case '>': w.write(">"); break;
case '\'': w.write("'"); break;
case '"': w.write("""); break;
default:
if (canEncode(c)) {
w.write(c);
} else {
w.write("");
w.write(Integer.toString(c));
w.write(';');
}
break;
}
}
}
/** Starts a new element.
*
* @param namespaceURI The namespace URI, if any, or null
* @param localName The local name, without prefix, or null
* @param qName The qualified name, including a prefix, or null
* @param attr The element attributes
* @throws SAXException Thrown in case of an IOException.
*/
public void startElement(String namespaceURI, String localName, String qName,
Attributes attr) throws SAXException {
try {
stopTerminator();
if (m != null && m.getIndentation()) {
if (curIndent > 0) {
indentMe();
}
curIndent++;
}
if (w != null) {
w.write('<');
w.write(qName);
if (attr != null) {
for (int i = attr.getLength(); i > 0;) {
w.write(' ');
String name = attr.getQName(--i);
w.write(name);
if (delayedPrefixes != null) {
delayedPrefixes.remove(name);
}
w.write("=\"");
writeCData(attr.getValue(i));
w.write('"');
}
}
if (delayedPrefixes != null && delayedPrefixes.size() > 0) {
for (java.util.Iterator iter = delayedPrefixes.entrySet().iterator();
iter.hasNext(); ) {
java.util.Map.Entry entry = (java.util.Map.Entry) iter.next();
w.write(' ');
w.write((String) entry.getKey());
w.write("=\"");
w.write((String) entry.getValue());
w.write('"');
}
delayedPrefixes.clear();
}
}
state = STATE_IN_START_ELEMENT;
} catch (java.io.IOException e) {
throw new SAXException(e);
}
}
/** Not actually implemented, because I don't know how to skip entities.
*
* @param ent The entity being skipped.
* @throws SAXException Not actually thrown, just for compliance to the interface specification.
*/
public void skippedEntity(String ent) throws SAXException {
throw new SAXException("Don't know how to skip entities");
}
/** Inserts a processing instruction.
*
* @param target The PI target
* @param data The PI data
* @throws SAXException Thrown in case of an IOException
*/
public void processingInstruction(String target, String data)
throws SAXException {
try {
stopTerminator();
if (w != null) {
w.write("");
w.write(target);
w.write(' ');
w.write(data);
w.write("?>");
}
} catch (java.io.IOException e) {
throw new SAXException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy