Might this have something to do with the fact that I'm faking the
requestCycle in order to get the page's processed HTML ?
Like having the IResourceListener expired ?

I'm faking the request cycle like this :

/** Returns the processed HTML of the page as it would have been responded
by faking a requestcycle */
public static String renderPage(Page page) {

        //get the servlet context
        WebApplication application = (WebApplication) WebApplication.get();

        ServletContext context = application.getServletContext();

        //fake a request/response cycle
        MockHttpSession servletSession = new MockHttpSession(context);
        servletSession.setTemporary(true);

        MockHttpServletRequest servletRequest = new MockHttpServletRequest(
                application, servletSession, context);
        MockHttpServletResponse servletResponse = new
MockHttpServletResponse(
                servletRequest);

        //initialize request and response
        servletRequest.initialize();
        servletResponse.initialize();

        WebRequest webRequest = new ServletWebRequest(servletRequest);

        BufferedWebResponse webResponse = new
BufferedWebResponse(servletResponse);
        webResponse.setAjax(true);

        WebRequestCycle requestCycle = new WebRequestCycle(
                application, webRequest, webResponse);

        //requestCycle.setRequestTarget(new
BookmarkablePageRequestTarget(pageClass, pageParameters));
        requestCycle.setRequestTarget(new PageRequestTarget(page));

        try {
            requestCycle.getProcessor().respond(requestCycle);

            if (requestCycle.wasHandled() == false) {
                requestCycle.setRequestTarget(new
WebErrorCodeResponseTarget(
                        HttpServletResponse.SC_NOT_FOUND));
            }
            requestCycle.detach();

        } finally {
            requestCycle.getResponse().close();
        }

        return webResponse.toString();
    }


Thank you,
Xavier



2010/5/27 Xavier López <[email protected]>

