Hi All,

Martin, thanks for the response, see comments below:

On 08/06/2012 02:26, Martin Grigorov wrote:
Hi Jesse,

The signature of this method has been changed with:

commit 4977f66ef55eaa5d89ed5d3751ff6aefc9652c50
Author: Matej Knopp<[email protected]>
Date:   Mon Jan 4 01:03:29 2010 +0000

     Wild attempt to integrate new RequestCycle
     src/main/java almost builds, definitely doesn't work
     rest doesn't even build

     put bunch of classes that will likely be removed to src/main/disabled

     hopefully will continue working on it shortly


I.e. it was changed in the very early early days of 1.5.
I'm not sure whether the change is intentional, i.e. whether Matej
wanted to improve the API by making it consistent with the rest of the
code or it was just part of "make the code compiling" coding session.

I think it makes it more inconsistent. IResourceStream has a size, contentType and lastModified. It also has a getInputStream() to get the data. This can be implemented for things like java.io.File etc that have no knowledge of what a HTTP request/response is. IResourceStreamWriter is a simple class that is a IResourceStream, but instead of using pull to get the data, it pushes the data to an OutputStream. Think generate data on the fly. Without it, I would have to use a IResourceStream, write my data to memory or a temp file, then provide a InputStream to read that temp data. I think this is what the javadoc means when it says buffer.

It is the job of IResource to respond to a Response. It is the job of the IResourceStream to provide data and meta data. You cant have IResourceStream doing IResource's job, you'll have the labour unions all over you :-)

I wrote the original mail when I was implementing a custom IResourceStream, that generates new data for download for each request. I didn't want to write a buffer like described above, so I use IResourceStreamWriter. But, now I must write to a Response. So my thoughts go like this:

"Oh no, not I must first work out how a Response works, just to serve up generated data. Ok, so what does a Response do? Set headers and write to an OutputStream. OK, so I am being passed a Response, there is probably a need to write the headers, but I already provide the header data in IResourceStream API - lets see if they are being set for me. <dive into wicket internals, discover that ultimately its the responibility of ResourceStreamResource>. Oh look, its setting all the headers for me, so all I need to do is write data to the OutputStream. So why did I need a Response and have to dive into the internals to work out what to do with it?"


The javadoc says that IResourceStreamWriter can stream to the client
without buffering but looking at the current version I think this is
no more true, i.e. the written data IS buffered.
I cant see where it is buffered but thats not important for my situation.
I personally have never needed to use this class in my apps and I'm
not very familiar with it.

@Devs: is this class broken in 1.5.x ? Should we revert the API change for 6.x ?


On Thu, Jun 7, 2012 at 6:04 PM, Jesse Long<[email protected]>  wrote:
Hi Wicket Devs,

(wicket 6.0.0-beta2 btw).

Why does IResourceStreamWriter#write() take a Response and not an
OutputStream?

As I see it, ResourceStreamResource (which is called from
ResourceStreamRequestHandler) is responsible for setting the headers for the
response, and does. What more could the IResourceStreamWriter want to do
with the response?

AbstractResource#respond() calls
ResourceStreamResource#newResourceResponse(), which returns all the headers
in the ResourceReponse (using normal IResourceStream calls), and passes back
a wrapped call to IResourceStreamWriter#write() as the writer callback.
AbstractResource#respond() then sets the headers on the Response, then only
calls IResourceStreamWriter#write() via the write callback only if
AbstractResource thinks data needs to be written based on the values
returned from the normal IResourceStream calls.

So, if the IResourceStreamWriter sets different headers in its write()
method to the values produced by calling lastModifiedTime() etc (I would
consider this a bad idea, and probably wrong), there is a danger that
unexpected behaviour may occur if AbstractResource#respond() decides NOT to
call the writer callback (which will call IResourceStreamWriter#write()).
The IResourceStreamWriter implementer may wonder why his headers are not
being set.

If the IResourceStreamWriter does not set any headers apart from the data
available via its IResourceStream methods, then it obviously does not need a
Response object, because AbstractResource is setting all the headers
already. All IResourceStreamWriter needs to do is write data to the
OutputStream.

Could it be a remnant of an era where Response did not have a
getOutputStream() method, and writing to it required using Response#write()?

Also, AbstractResource.WriteCallback#writeStream() unnecessarily creates an
OutputStream that delegates write() calls to the Response. It could just as
well use the one provided by Response.getOutputStream().

Thanks,
Jesse




Reply via email to