blob: afd141b445995ea3c06ace35101c329ad18c2e1b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You
* 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. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.abdera.parser.stax;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.activation.MimeType;
import javax.xml.stream.XMLStreamException;
import org.apache.abdera.factory.Factory;
import org.apache.abdera.i18n.iri.IRI;
import org.apache.abdera.i18n.rfc4646.Lang;
import org.apache.abdera.model.Base;
import org.apache.abdera.model.Document;
import org.apache.abdera.model.Element;
import org.apache.abdera.model.ElementWrapper;
import org.apache.abdera.util.EntityTag;
import org.apache.abdera.util.XmlUtil;
import org.apache.abdera.util.XmlUtil.XMLVersion;
import org.apache.abdera.writer.Writer;
import org.apache.abdera.writer.WriterOptions;
import org.apache.axiom.om.OMComment;
import org.apache.axiom.om.OMDocType;
import org.apache.axiom.om.OMDocument;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMOutputFormat;
import org.apache.axiom.om.OMProcessingInstruction;
import org.apache.axiom.om.OMXMLParserWrapper;
import org.apache.axiom.om.impl.llom.OMDocumentImpl;
@SuppressWarnings("unchecked")
public class FOMDocument<T extends Element> extends OMDocumentImpl implements Document<T> {
private static final long serialVersionUID = -3255339511063344662L;
protected IRI base = null;
protected MimeType contentType = null;
protected Date lastModified = null;
protected EntityTag etag = null;
protected String language = null;
protected String slug = null;
protected boolean preserve = true;
public FOMDocument() {
super(new FOMFactory());
}
protected FOMDocument(OMFactory factory) {
super(factory);
}
protected FOMDocument(OMXMLParserWrapper parserWrapper, OMFactory factory) {
super(parserWrapper, factory);
}
protected FOMDocument(OMXMLParserWrapper parserWrapper) {
super(parserWrapper, new FOMFactory());
}
public T getRoot() {
FOMFactory factory = (FOMFactory)getFactory();
return (T)factory.getElementWrapper((T)this.getOMDocumentElement());
}
public Document<T> setRoot(T root) {
if (root instanceof OMElement) {
this.setOMDocumentElement((OMElement)root);
} else if (root instanceof ElementWrapper) {
this.setOMDocumentElement((OMElement)((ElementWrapper)root).getInternal());
}
return this;
}
public IRI getBaseUri() {
return base;
}
public Document<T> setBaseUri(String base) {
this.base = new IRI(base);
return this;
}
public void writeTo(OutputStream out, WriterOptions options) throws IOException {
Writer writer = this.getFactory().getAbdera().getWriter();
writer.writeTo(this, out, options);
}
public void writeTo(java.io.Writer out, WriterOptions options) throws IOException {
Writer writer = this.getFactory().getAbdera().getWriter();
writer.writeTo(this, out, options);
}
public void writeTo(Writer writer, OutputStream out) throws IOException {
writer.writeTo(this, out);
}
public void writeTo(Writer writer, java.io.Writer out) throws IOException {
writer.writeTo(this, out);
}
public void writeTo(Writer writer, OutputStream out, WriterOptions options) throws IOException {
writer.writeTo(this, out, options);
}
public void writeTo(Writer writer, java.io.Writer out, WriterOptions options) throws IOException {
writer.writeTo(this, out, options);
}
public void writeTo(OutputStream out) throws IOException {
String charset = getCharset();
if (charset == null)
charset = "UTF-8";
Writer writer = getFactory().getAbdera().getWriter();
writeTo(writer, new OutputStreamWriter(out, charset));
}
public void writeTo(java.io.Writer writer) throws IOException {
Writer out = getFactory().getAbdera().getWriter();
if (!(out instanceof FOMWriter)) {
out.writeTo(this, writer);
} else {
try {
OMOutputFormat outputFormat = new OMOutputFormat();
if (this.getCharsetEncoding() != null)
outputFormat.setCharSetEncoding(this.getCharsetEncoding());
this.serialize(writer, outputFormat);
} catch (XMLStreamException e) {
throw new FOMException(e);
}
}
}
public MimeType getContentType() {
return contentType;
}
public Document<T> setContentType(String contentType) {
try {
this.contentType = new MimeType(contentType);
if (this.contentType.getParameter("charset") != null)
setCharset(this.contentType.getParameter("charset"));
} catch (javax.activation.MimeTypeParseException e) {
throw new org.apache.abdera.util.MimeTypeParseException(e);
}
return this;
}
public Date getLastModified() {
return this.lastModified;
}
public Document<T> setLastModified(Date lastModified) {
this.lastModified = lastModified;
return this;
}
public Object clone() {
Document<T> doc = ((FOMFactory)getOMFactory()).newDocument();
OMDocument omdoc = (OMDocument)doc;
for (Iterator i = getChildren(); i.hasNext();) {
OMNode node = (OMNode)i.next();
switch (node.getType()) {
case OMNode.COMMENT_NODE:
OMComment comment = (OMComment)node;
getOMFactory().createOMComment(omdoc, comment.getValue());
break;
// TODO: Decide what to do with this code; it will no longer work in Axiom 1.2.14 (because of AXIOM-437).
// On the other hand, since we filter out DTDs, this code is never triggered.
// case OMNode.DTD_NODE:
// OMDocType doctype = (OMDocType)node;
// factory.createOMDocType(omdoc, doctype.getValue());
// break;
case OMNode.ELEMENT_NODE:
Element el = (Element)node;
omdoc.addChild((OMNode)el.clone());
break;
case OMNode.PI_NODE:
OMProcessingInstruction pi = (OMProcessingInstruction)node;
getOMFactory().createOMProcessingInstruction(omdoc, pi.getTarget(), pi.getValue());
break;
}
}
return doc;
}
public String getCharset() {
String enc = this.getXMLEncoding();
return enc == null ? "utf-8" : enc;
}
public Document<T> setCharset(String charset) {
this.setXMLEncoding(charset);
this.setCharsetEncoding(charset);
return this;
}
public Factory getFactory() {
return (Factory)this.getOMFactory();
}
public String[] getProcessingInstruction(String target) {
List<String> values = new ArrayList<String>();
for (Iterator i = getChildren(); i.hasNext();) {
OMNode node = (OMNode)i.next();
if (node.getType() == OMNode.PI_NODE) {
OMProcessingInstruction pi = (OMProcessingInstruction)node;
if (pi.getTarget().equalsIgnoreCase(target))
values.add(pi.getValue());
}
}
return values.toArray(new String[values.size()]);
}
public Document<T> addProcessingInstruction(String target, String value) {
OMProcessingInstruction pi = this.getOMFactory().createOMProcessingInstruction(null, target, value);
if (this.getOMDocumentElement() != null) {
this.getOMDocumentElement().insertSiblingBefore(pi);
} else {
this.addChild(pi);
}
return this;
}
public Document<T> addStylesheet(String href, String media) {
if (media == null) {
addProcessingInstruction("xml-stylesheet", "href=\"" + href + "\"");
} else {
addProcessingInstruction("xml-stylesheet", "href=\"" + href + "\" media=\"" + media + "\"");
}
return this;
}
public <X extends Base> X addComment(String value) {
OMComment comment = this.getOMFactory().createOMComment(null, value);
if (this.getOMDocumentElement() != null) {
this.getOMDocumentElement().insertSiblingBefore(comment);
} else {
this.addChild(comment);
}
return (X)this;
}
public EntityTag getEntityTag() {
return etag;
}
public Document<T> setEntityTag(EntityTag tag) {
this.etag = tag;
return this;
}
public Document<T> setEntityTag(String tag) {
this.etag = new EntityTag(tag);
return this;
}
public String getLanguage() {
return language;
}
public Lang getLanguageTag() {
String lang = getLanguage();
return (lang != null) ? new Lang(lang) : null;
}
public Document<T> setLanguage(String lang) {
this.language = lang;
return this;
}
public String getSlug() {
return slug;
}
public Document<T> setSlug(String slug) {
this.slug = slug;
return this;
}
public boolean getMustPreserveWhitespace() {
return preserve;
}
public Document<T> setMustPreserveWhitespace(boolean preserve) {
this.preserve = preserve;
return this;
}
public XMLVersion getXmlVersion() {
return XmlUtil.getVersion(super.getXMLVersion());
}
public WriterOptions getDefaultWriterOptions() {
return new FOMWriter().getDefaultWriterOptions();
}
/**
* Ensure that the underlying streams are fully parsed. We might eventually need to find a more efficient way of
* doing this, but for now, calling toString() will ensure that this particular object is fully parsed and ready to
* be modified.
*/
public <X extends Base> X complete() {
if (!isComplete() && getRoot() != null)
getRoot().complete();
return (X)this;
}
public void writeTo(String writer, OutputStream out) throws IOException {
writeTo(getFactory().getAbdera().getWriterFactory().getWriter(writer), out);
}
public void writeTo(String writer, java.io.Writer out) throws IOException {
writeTo(getFactory().getAbdera().getWriterFactory().getWriter(writer), out);
}
public void writeTo(String writer, OutputStream out, WriterOptions options) throws IOException {
writeTo(getFactory().getAbdera().getWriterFactory().getWriter(writer), out, options);
}
public void writeTo(String writer, java.io.Writer out, WriterOptions options) throws IOException {
writeTo(getFactory().getAbdera().getWriterFactory().getWriter(writer), out, options);
}
public String toFormattedString() {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
writeTo("prettyxml", out);
return new String(out.toByteArray(), "UTF-8");
} catch (Exception e) {
return toString();
}
}
}