package org.apache.slide.projector.value;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom.DocType;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
public class DocumentValue extends AbstractStreamableValue implements XMLValue {
private static Logger logger = Logger.getLogger(DocumentValue.class.getName());
private final static XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
private byte[] bytes = null;
private Document document;
private boolean documentCreated = false;
private InputStream inputStream = null;
public DocumentValue(StreamableValue streamableResource) throws IOException {
this(streamableResource.getInputStream());
}
public DocumentValue(InputStream inputStream) {
this.inputStream = inputStream;
}
public DocumentValue(Document document) {
this.document = document;
documentCreated = true;
}
public InputStream getInputStream() throws IOException {
if ( inputStream != null ) return inputStream;
if ( bytes == null ) {
bytes = getBytes();
}
InputStream inputStream = new ByteArrayInputStream(bytes);
return inputStream;
}
private byte[] getBytes() throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
xmlOutputter.output(getDocument(), outputStream);
return outputStream.toByteArray();
}
public void enableMultipleStreaming() {}
public DocType getDocumentType() {
DocType docType = getDocument().getDocType();
if (docType == null) {
docType = new DocType(getDocument().getRootElement().getName());
getDocument().setDocType(docType);
}
return docType;
}
public Document getDocument() {
if ( !documentCreated ) {
documentCreated = true;
SAXBuilder saxBuilder = new SAXBuilder();
try {
document = saxBuilder.build(inputStream);
} catch (JDOMException e) {
logger.log(Level.SEVERE, "Could not create XML document from given input stream", e);
// FIXME: Exception handling!
document = null;
} catch (IOException e) {
logger.log(Level.SEVERE, "Could not create XML document from given input stream", e);
document = null;
}
}
return document;
}
public Element getRootElement() {
return getDocument().getRootElement();
}
public String getContentType() {
return XMLValue.CONTENT_TYPE;
}
public String getCharacterEncoding() {
return "UTF-8";
}
public int getContentLength() {
if ( bytes == null ) {
try {
bytes = getBytes();
} catch ( IOException e ) {
// could not calculate content length
return -1;
}
}
return bytes.length;
}
public boolean isDocument() {
return true;
}
}