org.apache.camel.converter.jaxp.XMLStreamReaderReader Maven / Gradle / Ivy
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.camel.converter.jaxp;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.Reader;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
/**
*
*/
class XMLStreamReaderReader extends Reader {
private static final int BUFFER_SIZE = 4096;
private XMLStreamReader reader;
private XMLStreamWriter writer;
private TrimmableCharArrayWriter chunk;
private char[] buffer;
private int bpos;
XMLStreamReaderReader(XMLStreamReader reader, XMLOutputFactory outfactory) {
this.reader = reader;
this.buffer = new char[BUFFER_SIZE];
this.chunk = new TrimmableCharArrayWriter();
try {
this.writer = outfactory.createXMLStreamWriter(chunk);
} catch (XMLStreamException e) {
//ignore
}
}
@Override
public void close() throws IOException {
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
int tlen = 0;
while (len > 0) {
int n = ensureBuffering(len);
if (n < 0) {
break;
}
int clen = len > n ? n : len;
System.arraycopy(buffer, 0, cbuf, off, clen);
System.arraycopy(buffer, clen, buffer, 0, buffer.length - clen);
bpos -= clen;
len -= clen;
off += clen;
tlen += clen;
}
return tlen > 0 ? tlen : -1;
}
private int ensureBuffering(int size) throws IOException {
if (size < bpos) {
return bpos;
}
// refill the buffer as more buffering is requested than the current buffer status
try {
// very first event
if (XMLStreamConstants.START_DOCUMENT == reader.getEventType()) {
writer.writeStartDocument("utf-8", "1.0");
}
if (chunk.size() < buffer.length) {
while (reader.hasNext()) {
int code = reader.next();
switch (code) {
case XMLStreamConstants.END_DOCUMENT:
writer.writeEndDocument();
break;
case XMLStreamConstants.START_ELEMENT:
QName qname = reader.getName();
writer.writeStartElement(qname.getPrefix(), qname.getLocalPart(), qname.getNamespaceURI());
for (int i = 0; i < reader.getAttributeCount(); i++) {
writer.writeAttribute(
reader.getAttributePrefix(i), reader.getAttributeNamespace(i), reader.getAttributeLocalName(i),
reader.getAttributeValue(i));
}
for (int i = 0; i < reader.getNamespaceCount(); i++) {
writer.writeNamespace(reader.getNamespacePrefix(i), reader.getNamespaceURI(i));
}
break;
case XMLStreamConstants.END_ELEMENT:
writer.writeEndElement();
break;
case XMLStreamConstants.CHARACTERS:
writer.writeCharacters(reader.getText());
break;
case XMLStreamConstants.COMMENT:
writer.writeComment(reader.getText());
break;
case XMLStreamConstants.CDATA:
writer.writeCData(reader.getText());
break;
default:
break;
}
// check if the chunk is full
final int csize = buffer.length - bpos;
if (chunk.size() > csize) {
System.arraycopy(chunk.getCharArray(), 0, buffer, bpos, csize);
bpos = buffer.length;
chunk.trim(csize, 0);
return buffer.length;
}
}
}
final int csize = chunk.size() < buffer.length - bpos ? chunk.size() : buffer.length - bpos;
if (csize > 0) {
System.arraycopy(chunk.getCharArray(), 0, buffer, bpos, csize);
bpos += csize;
chunk.trim(csize, 0);
return bpos;
} else {
return bpos > 0 ? bpos : -1;
}
} catch (XMLStreamException e) {
throw new IOException(e);
}
}
static class TrimmableCharArrayWriter extends CharArrayWriter {
public void trim(int head, int tail) {
System.arraycopy(buf, head, buf, 0, count - head - tail);
count -= head + tail;
}
public char[] toCharArray(int len) {
char[] c = new char[len];
System.arraycopy(buf, 0, c, 0, len);
return c;
}
char[] getCharArray() {
return buf;
}
}
}