Leszek Gawron wrote:

The whole module idea is really great but (please correct me if I'm wrong):


<map:generate type="file" src="module:request:inputStream"/>

The o.a.c.components.modules.input.RequestModule provides this:


return ObjectModelHelper.getRequest(objectModel);

getRequest returns o.a.c.environment.Request which is an interface that is not
bound to http. You cannot reach the request's body from here.

Actually you can. When you use Cocoon as a servlet ObjectModelHelper.getRequest(objectModel) returns a HTTPServletRequest object. Then the "inputStream" part of "module:request:inputStream" is accessed through reflection using JXPath, so you will get the inputStream without needing to do any down cast. As I have a background from more strongly typed programming languages I first found it quite "hacky", but I decided that it probably is ok to do this kind of stuff while using reflection.


I have a test in the samples: http://cvs.apache.org/viewcvs.cgi/cocoon-2.1/src/blocks/scratchpad/samples/module-source/sitemap.xmap

try
> curl -T "test.xml" http://localhost:8888/samples/scratchpad/module-source/test3


It worked some weeks ago at least ;) Please tell if it has stoped working.


To be able to read from input stream one has to do this:


HttpServletRequest request =    
  (HttpServletRequest) objectModel.get( HttpEnvironment.HTTP_REQUEST_OBJECT );
int contentLength = request.getContentLength();
PostInputStream stream = new PostInputStream(    request.getInputStream(),

                                                contentLength   );
InputSource     contentSource = new     InputSource( stream );
parser = ( DOMParser ) manager.lookup( DOMParser.ROLE );
return parser.parseDocument( contentSource );

How can I reach the XModuleSource from XSP? I need it for processing XML
document that is passed as request body (right now I use the code pasted
above).

I don't use XSP. Using flowscript I would write a pipeline consisting of a file generator with module:request:inputStream as source and an xml serializer. This pipeline is then called from processToDOM in PipelineUtil. I don't know if there are any XSP tag libraries for using sources, but you can at least simplify the above code considerably by first geting the source resolver, then using o.a.c.components.source.SourceUtil.readDOM with the URI module:request:inputStream. There are lots of usefull stuff for using sources in SourceUtil.


You cannot use XModuleSource for reading from the input stream, XModuleSource only reads from DOM and XMLizable, you should use the ModuleSource that reads from streams and strings instead.

The task for sources is to get an input stream from a URI, while it is the task of a generator to adapt an binary input e.g. a atream to XML. From this we can see that the XModuleSource is a little bit outside the borders of how sources are supposed to behave, it would in some sense have been better to let the ModuleSource check if the input is a DOM or an XMLizable and in that case serialize it to a stream. The reasons for me to write the XModuleSource was that I wanted a modifiable source that could store the result in a DOM tree, and I found no natural way to extend the ModuleSource to this behaviour as it doesn't make sense for non-xml input. We also avoid one parse/reparse step when it is used from e.g. the file generator, by leting XModuleSource implement XMLizable, this wouldn't make sense for the more general ModuleSource.

/Daniel



Reply via email to