Reference Manual for Gracelets - 2.0.0.RC2SourceForge.net Logo
2.15 - Tutorial : Inline Media
Sometimes you want to be able to inline media (like graphics, especially charts) more often than not when its dynamic (reporting charts, shopping cart pictures, etc.,). Although you can go about this in many different ways in the Gracelets environment, there is a new option, a dynamic media link.

What this allows you to do is provide a closure that writes to a provided output stream or uses a provided xml markup builder. Together with the content type you provide, it will create a dynamic link to access the closure. In this way there is no storage of big data in memory or complicated servlets or phase listeners. Your closure can be compact, but its responsable for providing the data for the dynamic media resource.

In view scripts (or even in libraries) you access this via the "resource" variable, which has a method on in the form of: link(String, Closure). The first parameter is a string specifying the content type (i.e., image/png) and the second is the closure that is responsable for creating the content. If the content type starts with 'text', like 'text/html' it will provide a Markup builder tied to the ResponseWriter for the JSF context that you can use to produce the output. Otherwise it will provide the Response OutputStream that you can write to in order to send the media content to the client.

The following example will illustrate this:
Toggle Line Numbers
1 xh.img(src: resource.link("image/png") { stream -> someBean.writePicture(stream) }) 
Here we say that a dynamic link should be made, when it is retrieved from the browser Gracelets will use the closure and contentType provided to respond.

When using this in a looping component, like dataTable's you can do something like the following:

Toggle Line Numbers
1  
2 h.dataTable(value: { someDataModel }, var: "row") { 
3     h.column { 
4         xh.img(src: { 
5             (resource.link("image/png") { stream -> someBean.writePicture( stream, Integer.parseInt(param.id) ) }) + "&id=$row.id" 
6         }) 
7     } 
8 } 
9              
Here we add an id to the link created by the Gracelets system. Then since our media generating closures have access to all the normal gracelets view stuff, we grab the id from the request parameter when the image is being requested from the browser.

The following is a working example showing how you could dynamically generate a JPEG with Java's 2D library and also how inside these closures you have access to the JSF/framework environment which includes, among other things, access to the variable contexts.

Toggle Line Numbers
1   
2 import java.awt.Color; 
3 import java.awt.Graphics2D; 
4 import java.awt.Image; 
5 import java.awt.Stroke; 
6 import java.awt.Toolkit; 
7 import java.awt.image.BufferedImage; 
8 import java.io.FileOutputStream; 
9  
10 import javax.imageio.ImageIO; 
11 import javax.imageio.ImageWriter; 
12  
13 import com.sun.imageio.plugins.jpeg.JPEGImageWriter; 
14  
15 Factory("mediaVar") { "Some Variable" } 
16  
17 xh.img(src: resource.link("image/jpeg") { stream -> 
18      
19     BufferedImage img = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); 
20  
21     Graphics2D g2d = (Graphics2D) img.getGraphics(); 
22      
23     g2d.setPaintMode(); 
24     g2d.setColor(Color.WHITE); 
25     g2d.drawString(mediaVar, 100, 100); 
26      
27     img.flush(); 
28  
29     ImageIO.write(img, "JPEG", stream); 
30      
31 }) 
32          
http://somesite/somepage.jsf - Mozilla Firefox
http://somesite/somepage.jsf
http://somesite/somepage.jsf