Gary, I wanted to thank you for your well-thought-out post just before Christmas. I have attributes on my custom component now that support selecting HTML or PDF, popup window or embedded, for reports. The embed option (I ended up using an OBJECT tag) with a separate servlet serving up the PDF avoided the need for extra renderkits for the PDF. The pop-up options worked out well also. Thanks for pointing me in the right directions.

I have been enjoying Clay the more I learn about how to use it. Good stuff...


----- Original Message ----- From: "Gary VanMatre" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Sunday, December 24, 2006 10:04 AM
Subject: Re: Question about custom component and PDF


>From: "Steve Olson" <[EMAIL PROTECTED]>

I'm new to Clay, and just slightly less new to JSF. I'm experimenting with a JSF custom component that renders an eclipse BIRT report. I'm using Clay HTML views in a webapp that among other things needs to render various reports. I'm
not using any JSP, so didn't bother with a JSP tag for this component.

BIRT reports can either be rendered as embedded HTML, or as a PDF. I think I understand how everything works rendering HTML. My question is with rendering a report to PDF - the content is no longer HTML and the response content type has to be application/pdf. So my custom component based on UIComponentBase that
works fine with embeded HTML won't work for PDF. If an attribute on this
component indicates a PDF rendering is desired, what's a good strategy for implementing this? One thought that comes to mind is rendering javascript back in the HTML response, that would pop up a separate window, and have that served by a separate URL handled outside of Clay/JSF. Are there better alternatives for handling this? I know very little about custom RenderKits or other options,
and would appreciate it if anyone is interested in pointing me in other
directions.

Thanks in advance for any tips...

If you are using full clay views (no-jsp), the clay view handler assumes the content type of the response to be "text/html". That's if a content type has not already been set.
This is one of those todo items.

Although, I think you could set the response's content
type to "application/pdf" in a view controllers prerender event. Or, create a JSP page
that sets the content type, has a f:view tag and a single clay component.

You can change the render kit per view using the f:view tag's "renderKitId" attribute, but it applies to the entire page - all components in the view. Clay allows you to do this using the "f:view". It just needs to be some place in the page - unlike the jsp tag that has to be a root. <span view="f:view" renderKitId="org.acme.mypdfkit"/>

If you created a html markup renderer for your component and also a PDF renderer, you would need to register them in the faces config under different render kits.

  <render-kit>
     <render-kit-id>org.acme.mypdfkit</render-kit-id>
     <renderer>
        <component-family>org.acme.mycomponent</component-family>
        <renderer-type>org.acme.mycomponent</renderer-type>
        <renderer-class>org.acme.mycomponentPdfRenderer</renderer-class>
     </renderer>
  <render-kit>
  <render-kit>
     <!-- default -->
     <renderer>
        <component-family>org.acme.mycomponent</component-family>
        <renderer-type>org.acme.mycomponent</renderer-type>
        <renderer-class>org.acme.mycomponentRenderer</renderer-class>
     </renderer>
  <render-kit>

I've always liked to see the PDF documents embeded in html. If you are able to embed the document, you could make a component attribute for documentType (html or pdf). The renderer could generate an html embed tag with a src that pointed to a servlet. The render could save the document to a map in session scope. The key used to store the document in the session map could be added as a query parameter to the src of the embed tag. So, the servlet only needs to look for the query parameter and use it as the key into the document's cache. Next,
push the cached document to the response and set the content type.

<EMBED width="672" height="500" border="2"
src="/contextRoot/embedDoc;jsessionid=xxx?token=123"
type=application/pdf >

Another approach would be to use the Trinidad internal view handler versus a servlet. With the internal view handler, you can map a custom view hander to a view id. So, if your view id was "/embedDoc", you could delegate to an internal view handler that could create a component tree specifically addressing your needs. They use this to complement some of the trinidad components that need popup dialogs. I have an
example of this in the shale sandbox.

Properties file to register the mapping between viewId and internal view handler:
http://svn.apache.org/viewvc/shale/sandbox/shale-clay-trinidad/src/main/resources/META-INF/org.apache.myfaces.trinidad.render.InternalView.properties?view=log

View handler:
http://svn.apache.org/viewvc/shale/sandbox/shale-clay-trinidad/src/main/java/org/apache/shale/clay/PageHandler.java?view=log

Your popup idea would also work nicely with this library. They make it very easy to attach script files. Here's an example of sending script to the browser
(@ "loadHtmlFragment" method):
http://svn.apache.org/viewvc/shale/sandbox/shale-clay-trinidad/src/main/java/org/apache/myfaces/trinidad/blank/CatalogBacking.java?view=markup

Sounds like a fun project.  Hope that gives you some ideas.

Gary

Reply via email to