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]

Reply via email to