All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.coode.xml.XMLWriterImpl Maven / Gradle / Ivy

/*
 * This file is part of the OWL API.
 *
 * The contents of this file are subject to the LGPL License, Version 3.0.
 *
 * Copyright (C) 2011, The University of Manchester
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses/.
 *
 *
 * Alternatively, the contents of this file may be used under the terms of the Apache License, Version 2.0
 * in which case, the provisions of the Apache License Version 2.0 are applicable instead of those above.
 *
 * Copyright 2011, University of Manchester
 *
 * 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.coode.xml;

import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.StringTokenizer;

import org.semanticweb.owlapi.io.XMLUtils;
import org.semanticweb.owlapi.vocab.OWL2Datatype;

/**
 * Author: Matthew Horridge
* The University Of Manchester
* Medical Informatics Group
* Date: 30-May-2006

*

* [email protected]
* www.cs.man.ac.uk/~horridgm

*

* Developed as part of the CO-ODE project * http://www.co-ode.org */ @SuppressWarnings("javadoc") public class XMLWriterImpl implements XMLWriter { private Stack elementStack; protected Writer writer; private String encoding = ""; private String xmlBase; private URI xmlBaseURI; private XMLWriterNamespaceManager xmlWriterNamespaceManager; private Map entities; private static final int TEXT_CONTENT_WRAP_LIMIT = Integer.MAX_VALUE; private boolean preambleWritten; private static final String PERCENT_ENTITY = "%"; public XMLWriterImpl(Writer writer, XMLWriterNamespaceManager xmlWriterNamespaceManager, String xmlBase) { this.writer = writer; this.xmlWriterNamespaceManager = xmlWriterNamespaceManager; this.xmlBase = xmlBase; xmlBaseURI = URI.create(xmlBase); // no need to set it to UTF-8: it's supposed to be the default encoding for XML. //Must be set correctly for the Writer anyway, or bugs will ensue. //this.encoding = "UTF-8"; elementStack = new Stack(); setupEntities(); } private void setupEntities() { List namespaces = new ArrayList(xmlWriterNamespaceManager.getNamespaces()); Collections.sort(namespaces, new StringLengthOnlyComparator()); entities = new LinkedHashMap(); for (String curNamespace : namespaces) { String curPrefix = ""; if (xmlWriterNamespaceManager.getDefaultNamespace().equals(curNamespace)) { curPrefix = xmlWriterNamespaceManager.getDefaultPrefix(); } else { curPrefix = xmlWriterNamespaceManager.getPrefixForNamespace(curNamespace); } if (curPrefix.length() > 0) { entities.put(curNamespace, "&" + curPrefix + ";"); } } } protected String swapForEntity(String value) { for (String curEntity : entities.keySet()) { String entityVal = entities.get(curEntity); if (value.length() > curEntity.length()) { String repVal = value.replace(curEntity, entityVal); if (repVal.length() < value.length()) { return repVal; } } } return value; } public String getDefaultNamespace() { return xmlWriterNamespaceManager.getDefaultNamespace(); } @Override public String getXMLBase() { return xmlBase; } public URI getXMLBaseAsURI() { return xmlBaseURI; } @Override public XMLWriterNamespaceManager getNamespacePrefixes() { return xmlWriterNamespaceManager; } @Override public void setEncoding(String encoding) { this.encoding = encoding; } private boolean isValidQName(String name) { if(name == null) { return false; } int colonIndex = name.indexOf(":"); boolean valid = false; if (colonIndex == -1) { valid = OWL2Datatype.XSD_NCNAME.getPattern().matcher(name).matches(); } else { valid = OWL2Datatype.XSD_NCNAME.getPattern().matcher(name.substring(0, colonIndex - 1)).matches(); if (valid) { valid = OWL2Datatype.XSD_NAME.getPattern().matcher(name.substring(colonIndex + 1)).matches(); } } return valid; } @Override public void setWrapAttributes(boolean b) { if (!elementStack.isEmpty()) { XMLElement element = elementStack.peek(); element.setWrapAttributes(b); } } @Override public void writeStartElement(String name) throws IOException { String qName = xmlWriterNamespaceManager.getQName(name); if ( qName == null || qName.equals(name)) { if (!isValidQName(name)) { // Could not generate a valid QName, therefore, we cannot // write valid XML - just throw an exception! throw new IllegalElementNameException(name); } } XMLElement element = new XMLElement(qName, elementStack.size()); if (!elementStack.isEmpty()) { XMLElement topElement = elementStack.peek(); if (topElement != null) { topElement.writeElementStart(false); } } elementStack.push(element); } @Override public void writeEndElement() throws IOException { // Pop the element off the stack and write it out if (!elementStack.isEmpty()) { XMLElement element = elementStack.pop(); element.writeElementEnd(); } } @Override public void writeAttribute(String attr, String val) { XMLElement element = elementStack.peek(); String qName = xmlWriterNamespaceManager.getQName(attr); if (qName != null) { element.setAttribute(qName, val); } } @Override public void writeTextContent(String text) { XMLElement element = elementStack.peek(); element.setText(text); } @Override public void writeComment(String commentText) throws IOException { XMLElement element = new XMLElement(null, elementStack.size()); element.setText(""); if (!elementStack.isEmpty()) { XMLElement topElement = elementStack.peek(); if (topElement != null) { topElement.writeElementStart(false); } } if (preambleWritten) { element.writeElementStart(true); } else { elementStack.push(element); } } private void writeEntities(String rootName) throws IOException { String qName = xmlWriterNamespaceManager.getQName(rootName); if (qName == null) { throw new IOException("Cannot create valid XML: qname for " + rootName + " is null"); } writer.write("\n\n\n"); } writer.write("]>\n\n\n"); } @Override public void startDocument(String rootElementName) throws IOException { String encodingString = ""; if (encoding.length() > 0) { encodingString = " encoding=\"" + encoding + "\""; } writer.write("\n"); if (XMLWriterPreferences.getInstance().isUseNamespaceEntities()) { writeEntities(rootElementName); } preambleWritten = true; while (!elementStack.isEmpty()) { elementStack.pop().writeElementStart(true); } writeStartElement(rootElementName); setWrapAttributes(true); writeAttribute("xmlns", xmlWriterNamespaceManager.getDefaultNamespace()); if (xmlBase.length() != 0) { writeAttribute("xml:base", xmlBase); } for (String curPrefix : xmlWriterNamespaceManager.getPrefixes()) { if (curPrefix.length() > 0) { writeAttribute("xmlns:" + curPrefix, xmlWriterNamespaceManager.getNamespaceForPrefix(curPrefix)); } } } @Override public void endDocument() throws IOException { // Pop of each element while (!elementStack.isEmpty()) { writeEndElement(); } writer.flush(); } private static final class StringLengthOnlyComparator implements Comparator, Serializable { private static final long serialVersionUID = 30402L; public StringLengthOnlyComparator() {} @Override public int compare(String o1, String o2) { // Shortest string first return o1.length() - o2.length(); } } public class XMLElement { private String name; private Map attributes; String textContent; private boolean startWritten; private int indentation; private boolean wrapAttributes; public XMLElement(String name) { this(name, 0); wrapAttributes = false; } public XMLElement(String name, int indentation) { this.name = name; attributes = new LinkedHashMap(); this.indentation = indentation; textContent = null; startWritten = false; } public void setWrapAttributes(boolean b) { //XXX it was: //wrapAttributes = true; wrapAttributes = b; } public void setAttribute(String attribute, String value) { attributes.put(attribute, value); } public void setText(String content) { textContent = content; } public void writeElementStart(boolean close) throws IOException { if (!startWritten) { startWritten = true; insertIndentation(); if (name != null) { writer.write('<'); writer.write(name); writeAttributes(); if (textContent != null) { boolean wrap = textContent.length() > TEXT_CONTENT_WRAP_LIMIT; if (wrap) { writeNewLine(); indentation++; insertIndentation(); } writer.write('>'); writeTextContent(); if (wrap) { indentation--; } } if (close) { if (textContent != null) { writeElementEnd(); } else { writer.write("/>"); writeNewLine(); } } else { if (textContent == null) { writer.write('>'); writeNewLine(); } } } else { // Name is null so by convension this is a comment if (textContent != null) { writer.write("\n\n\n"); StringTokenizer tokenizer = new StringTokenizer(textContent, "\n", true); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); if (!token.equals("\n")) { insertIndentation(); } writer.write(token); } writer.write("\n\n"); } } } } public void writeElementEnd() throws IOException { if (name != null) { if (!startWritten) { writeElementStart(true); } else { if (textContent == null) { insertIndentation(); } writer.write(""); writeNewLine(); } } } private void writeAttribute(String attr, String val) throws IOException { writer.write(attr); writer.write('='); writer.write('"'); if (XMLWriterPreferences.getInstance().isUseNamespaceEntities()) { writer.write(swapForEntity(XMLUtils.escapeXML(val))); } else { writer.write(XMLUtils.escapeXML(val)); } writer.write('"'); } private void writeAttributes() throws IOException { for (Iterator it = attributes.keySet().iterator(); it.hasNext();) { String attr = it.next(); String val = attributes.get(attr); writer.write(' '); writeAttribute(attr, val); if (it.hasNext() && wrapAttributes) { writer.write("\n"); indentation++; insertIndentation(); indentation--; } } } private void writeTextContent() throws IOException { if (textContent != null) { writer.write(XMLUtils.escapeXML(textContent)); } } private void insertIndentation() throws IOException { if (XMLWriterPreferences.getInstance().isIndenting()) { for (int i = 0; i < indentation * XMLWriterPreferences.getInstance().getIndentSize(); i++) { writer.write(' '); } } } private void writeNewLine() throws IOException { writer.write('\n'); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy