You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Guido Casper <gc...@s-und-n.de> on 2003/12/07 14:24:59 UTC
extending FOM? (was on cocoon-users: Re: Parsing Source into DOM in Flow)
Did anyone else also feel the need to have something like
processPipelineTo but getting a DOM or just an InputStream instead of
just streaming it directly to another OutputStream?
Guido
Geoff Howard wrote:
> Upayavira wrote:
>> Maybe my last question was too specific.
>>
>> I'm trying to parse the contents of a source into a DOM in
>> Flowscript, but am getting all sorts of errors. Can anyone provide a
>> better way than this (which doesn't work)?
>>
>> var resolver =
>>
cocoon.getComponent(Packages.org.apache.excalibur.source.SourceResolver.
ROLE);
>>
>> var source = resolver.resolveURI("blah.xml");
>> var builder =
>>
Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocum
entBuilder();
>
> I think I have observed that you cannot use the returned result of a
> java method call ( newInstance() ) as a java object in flow (
> .newDocumentBuilder() ).
>
> The workaround I have found is to separate the calls:
>
> var builderFactory =
> Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance();
>
> var builder = builderFactory.newDocumentBuilder();
>
> I don't know if this is a bug or not, don't know if it's only when
> calling with Packages or not. I also have not carefully confirmed
> this.
>
> Finally, don't we have a convenience component to do this?
>
> Geoff
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
> For additional commands, e-mail: users-help@cocoon.apache.org
Re: extending FOM? (was on cocoon-users: Re: Parsing Source into DOM in Flow)
Posted by Guido Casper <gc...@s-und-n.de>.
Sylvain Wallez wrote:
> Guido Casper wrote:
>
>> Did anyone else also feel the need to have something like
>> processPipelineTo but getting a DOM or just an InputStream instead
>> of just streaming it directly to another OutputStream?
>>
>>
>
> Rather than extending the FOM, what we need is a helper JS library
> that
> is a simple wrapper around the SourceResolver and the
> SourceUtil.toDOM() method. I have this on my projects in a
> "flow-utils.js" file.
Yes but passing parameters to the pipeline that way is a hassle and
misses the elegance of JXTemplate.
Guido
>
> I'll add it in the CVS (needs a little polishing). In the meantime,
> here are the DOM-related functions:
>
> ========================================================
>
> // Create a new document, given the name of its root element
> function newDocument(root) {
> var result =
>
Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocum
entBuilder().newDocument();
> result.appendChild(result.createElement("News"));
> return result;
> }
>
> // Load a document from an URI, absolute or relative to the current
> sitemap function loadDocument(uri) {
> var resolver =
> cocoon.getComponent("org.apache.excalibur.source.SourceResolver");
> var source = resolver.resolveURI(uri);
> try {
> var document =
> Packages.org.apache.cocoon.components.source.SourceUtil.toDOM(source);
> } finally {
> resolver.release(source);
> cocoon.releaseComponent(resolver);
> }
> return document;
> }
>
> // Save a document to an URI (which should be writeable)
> function saveDocument(document, uri) {
> var resolver =
>
cocoon.getComponent(Packages.org.apache.cocoon.environment.SourceResolve
r.ROLE);
> var source = resolver.resolveURI(uri);
> var output = null;
>
> try {
> output = source.getOutputStream();
>
> var transformer =
>
Packages.javax.xml.transform.TransformerFactory.newInstance().newTransfo
rmer();
>
>
>
transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.IN
DENT,
> "true");
>
>
transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.ME
THOD,
> "xml");
>
>
transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.EN
CODING,
> "ISO-8859-1");
> transformer.transform(
> new Packages.javax.xml.transform.dom.DOMSource(document),
> new
> Packages.javax.xml.transform.stream.StreamResult(output) );
>
> } finally {
> if (output != null) output.close();
> resolver.release(source);
> cocoon.releaseComponent(resolver);
> }
> }
>
> ========================================================
>
> Note that processPipelineTo is nothing more than copying the result
> of a "cocoon:/" uri to an outputstream after having called
> FlowHelper.setContextObject(objectModel, viewdata);
>
> Sylvain
Re: extending FOM? (was on cocoon-users: Re: Parsing Source into
DOM in Flow)
Posted by Sylvain Wallez <sy...@apache.org>.
Guido Casper wrote:
>Did anyone else also feel the need to have something like processPipelineTo but getting a DOM or just an InputStream instead of just streaming it directly to another OutputStream?
>
>
Rather than extending the FOM, what we need is a helper JS library that
is a simple wrapper around the SourceResolver and the SourceUtil.toDOM()
method. I have this on my projects in a "flow-utils.js" file.
I'll add it in the CVS (needs a little polishing). In the meantime, here
are the DOM-related functions:
========================================================
// Create a new document, given the name of its root element
function newDocument(root) {
var result =
Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
result.appendChild(result.createElement("News"));
return result;
}
// Load a document from an URI, absolute or relative to the current sitemap
function loadDocument(uri) {
var resolver =
cocoon.getComponent("org.apache.excalibur.source.SourceResolver");
var source = resolver.resolveURI(uri);
try {
var document =
Packages.org.apache.cocoon.components.source.SourceUtil.toDOM(source);
} finally {
resolver.release(source);
cocoon.releaseComponent(resolver);
}
return document;
}
// Save a document to an URI (which should be writeable)
function saveDocument(document, uri) {
var resolver =
cocoon.getComponent(Packages.org.apache.cocoon.environment.SourceResolver.ROLE);
var source = resolver.resolveURI(uri);
var output = null;
try {
output = source.getOutputStream();
var transformer =
Packages.javax.xml.transform.TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.INDENT,
"true");
transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.METHOD,
"xml");
transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.ENCODING,
"ISO-8859-1");
transformer.transform(
new Packages.javax.xml.transform.dom.DOMSource(document),
new Packages.javax.xml.transform.stream.StreamResult(output)
);
} finally {
if (output != null) output.close();
resolver.release(source);
cocoon.releaseComponent(resolver);
}
}
========================================================
Note that processPipelineTo is nothing more than copying the result of a
"cocoon:/" uri to an outputstream after having called
FlowHelper.setContextObject(objectModel, viewdata);
Sylvain
--
Sylvain Wallez Anyware Technologies
http://www.apache.org/~sylvain http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }
Orixo, the opensource XML business alliance - http://www.orixo.com
Re: extending FOM? (was on cocoon-users: Re: Parsing Source
intoDOM in Flow)
Posted by da...@nada.kth.se.
Guido Casper wrote:
> Did anyone else also feel the need to have something like
> processPipelineTo but getting a DOM
Yes, I use that quite often, so it would be good if FOM could provide
some easier to use functionality for this.
We could have a processPipelineToDOM(uri, map) that returns a DOM. I
would also like a processPipelineToSource(uri, map, modifiableSourceURI)
which would simlify writing pipeline content to e.g. files and
repositorys. It could also be used together with the xmodule source
(http://nagoya.apache.org/bugzilla/show_bug.cgi?id=25210) to put DOM with
the pipeline content in whatether object that can be accessable from an
output module.
Implementation details
----------------------
In the processPipelineToDOM we can the avoid the serialize to output
stream reparse to SAX steps by using the same mechanism as in the
o.a.c.components.source.impl.SitemapSource. I.e. instead of using the
process(String uri, Object bizData, OutputStream out, Environment env)
from o.a.c.components.flow.AbstractInterpreter, we could write a
process(String uri, Object bizData, ContentHandler out, Environment env),
that process the pipeline directly to a ContentHandler, that in turn
could write the DOM, se the toSAX method in the SitemapSource for
details.
Something similar could be used for the processPipelineToSource, but here
we would need some convention for knowing when a ModifiableSource can
accept SAX input, before migrating to the Excalibur sources there was an
interface o.a.c.environment.WritableSource that had a method that
returned a ContentHandler for that purpose. One could of course let the
ModifiableSource implement XMLConsumer, but that is a litle bit
unconvinient as there are so many methods in that interface, I would
prefer to ihave an interface that just returns a ContentHandler e.g.
public interface SAXWritable {
ContentHandler getContentHandler();
}
WDYT?
> or just an InputStream instead of
> just streaming it directly to another OutputStream?
Have not found any use of that yet.
>
> Guido
>
>
> Geoff Howard wrote:
>
>>Upayavira wrote:
>>>Maybe my last question was too specific.
>>>I'm trying to parse the contents of a source into a DOM in
>>>Flowscript, but am getting all sorts of errors. Can anyone provide a
better way than this (which doesn't work)?
I have not access to my code ATM but take a look at the loadDocument and
saveDocument function in
http://cvs.apache.org/viewcvs.cgi/cocoon-2.1/src/blocks/woody/samples/flow/binding_example.js
That code can in turn be simplified to a few lines by using the toDOM and
getSource methods is o.a.c.components.source.SourceUtil
/Daniel
Re: extending FOM?
Posted by Daniel Fagerstrom <da...@nada.kth.se>.
Guido Casper wrote:
> Christopher Oliver wrote:
>>Why not have processPipelineTo take a javax.xml.transform.Result
>>instead of an OutputStream?
>
> Yes, that might be a good solution (although back incompatible IIUC).
> Buffering in a byte array might also work. I'm just (overly?) worried
> about the performance penalty of serialization/parsing which does not
> take place with Sylvain's approach. I think I'm seeking for the best of
> both, which might only be possible with an extra FOM method?.
>
> Guido
While javax.xml.transform.Result is convenient for connecting to
parsers, XSLT-transformers and serializing to SAX and DOM, it is not
used as an external API in Cocoon. In Cocoon XMLConsumer and XMLProducer
are the main API:s for transporting XML data. Furthermore it would be
unpractical to use Result within Cocoon as DOMResult, SAXResult and
StreamResult are classes instead of being interfaces.
I think that we need a
processPipelineToSAX(String uri, Object bizData, XMLConsumer out)
that would solve the serialization/parsing performance penalty that
worry me as well. It would not introduce any new concepts in Cocoon
either, when you use the cocoon protocol in e.g. an aggregator, you get
SAX output from a pipeline.
As I said in an earlier post I would like to have the convenience
functions: processPipelineToDOM and processPipelineToSource as well.
Concerning the question where to put these things, they should IMO be
part of the FOM. XML in form of SAX and DOM, and sources are core
concepts in Cocoon and should therefore be supported in the FOM.
/Daniel
Re: extending FOM?
Posted by Guido Casper <gc...@s-und-n.de>.
Christopher Oliver wrote:
> Why not have processPipelineTo take a javax.xml.transform.Result
> instead of an OutputStream?
Yes, that might be a good solution (although back incompatible IIUC).
Buffering in a byte array might also work. I'm just (overly?) worried
about the performance penalty of serialization/parsing which does not
take place with Sylvain's approach. I think I'm seeking for the best of
both, which might only be possible with an extra FOM method?.
Guido
>
> Guido Casper wrote:
>
>> Did anyone else also feel the need to have something like
>> processPipelineTo but getting a DOM or just an InputStream instead of
>> just streaming it directly to another OutputStream?
>>
>> Guido
>>
>>
>> Geoff Howard wrote:
>>
>>
>>> Upayavira wrote:
>>>
>>>
>>>> Maybe my last question was too specific.
>>>>
>>>> I'm trying to parse the contents of a source into a DOM in
>>>> Flowscript, but am getting all sorts of errors. Can anyone provide
>>>> a better way than this (which doesn't work)?
>>>>
>>>> var resolver =
>>>>
>>>>
>>>>
>>
cocoon.getComponent(Packages.org.apache.excalibur.source.SourceResolver.
>> ROLE);
>>
>>
>>>> var source = resolver.resolveURI("blah.xml");
>>>> var builder =
>>>>
>>>>
>>>>
>>
Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocum
>> entBuilder();
>>
>>
>>> I think I have observed that you cannot use the returned result of a
>>> java method call ( newInstance() ) as a java object in flow (
>>> .newDocumentBuilder() ).
>>>
>>> The workaround I have found is to separate the calls:
>>>
>>> var builderFactory =
>>> Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance();
>>>
>>> var builder = builderFactory.newDocumentBuilder();
>>>
>>> I don't know if this is a bug or not, don't know if it's only when
>>> calling with Packages or not. I also have not carefully confirmed
>>> this.
>>>
>>> Finally, don't we have a convenience component to do this?
>>>
>>> Geoff
>>>
>>>
>>> --------------------------------------------------------------------
-
>>> To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
>>> For additional commands, e-mail: users-help@cocoon.apache.org
Re: extending FOM? (was on cocoon-users: Re: Parsing Source into
DOM in Flow)
Posted by Christopher Oliver <re...@verizon.net>.
Why not have processPipelineTo take a javax.xml.transform.Result instead
of an OutputStream?
Guido Casper wrote:
>Did anyone else also feel the need to have something like
>processPipelineTo but getting a DOM or just an InputStream instead of
>just streaming it directly to another OutputStream?
>
>Guido
>
>
>Geoff Howard wrote:
>
>
>>Upayavira wrote:
>>
>>
>>>Maybe my last question was too specific.
>>>
>>>I'm trying to parse the contents of a source into a DOM in
>>>Flowscript, but am getting all sorts of errors. Can anyone provide a
>>>better way than this (which doesn't work)?
>>>
>>>var resolver =
>>>
>>>
>>>
>cocoon.getComponent(Packages.org.apache.excalibur.source.SourceResolver.
>ROLE);
>
>
>>>var source = resolver.resolveURI("blah.xml");
>>>var builder =
>>>
>>>
>>>
>Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocum
>entBuilder();
>
>
>>I think I have observed that you cannot use the returned result of a
>>java method call ( newInstance() ) as a java object in flow (
>>.newDocumentBuilder() ).
>>
>>The workaround I have found is to separate the calls:
>>
>>var builderFactory =
>>Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance();
>>
>>var builder = builderFactory.newDocumentBuilder();
>>
>>I don't know if this is a bug or not, don't know if it's only when
>>calling with Packages or not. I also have not carefully confirmed
>>this.
>>
>>Finally, don't we have a convenience component to do this?
>>
>>Geoff
>>
>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
>>For additional commands, e-mail: users-help@cocoon.apache.org
>>
>>
>
>
>
>