[ 
https://issues.apache.org/jira/browse/WICKET-5256?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13694627#comment-13694627
 ] 

Antti Hätinen commented on WICKET-5256:
---------------------------------------

Exposing public getCharsetName() in StringBufferResourceStream would also do.
                
> ResourceStreamResource does not setTextEncoding for StringResourceStream
> ------------------------------------------------------------------------
>
>                 Key: WICKET-5256
>                 URL: https://issues.apache.org/jira/browse/WICKET-5256
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket
>    Affects Versions: 1.5.10
>         Environment: Ubuntu 12.04, Sun JDK 1.6.0_38 64bit
>            Reporter: Antti Hätinen
>            Priority: Minor
>              Labels: ResourceStreamResource, StringResourceStream, 
> setTextEncoding
>         Attachments: WICKET-5256.patch
>
>
> During the migration from Wicket 1.4 to 1.5.10 I found out that the 
> ResourceStreamResource.respond() does not set the ContentType charset if the 
> resource is of type StringResourceStream. Even though the stream holds the 
> charset, it is not set, although quite a few other header parameters are 
> (well this is understandable because not all ResourceStreams are 
> StringResourceStreams. Also, it is difficult to call the 
> resource.setTextEncoding, because the current flow in 
> resourceStreamRequestHandler.respond does not allow easy overriding of any 
> smaller piece of respond than the whole method. The practical issue was to 
> download a CSV file by clicking a button. I managed to fix the issue by 
> copy/paste/Overriding the ResourceStreamRequestHandler.respond, but IMHO this 
> is not nice:
>     private void addCsvButton() {
>         Form<?> form = new Form<Void>("form") {
>             @Override
>             protected void onSubmit() {
>                 final String fileName = getFileName("csv");
>                 TableCsvResourceFactory factory = new 
> TableCsvResourceFactory();
>                 final IResourceStream resourceStream = 
> factory.getResourceStream(tableModel.getObject());
>                 ResourceStreamRequestHandler resourceStreamRequestHandler = 
> new ResourceStreamRequestHandler(
>                         resourceStream) {
>                     final ContentDisposition contentDisposition = 
> ContentDisposition.ATTACHMENT;
>                     @Override
>                     public void respond(IRequestCycle requestCycle) {
>                         Attributes attributes = new 
> Attributes(requestCycle.getRequest(), requestCycle.getResponse());
>                         ResourceStreamResource resource = new 
> ResourceStreamResource(resourceStream);
>                         resource.setFileName(fileName);
>                         if (contentDisposition != null) {
>                             
> resource.setContentDisposition(contentDisposition);
>                         } else {
>                             
> resource.setContentDisposition(Strings.isEmpty(fileName) ? 
> ContentDisposition.INLINE
>                                     : ContentDisposition.ATTACHMENT);
>                         }
>                         final Duration cacheDuration = getCacheDuration();
>                         if (cacheDuration != null) {
>                             resource.setCacheDuration(cacheDuration);
>                         }
> +                        resource.setTextEncoding("UTF-8");
>                         resource.respond(attributes);
>                     }
>                 };
>                 
> RequestCycle.get().scheduleRequestHandlerAfterCurrent(resourceStreamRequestHandler);
>             }
>         };
>         form.setVisible(displayCsv);
>         add(form);
>     }
> There are a couple of problems with the current implementation of 
> ResourceStreamRequestHandler:
> 1) I didn't figure out yet any other way how to call the 
>                         resource.setTextEncoding("UTF-8");
> except by copy/pasting the whole ResourceStreamRequestHandler.respond() code 
> to the Override. It would be nice, if there would be some cleaner hook to 
> override some smaller part of this method, such as an empty default 
> implementation of setTextEncoding() that would be always called but would not 
> do anything for other types.
> 2) A second approach would be to create a StringResourceStreamRequestHandler 
> extends ResourceStreamRequestHandler that would be otherwise the same, but 
> would use IStringResource instead of IResource, and would also set the 
> TextEncoding.
> 3) However, third, I didn't yet find any good way to get the encoding from 
> the StringResourceStream itself, because the AbstractStringResourceStream has 
> a protected getCharset(). This problem could be overcome by adding public 
> version of getCharset() to StringResourceStream, or as I did, create a 
> parallel subclass CharsetStringResourceStream that is a copy/paste from 
> StringResourceStream but is non-final and has public getCharset(). After this 
> you could dynamically set the text encoding in 
> ResourceStreamRequestHandler.respond for example like this:
>                         if (getResourceStream() instanceof 
> CharsetStringResourceStream) {
>                             
> resource.setTextEncoding(((CharsetStringResourceStream)getResourceStream()).getCharsetName());
>                         }
> Anyway, I think the usage of StringResourceStream with 
> ResourceStreamRequestHandler should be improved somehow, at the moment I 
> think it is a bit awkward to use.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to