/*
* 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.io.OutputStreamWriter;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.Map;
import org.mulgara.query.Answer;
import org.mulgara.query.TuplesException;
import org.mulgara.util.StringUtil;
/**
* Represents a data object as XML.
*
* @created Jul 8, 2008
* @author Paula Gearon
* @copyright © 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
*/
public class StreamedSparqlXMLObject implements StreamedXMLAnswer {
/** A single indent for use when pretty printing. */
static final private String INDENT_STR = " ";
/** Indicates that pretty printing should be used. */
boolean prettyPrint = true;
/** The encoded data. */
final Object objectData;
/** The writer used for creating the XML. */
protected OutputStreamWriter s = null;
/** The byte output stream used for creating the XML. */
protected OutputStream output = null;
/** The charset encoding to use when writing to the output stream. */
Charset charset = Charset.defaultCharset();
/**
* Creates an XML object encoding.
* @param objectData The data to encode.
* @param output Where to send the output.
*/
public StreamedSparqlXMLObject(Object objectData, OutputStream output) {
this.objectData = objectData;
this.output = output;
}
/** @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;
}
/** {@inheritDoc} */
public void addDocHeader() throws IOException {
s.append("<?xml version=\"1.0\"?>\n");
s.append("<sparql xmlns=\"http://www.w3.org/2005/sparql-results#\">");
if (prettyPrint) s.append("\n");
}
/** {@inheritDoc} */
public void addDocFooter() throws IOException {
s.append("</sparql>");
}
/** {@inheritDoc} */
protected void addResults() throws IOException {
if (prettyPrint) s.append(INDENT_STR);
s.append("<data>");
if (objectData != null) {
if (objectData instanceof Map<?,?>) s.append(encodeMap((Map<?,?>)objectData, INDENT_STR));
else s.append(StringUtil.quoteAV(objectData.toString()));
}
s.append("</data>");
if (prettyPrint) s.append("\n");
}
/**
* Put the parts of the document together, and close the stream.
* @see org.mulgara.protocol.StreamedXMLAnswer#emit()
*/
public void emit() throws IOException {
s = new OutputStreamWriter(output, charset);
addDocHeader();
addResults();
addDocFooter();
s.flush();
}
/**
* @see org.mulgara.protocol.XMLAnswer#addNamespace(java.lang.String, java.net.URI)
* Ignored.
*/
public void addNamespace(String name, URI nsValue) {
}
/**
* @see org.mulgara.protocol.XMLAnswer#addNamespace(java.lang.String, java.net.URI)
* Ignored.
*/
public void clearNamespaces() {
}
public void setPrettyPrint(boolean prettyPrint) {
this.prettyPrint = prettyPrint;
}
public String encodeMap(Map<?,?> map, String indent) {
String i2 = prettyPrint ? "\n" + indent + INDENT_STR : "";
StringBuilder s = new StringBuilder();
for (Map.Entry<?,?> entry: map.entrySet()) {
s.append(i2).append("<key>");
s.append(StringUtil.quoteAV(entry.getKey().toString()));
s.append("</key>");
s.append(i2).append("<value>");
s.append(StringUtil.quoteAV(entry.getValue().toString()));
s.append("</value>");
}
if (prettyPrint) s.append("\n").append(indent);
return s.toString();
}
public void addAnswer(Answer data) throws TuplesException, IOException {
throw new UnsupportedOperationException();
}
public void close() throws IOException {
output.close();
}
/**
* Not to be called for when doing an "emit". Only used when more manual control is needed
* due to streaming multiple answers.
*/
public void initOutput() {
if (s == null) s = new OutputStreamWriter(output, charset);
}
}