See the serlvet code in the attachment. Compile into WEB-INF/classes or into a jar under WEB-INF/lib
some use examples:
globalMacros.vm:#macro( button $parameters )/$WEBAPP/html/buttonFactory.jsp$parameters#end
#set( $tabButton = "$properties.getServletPath('button')" )
#set( $tabButton = "$tabButton?fontSize=12&fontStyle=Italic&tab=true" )
#set( $tabButton = "$tabButton&width=80&insetH=0&insetV=0&border=4" )
#set( $tabButton = "$tabButton&borderColor=0xC0C0C0" )
<td valign="bottom" height="26" background="$tabButton&text=$tabName">
in the WEB-INF/web.xml add
<servlet>
<servlet-name>ButtonFactory</servlet-name>
<servlet-class>de.dlr.dfd.naomi.ButtonFactory</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>ButtonFactory</servlet-name>
<url-pattern>/button/*</url-pattern>
</servlet-mapping>I hope this gives an idea.
Cheers, Christoph
Ilan Azbel wrote:
Thanks for the help. That code would be much appreciated. Could you also tell me to which directory I should compile my .class to?
Ilan
-----Original Message----- From: Christoph Reck [mailto:[EMAIL PROTECTED] Sent: 25 November 2004 04:17 To: Velocity Users List Subject: Re: vm to return a binary file
Ilan Azbel wrote:
Hello,
I would like a vm to return a binary file and thereby instruct
the browser
not to display it, but rather to download it. That is, ask the
user if they
would like to "Open" or "Save" the file.
I would like to do this without any redirecting statements - so
as soon as a
user requests a certain .vm file, the corresponding java
creates some type
of binary data, and the browser immediately asks whether to open or save this data.
Thanks Ilan
Hi,
first, be advised to configure your servlet container to serve binary data itself or to use your own servlet to create the binary content.
Solutions using Velocity tend to be a bit fragile (character encoding, whitespace handling, first and only to write to the output stream, changing response headers, etc.).
I once tried the following, but at some point in velocity history the response stream was changed - to my memory it was from Writer to OutputStream. (please notice the several context tools used to do the task).
#set( $l_file = $ServletContext.getRealPath("/images/$l_fileName") ) #if( $File.fileExists($l_file) ) #set( $l_fileData = $File.fileRead($l_file) ) ### check for other image types $res.setHeader("Content-type", "image/jpeg") $data.Out.write($l_fileData) #else #error( "File $l_file does not exist and cannot be displayed" ) #end
the I rewrote it to: <br> <img src="#image($l_fileName)" border="0" />
using a globalMacros.vm: #macro( image $fileName )/$WEBAPP/images/$fileName#end
This lets the HTTP server do its job.
You could use the first approach in velocity, by placing the outputStream object into the context and letting the template add the (binary) data. But be aware! this construct is really fragile - mainly due to the inconsitent whitespace handling of velocity. Also problesm arise when using the VelocitylayoutServlet, wher you have to instruct to skip the layout in such a case...
If you wish an example of creating binary content with a servlet check the literature, servlets.com, or I can send you a servlet code that creates button+text images on the fly.
-- :) Christoph Reck
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--- Incoming mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.801 / Virus Database: 544 - Release Date: 2004/11/24
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
package de.dlr.dfd.naomi;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import javax.swing.Icon;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicGraphicsUtils;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.acme.jpm.encoders.GifEncoder;
public class ButtonFactory extends HttpServlet {
private static final String BG_COLOR = "#CCCCCC"; // gray
private static final String FG_COLOR = "#000000"; // black
private static final String BD_COLOR = "#666666"; // dark gray
private static final String HL_COLOR = "#EEEEEE"; // light gray
private static String getParameter(
HttpServletRequest request, String name, String defaultValue )
{
String param = request.getParameter(name);
return (param == null) ? defaultValue : param;
}
public static int convertToInt(String str) {
if ( str.startsWith("0x") )
return Integer.parseInt(str.substring(2), 16);
else if ( str.startsWith("#") )
return Integer.parseInt(str.substring(1), 16);
else
return Integer.parseInt(str);
}
public static Color convertToColor(String colorStr) {
return new Color( convertToInt(colorStr) );
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
PrintWriter out = response.getWriter();
try {
BufferedImage img = null;
Graphics g = null;
FontMetrics fontMetrics = null;
Font font = null;
// get text
String text = getParameter(request, "text", "OK");
// get background
//## String data = readFile(request, "images/naomic.gif");
Icon icon = null;
// decode font
String fontName = getParameter(request, "fontName", "Dialog");
String fontStyle = getParameter(request, "fontStyle", "");
int fontSize = Integer.parseInt( getParameter(request, "fontSize", "14")
);
int style =
(((fontStyle.indexOf('B') >= 0) ||
(fontStyle.indexOf('b') >= 0)) ? Font.BOLD : Font.PLAIN)
| (((fontStyle.indexOf('I') >= 0) ||
(fontStyle.indexOf('i') >= 0)) ? Font.ITALIC : Font.PLAIN);
font = new Font(fontName, style, fontSize);
// decode size
int border = Integer.parseInt( getParameter(request, "border", "2") );
if (border < 0) border = 0;
int insetH = Integer.parseInt( getParameter(request, "insetH", "10") );
int insetV = Integer.parseInt( getParameter(request, "insetV", "1") );
int width = 20;
int height = 20;
// retrieve font metrics to determine minimum height
img = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED);
g = img.createGraphics();
g.setFont(font);
fontMetrics = g.getFontMetrics();
g.dispose();
int x = SwingUtilities.computeStringWidth(fontMetrics, text)
+ 2*border + 2*insetH;
int y = fontMetrics.getHeight() + 2*border + 2*insetV;
int w = Integer.parseInt( getParameter(request, "width", "" + x) );
int h = Integer.parseInt( getParameter(request, "height", "" + y) );
if ( (w > width) || (h > height) || (y > height) ) {
if (w > width) width = w;
if (h > height) height = h;
if (y > height) height = y;
img = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED);
}
// decode colors
Color fgColor = Color.decode(
getParameter(request, "fgColor", FG_COLOR ) );
Color bgColor = Color.decode(
getParameter(request, "bgColor", BG_COLOR ) );
Color buttonColor = convertToColor(
getParameter(request, "buttonColor", String.valueOf(bgColor.getRGB()) )
);
Color borderColor = Color.decode(
getParameter(request, "borderColor", BD_COLOR ) );
Color borderHighlite = Color.decode(
getParameter(request, "borderHighlite", HL_COLOR) );
int transparent = convertToInt( getParameter(request, "transparent",
"-1") );
// decode button state
boolean enabled = Boolean.valueOf(
getParameter(request, "enabled", "true") ).booleanValue();
boolean pressed = Boolean.valueOf(
getParameter(request, "pressed", "false") ).booleanValue();
boolean tabShape = Boolean.valueOf(
getParameter(request, "tab", "false") ).booleanValue();
// build button
g = img.createGraphics();
g.setFont(font);
fontMetrics = g.getFontMetrics();
Rectangle iconR = new Rectangle(0, 0, 0, 0);
Rectangle textR = new Rectangle(0, 0, 0, 0);
Rectangle viewR =
new Rectangle(insetH, insetV, width - 2*insetH, height - 2*insetV);
String clippedText = SwingUtilities.layoutCompoundLabel(
fontMetrics,
text,
icon,
SwingUtilities.CENTER, // VerticalAlignment
SwingUtilities.CENTER, // HorizontalAlignment
SwingUtilities.CENTER, // VerticalTextPosition
SwingUtilities.CENTER, // HorizontalTextPosition
viewR,
iconR,
textR,
0 );
// draw background and border
g.setColor(bgColor);
g.fillRect(0, 0, width, height);
if (tabShape) {
int x1 = border;
int x2 = (height - 2*border)/2;
int x3 = width - x2;
int x4 = width - border;
int y1 = height - 2; // border does not affect Y
int y2 = 2;
// draw tab
g.setColor(buttonColor);
g.fillPolygon( new int[] {x1 - 1, x2 - 1, x3 + 1, x4 + 1},
new int[] {y1, y2, y2, y1}, 4 );
// draw bottom line (selected or unselected)
g.setColor((pressed) ? buttonColor : borderHighlite);
g.drawLine(x1 - 1, y1, x4 + 1, y1); // bottom line
g.setColor((pressed) ? buttonColor : borderColor);
g.drawLine(x1 - 2, y1 + 1, x4 + 2, y1 + 1);
// draw bezel tab border
g.setColor(borderHighlite);
g.drawLine(x1 - 2, y1 - 1, x2 - 2, y2 ); // up
g.drawLine(x2 - 1, y2 - 2, x3 , y2 - 2); // right
g.setColor(borderHighlite.darker());
g.drawLine(x1 - 1, y1 - 1, x2 - 1, y2 ); // up
g.drawLine(x2 - 1, y2 - 1, x3 + 1, y2 - 1); // right
g.setColor(borderColor.darker());
g.drawLine(x3 + 1, y2 , x4 + 1, y1 ); // down
g.setColor(borderColor);
g.drawLine(x3 + 2, y2 , x4 + 2, y1 ); // down
// tab connector line
if (!pressed || (border > 2)) {
g.setColor(borderHighlite);
g.drawLine(0 , y1, x1 - 2, y1);
g.drawLine(x4 + 2, y1, width , y1);
g.setColor(borderColor);
g.drawLine(0 , y1 + 1, x1 - 3, y1 + 1);
g.drawLine(x4 + 2, y1 + 1, width , y1 + 1);
}
} else {
g.setColor(buttonColor);
g.fillRect(border, border, width - 2*border, height - 2*border);
if (border >= 2) {
BasicGraphicsUtils.drawBezel( g,
border - 2, border - 2,
width - 2*border + 4, height - 2*border + 4,
pressed, false,
borderColor.darker(), borderColor,
borderHighlite, borderHighlite.brighter()
);
}
}
//## if (icon != null) {
//## icon.paintIcon(c, g, iconR.x, iconR.y);
//## }
if (text != null) {
int textX = textR.x;
int textY = textR.y + fontMetrics.getAscent();
if (enabled) {
g.setColor(fgColor);
} else {
g.setColor(bgColor.brighter());
g.drawString(clippedText, textX + 1, textY + 1);
g.setColor(bgColor.darker());
}
g.drawString(clippedText, textX, textY);
}
g.dispose();
// prepare buffer with typical button data size
ByteArrayOutputStream buf = new ByteArrayOutputStream(1200);
// decide what we should return
String format = getParameter(request, "format", "gif");
if ( format.equalsIgnoreCase("jpeg") ) {
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(buf);
encoder.encode(img);
response.setContentType("image/jpeg");
} else {
GifEncoder encoder = new GifEncoder(img);
if (transparent >= 0) {
//## not wroking properly, e.g. only works with 0x000000 and 0x333333
encoder.setTransparentRGB(transparent);
}
encoder.write(buf);
response.setContentType("image/gif");
}
out.write( buf.toString( response.getCharacterEncoding() ) );
} catch (Exception ex) {
response.setContentType("text/plain");
out.write("An error ocurred\n");
ex.printStackTrace(out);
}
} // end of doGet
} // end of ButtonFactory
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