> Finally, I've managed to dig through the XHtmlRenderer's code, and the
> IText dependencies inside, and have encountered the root of the issue :
>
> The problem is raised by the IText Image resource class, which tries to
> detect the format of the image by peeking at the first bytes of the stream.
> Getting into details, that piece of code receives an InputStream, obtained
> from a "new URL(source)", where 'source' is the value of the 'src' attribute
> in the <img> tag.
>
> I've tried constructing that URL by myself, and peeking at the first bytes,
> and have found that they do not match what it should be expected taking into
> account the image's format (jpg -> 0xFF, 0xD8). Instead, the first bytes
> are: 0x3C, 0x21, 0x44, 0x4F.
>
> I'm creating the Wicket image resource with a DynamicImageResource, and
> I've checked that, when it's called, it returns the expected first bytes...
>
> DynamicImageResource resource = new DynamicImageResource("jpg") {
>             @Override
>             protected byte[] getImageData() {
>                 return generateBarCode(....);
>             }
>         };
>
>
> And again, when I try this on the link's onClick:
>
> link = new Link("printFullPagament"){
>
>                         private static final long serialVersionUID = 1L;
>                         @Override
>                         public void onClick() {
>                             try{
>
>                                 String srcImg = "
> http://myapp/?wicket:interface=:34:
> barcode::IResourceListener::&wicket:antiCache=1274953227999";
>                                 java.io.InputStream is = new
> URL(srcImg).openStream();
>                                 int c1 = is.read();
>                                 int c2 = is.read();
>                                 int c3 = is.read();
>                                 int c4 = is.read();
>                                 ...
> }
>
> I don't seem to get DynamicImageResource#getImageData, nor any of the
> methods it defines (getResourceState()), and get those values on the first
> bytes ( 0x3C, 0x21, 0x44, 0x4F)
>
> Does anyone know what may be happening here ?
>
> Thanks a lot,
> Xavier Lopez
>
>
>
> 2010/5/27 Xavier López <[email protected]>
>
>> Sorry for double-posting, I'm attaching some of the code I'm using:
>>
>> I havent't mentioned other static styling images are rendering correctly.
>>
>>
>> byte[] imageByteArray = generateBarCodeImage(...)
>>> ByteArrayResource resource = new ByteArrayResource("image/jpeg",
>>> imageByteArray);
>>> Image barcodeImage= new Image("barcode", resource){
>>>             protected void onComponentTag(ComponentTag tag)
>>>             {
>>>                 super.onComponentTag(tag);
>>>                 String url = tag.getAttributes().getString("src");
>>>                 url = url + ((url.indexOf("?") >= 0) ? "&amp;" : "?");
>>>                 url = url + "wicket:antiCache=" +
>>> System.currentTimeMillis();
>>>                 tag.put("src", url);
>>>             }
>>>         };
>>> barcodeImage.setMarkupId("barcodeImageId");
>>> barcodeImage.setOutputMarkupId(true);
>>> add(imatgeCodiBarres);
>>> .....
>>> link = new Link("printPDF"){
>>>                         private static final long serialVersionUID = 1L;
>>>                         @Override
>>>                         public void onClick() {
>>>                             try{
>>>                             String baseUrl = "http://myapp/";;
>>>                             // Get the html to render into pdf
>>>                             String html = RenderHTMLUtils.renderPage(new
>>> PrintPage(...));
>>>                             DocumentBuilder builder =
>>> DocumentBuilderFactory.newInstance().newDocumentBuilder();
>>>                             Document doc = builder.parse(new
>>> ByteArrayInputStream(html.getBytes("UTF-8")));
>>>
>>>
>>>                             String src =
>>> doc.getElementById("barcodeImageId").getAttribute("src");
>>>                             src = baseUrl + src;
>>>
>>> doc.getElementById("barcodeImageId").setAttribute("src", src);
>>>
>>>                             ITextRenderer renderer = new ITextRenderer();
>>>                             renderer.setDocument(doc, baseUrl);
>>>
>>>
>>> RequestCycle.get().setRequestTarget(EmptyRequestTarget.getInstance());
>>>                             WebResponse response = (WebResponse)
>>> getResponse();
>>>                             response.setContentType("application/pdf");
>>>                             response.setAttachmentHeader("printout.pdf");
>>>                             response.setHeader("Cache-Control",
>>> "max-age=0");
>>>                             OutputStream out =
>>> response.getOutputStream();
>>>                             renderer.layout();
>>>                             renderer.createPDF(out);
>>>                             }
>>>                             catch (Exception e){ }
>>>                         }
>>>                     };
>>>
>>
>> 2010/5/27 Xavier López <[email protected]>
>>
>> Hi,
>>>
>>> I'm trying to use a xhtml to pdf renderer 
>>> (https://xhtmlrenderer.dev.<http://goog_1283895835>
>>> java.net/) in order to print out a page to PDF.
>>>
>>> The page contains a  NonCachingImage, with a barcode, in such a way that
>>> the image gets the following HTML :
>>>
>>> <?xml version="1.0" encoding="UTF-8"?>
>>>> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "
>>>> http://www.w3.org/TR/xhtml11/DTD/xhtml11-flat.dtd";>
>>>> <html xml:lang="ca" xmlns="http://www.w3.org/1999/xhtml";>
>>>> ...
>>>> <img class="floatR"
>>>> src="?wicket:interface=:34:barcode::IResourceListener::&wicket:antiCache=1274953227999"/>
>>>> ...
>>>> </html>
>>>>
>>>
>>> When parsing the html String into a org.w3c.dom.document, I get the
>>> following exception:
>>>
>>> org.xml.sax.SAXParseException: The reference to entity "wicket:antiCache"
>>>> must end with the ';' delimiter.
>>>>
>>>
>>>
>>> I know this is probably not a Wicket issue, and maybe has to do with the
>>> DTD used for validation, or something like that.
>>> I found somewhere this can get solved by changing the '&' character in
>>> the URL by '&amp;'. That worked. Now I plan to override NonCachingImage's
>>> onComponentTag to append &amp; instead of '&'.
>>>
>>> That solved, I can't get the image to get rendered in the pdf document,
>>> in the html's DOM I have the <img> Element with the 'src' atttribute with
>>> value ="http://myapp/?wicket:interface=:34:
>>> barcode::IResourceListener::&wicket:antiCache=1274953227999", but
>>> Image#onResourceRequested() (which is the callback for that URL) never gets
>>> called during the render phase of the PDF...
>>>
>>> I'd really appreciate any hints on this one, I've been looking into the
>>> resources reference but I don't know if I should use it, or which
>>> implementation to use... The image resource is formed from a byte array.
>>>
>>> Many thanks,
>>> Xavier López
>>>
>>
>>

Reply via email to