I've implemented two utility classes (attached) that implement the
javax.xml.transform.Source and javax.xml.transform.Result interfaces.
These allows us to apply XSLT transforms to Abdera objects. For instance:
// yes... abdera can parse XSLT too :-)
InputStream xslt = Test.class.getResourceAsStream("/test.xslt");
Document<Element> xsltdoc = Parser.INSTANCE.parse(xslt);
BaseSource source = new BaseSource(xsltdoc);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(source);
// let's first transform a parsed feed
InputStream feed = Test.class.getResourceAsStream("/test.xml");
Document<Feed> doc = Parser.INSTANCE.parse(feed);
BaseSource feedSource = new BaseSource(doc);
BaseResult result = new BaseResult();
transformer.transform(feedSource, result);
// did it work?
Document<Element> doc2 = result.getDocument();
doc2.writeTo(System.out);
// it even works with dynamically created feeds
Feed dynamicFeed = Factory.INSTANCE.newFeed();
dynamicFeed.setId("urn:foo");
feedSource = new BaseSource(feed);
result = new BaseResult();
transformer.transform(feedSource, result);
doc2 = result.getDocument();
doc2.writeTo(System.out);
I would like to add these to org.apache.abdera.util.*
(I'll likely rename them to AbderaSource and AbderaResult)
- James
package org.apache.abdera.util;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Writer;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import org.apache.abdera.model.Document;
import org.apache.abdera.model.Element;
import org.apache.abdera.parser.Parser;
/**
* Provides a simple (and likely somewhat inefficient) implementation of
* javax.xml.transform.Result that allows Abdera objects to be used with
* the javax.xml.transform API's
*
* Only use this once per transform!!!
*/
public class BaseResult
extends StreamResult
implements Result {
private PipedOutputStream pipeout = null;
private PipedInputStream pipein = null;
private Document doc = null;
@SuppressWarnings("unchecked")
public <T extends Element>Document<T> getDocument() {
if (doc == null) {
if (pipein == null) return null;
doc = Parser.INSTANCE.parse(pipein);
}
return doc;
}
@Override
public OutputStream getOutputStream() {
if (pipein == null && pipeout == null) {
try {
pipeout = new PipedOutputStream();
pipein = new PipedInputStream(pipeout);
} catch (IOException e) {}
}
return pipeout;
}
@Override
public Writer getWriter() {
return null;
}
@Override
public void setOutputStream(OutputStream out) {
throw new UnsupportedOperationException();
}
@Override
public void setWriter(Writer out) {
throw new UnsupportedOperationException();
}
}
package org.apache.abdera.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Reader;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import org.apache.abdera.model.Base;
/**
* Provides a simple (and likely somewhat inefficient) implementation of
* javax.xml.transform.Source that allows Abdera objects to be used with
* the javax.xml.transform API's
*/
public class BaseSource
extends StreamSource
implements Source {
private Base base = null;
public BaseSource(Base base) {
this.base = base;
}
@Override
public InputStream getInputStream() {
try {
PipedOutputStream pipeout = new PipedOutputStream();
PipedInputStream pipein = new PipedInputStream(pipeout);
base.writeTo(pipeout);
pipeout.flush();
pipeout.close();
return pipein;
} catch (IOException e) {}
return null;
}
@Override
public Reader getReader() {
return null;
}
@Override
public void setInputStream(InputStream in) {
throw new UnsupportedOperationException();
}
@Override
public void setReader(Reader reader) {
throw new UnsupportedOperationException();
}
}