cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Zisch (Matthias Meier), NetHorizon AG" <>
Subject Internal Subrequests [Was: Re: Some Cocoon-Hacks [...]]
Date Sun, 02 Apr 2000 21:13:02 GMT
Hi Donald,

> > I looked through the Cocoon 2 sources and my conclusion is, that it would
> > probably need much more work for me to get a clean implementation of the
> > inclusion-functionality into it, than doing some dirty hacks on Cocoon 1. (I
> > think, I can get away with hacking the Engine class in Cocoon 1, while the
> > architecture of Cocoon 2 is -- no wonder -- quite different and somewhat more
> > complex.)
> What are you talking about? You could write a simple filter to process
> XIncludes. What's hard about that?
> - donald

Weeell ... maybe I just don't see how easy it is? ;-)

I will try to explain my thoughts:

I admit, one could simply open a URL to the document beeing included and parse
the resulting character-stream to get a DOM Document (for Cocoon 1) resp. SAX
events (for Cocoon 2). This is OK for external URL's, but I wouldn't call it a
good solution for including internal documents (that is documents which are
served by the same Cocoon instance as the including document), since one of the
major points of Cocoon is that you can parse the XML once and then filter them
on the DOM/SAX-event level. (I assume that this is not only an academic
question, but actually important for the performance of -- for example -- our
shop-software, since usually every shop-page includes at least three other
parts: a header, a footer and a navigation-panel!)

In Cocoon 1, you can (I think ;-) basically split the handle() method and put
an inner part of it into a method with the following signature:

  private Document handleInternally(HttpServletRequest req,
                                    HttpServletResponse resp) throws ...

This method would do most of the work which is currently done in handle();
however, it would _not_ call the formatter, but return the document after it
has been processed by all Processors. The formatting-part (and probably
some other stuff, like creating and caching the page-object) would be left in

You could then implement a method like the following:

  public Document handleInternalRequest(HttpServletRequest req,
                                        HttpServletResponse resp,
                                        String path) throws ...

which would wrap the HttpServletRequest in a simple wrapper and call
handleInternally() using the wrapped request object. The wrapper would redirect
almost all calls to the actual request object, except for getPathInfo() and
getPathTranslated(), which would return 'path' resp.
'ServletContext.getRealPath(path)'. (Note: 'path' is meant to be the path to
the document which should be included into another document.)

Once you have the handleInternalRequest() method, it should be easy to
"internally" request a Document from the Engine object (for example from
whithin an XSP page or from whithin a dedicated Processor which just processes
XInclude elements) and to include it into another Document tree.

This is only a rough sketch of how I intend to do it. I expect some hairy
details to come up in practice, but I think it should basically work this way.
(If I do it just for our own purposes, I can also do some simplifications,
since we only need XSP and XSLT and _all_ pages are dynamic XSP pages, because
we want to do URL-rewriting in every page. Therefore I just need to make the
XSP and XSLT Processors work and don't need to cache the formatted pages!)

In Cocoon 2 on the other hand, I expect this to get somewhat more complicated.
Probably the Sitemap should contain a method like:

  public void processInternalRequest(Request req, Response resp,
                                     String path, ContentHandler saxHandler)
                                     throws ...

which would correspond to the handleInternalRequest() method for Cocoon 1. The
question is how to implement this method. My idea is, that probably the
processing-pipeline for internal requests need to end with a Generator, which
does not actually write the document to the output stream, but rather forwards
it to the specified ContentHandler. This Generator will need to know which
ContentHandler to use, therefore the processInternalRequest() method will
probably set the target ContentHandler as a request attribute.

(Note: I _believe_ that "Generator" in Cocoon 2 is the equivalent to
"Formatter" in Cocoon 1, but I'm not really sure!)

You see, I have an idea about how to do it, but it's not as clear to me as for
the Cocoon 1 variant.

Also for a clean implementation, some other issues will probably come up. For
example, the included pages probably should have a way to "know" the path of
the main-page into which they are included; should Request contain an
additional method getRequestedPath() for this? How does the caching work in the
case of internal requests? Etc. etc.

BTW: I assume the Cocoon 2 variant will allow to define the pages which are
just parts of other pages as opposed to the "main"-pages which can be requested
externally (by specifying the appropriate Generator in the Sitemap). This would
be a really nice feature.

As I said: it surely can be done in Cocoon 2, but I expect that I would need
more time than for the Cocoon 1 variant, especially if it should be more than a
dirty hack.

Finally, I admit, that my main problem with the Cocoon 2 variant is probably,
that I don't know the Cocoon 2 source code very well at the moment, and I will
need time to learn more about it. So be patient with me! ;-)


| Matthias Meier  |
| NetHorizon AG     |
|                                                  |
| City Server of Winterthur |
| Swiss Internet CD Shop |
| Web Application Framework |

View raw message