/* * citygml4j - The Open Source Java API for CityGML * https://github.com/citygml4j * * Copyright 2013-2017 Claus Nagel <claus.nagel@gmail.com> * * 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.citygml4j.util.xml; import javax.xml.namespace.QName; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.XMLFilterImpl; public class SAXFragmentWriter extends XMLFilterImpl { private final ContentHandler writer; private final QName breakElement; private WriteMode mode; private boolean shouldWrite; private boolean hasStartElement; public enum WriteMode { HEAD, TAIL } public SAXFragmentWriter(QName breakElement, ContentHandler writer, WriteMode mode) { this.breakElement = breakElement; this.writer = writer; this.mode = mode; shouldWrite = mode == WriteMode.HEAD; } public SAXFragmentWriter(QName breakElement, ContentHandler writer) { this(breakElement, writer, WriteMode.HEAD); } public WriteMode getWriteMode() { return mode; } public void setWriteMode(WriteMode mode) { this.mode = mode; shouldWrite = mode == WriteMode.HEAD; } @Override public void characters(char[] ch, int start, int length) throws SAXException { if (shouldWrite) writer.characters(ch, start, length); } @Override public void endDocument() throws SAXException { if (shouldWrite && mode == WriteMode.TAIL) writer.endDocument(); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (localName.equals(breakElement.getLocalPart()) && uri.equals(breakElement.getNamespaceURI())) shouldWrite = !shouldWrite; if (shouldWrite) { if (!hasStartElement && writer instanceof SAXEventBuffer) { ((SAXEventBuffer)writer).addEndElement(uri, localName); return; } writer.endElement(uri, localName, qName); } } @Override public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { if (shouldWrite) writer.ignorableWhitespace(ch, start, length); } @Override public void startDocument() throws SAXException { if (shouldWrite && mode == WriteMode.HEAD) writer.startDocument(); } @Override public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { if (shouldWrite) { writer.startElement(uri, localName, qName, atts); hasStartElement = true; } } @Override public void endPrefixMapping(String prefix) throws SAXException { writer.endPrefixMapping(prefix); } @Override public void startPrefixMapping(String prefix, String uri) throws SAXException { writer.startPrefixMapping(prefix, uri); } }