/* * Copyright 2008 Fedora Commons, Inc. * * 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.mulgara.protocol; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.nio.charset.Charset; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jrdf.graph.BlankNode; import org.jrdf.graph.Literal; import org.jrdf.graph.URIReference; import org.mulgara.query.Answer; import org.mulgara.query.TuplesException; import org.mulgara.query.Variable; /** * Basic functionality for emitting Answers as XML using raw text methods. * * @created Jul 9, 2008 * @author Paula Gearon * @copyright © 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a> */ public abstract class AbstractStreamedXMLAnswer extends AbstractStreamedAnswer implements StreamedXMLAnswer { /** A single indent for use when pretty printing. */ static final private String SINGLE_INDENT_STR = " "; /** The size of indents to use for pretty printing. */ static final private int SINGLE_INDENT_SIZE = SINGLE_INDENT_STR.length(); /** The largest indent string allowed. */ static final private String MAX_INDENT = "\n "; /** * An array of indent strings used by {@link #i(int)}. * This is pre-generated to avoid creating them while emiting xml. */ static final String[] INDENT = new String[MAX_INDENT.length() / SINGLE_INDENT_SIZE]; // Build the indents using the MAX_INDENT as a raw data source static { for (int i = 0; i < INDENT.length; i++) INDENT[i] = MAX_INDENT.substring(0, i * SINGLE_INDENT_SIZE + 1); } /** All the namespaces explicitly requested. */ Map<String,URI> namespaces = new HashMap<String,URI>(); /** Indicates that pretty printing should be used. */ boolean prettyPrint = true; /** * Create an XMLAnswer based on a given {@link Answer}. * @param answer The Answer with the data to convert. */ public AbstractStreamedXMLAnswer(Answer answer, OutputStream output) { super(answer, output); } /** * Create an XMLAnswer based on a given {@link Answer}. * @param answer The Answer with the data to convert. */ public AbstractStreamedXMLAnswer(Answer answer, OutputStream output, String charsetName) { super(answer, output, charsetName); } /** * Create an XMLAnswer based on a given {@link Answer}. * @param answers The list of Answers with the data to convert. */ public AbstractStreamedXMLAnswer(List<Answer> answers, OutputStream output) { super(answers, output); } /** * Create an XMLAnswer based on a given {@link Answer}. * @param answers The list of Answers with the data to convert. */ public AbstractStreamedXMLAnswer(List<Answer> answers, OutputStream output, String charsetName) { super(answers, output, charsetName); } /** * @see org.mulgara.protocol.StreamedXMLAnswer#setCharacterEncoding(java.lang.String) */ public void setCharacterEncoding(String encoding) { charset = Charset.forName(encoding); } /** * @see org.mulgara.protocol.StreamedXMLAnswer#setCharacterEncoding(java.nio.Charset) */ public void setCharacterEncoding(Charset charset) { this.charset = charset; } /** * @see org.mulgara.protocol.StreamedXMLAnswer#addNamespace(java.lang.String, java.net.URI) */ public void addNamespace(String name, URI nsValue) { namespaces.put(name, nsValue); s = null; } /** * @see org.mulgara.protocol.StreamedXMLAnswer#clearNamespaces() */ public void clearNamespaces() { namespaces.clear(); s = null; } /** * @see org.mulgara.protocol.StreamedXMLAnswer#setPrettyPrint(boolean) */ public void setPrettyPrint(boolean prettyPrint) { this.prettyPrint = prettyPrint; s = null; } /** * When {@link #setPrettyPrint(boolean)} is set, returns a string containing a new line and an indentation. * When pretty printing is off, then return an empty string. * @param indent The number of indentations to use. * @return A String containing the appropriate indentation, or an empty string if not pretty printing. */ String i(int indent) { if (!prettyPrint) return ""; if (indent < INDENT.length) return INDENT[indent]; StringBuilder sbi = new StringBuilder(MAX_INDENT); for (int i = INDENT.length; i < indent; i++) sbi.append(SINGLE_INDENT_STR); return sbi.toString(); } /** * Adds the document header to the buffer. */ @Override public abstract void addDocHeader() throws IOException; /** * Adds the document footer to the buffer. */ @Override public abstract void addDocFooter() throws IOException; /** * Adds the header to the document data. * @param a The answer to add a header for. */ @Override protected abstract void addHeader(Answer a) throws IOException; /** * Adds the results to the document data. * @param a The answer to add the results for. * @throws TuplesException Indicates an error accessing the Answer. */ @Override protected abstract void addResults(Answer a) throws TuplesException, IOException; /** * Adds a variable to the header. * @param var The variable to add. */ @Override protected abstract void addHeaderVariable(Variable var) throws IOException; /** * Adds a single result, based on the current result in the {@link #answer}. * @param a The answer to get the result from * @throws TuplesException Indicates an error accessing the Answer. */ @Override protected abstract void addResult(Answer a) throws TuplesException, IOException; /** * Adds a single binding from the current result in the {@link #answer}. * @param var The bound variable. * @param value The value bound to the variable. * @throws TuplesException Indicates an error accessing the Answer. */ @Override protected abstract void addBinding(Variable var, Object value) throws TuplesException, IOException; /** * Adds a single URI to the buffer. * @param uri The URIReference for the URI to add. */ @Override protected abstract void addURI(URIReference uri) throws IOException; /** * Adds a single blank node to the buffer. * @param uri The blank node to add. */ @Override protected abstract void addBNode(BlankNode bnode) throws IOException; /** * Adds a single Literal to the buffer. * @param literal The Literal to add. */ @Override protected abstract void addLiteral(Literal literal) throws IOException; }