ServletOutputStream out = res.getOutputStream();
Frame frame = null;
Graphics g = null;
try {
// Get the count to display, must be sole value in the raw query string
// Or use the default
String count = (String)req.getQueryString();
if (count == null) count = COUNT;
int countlen = count.length();
Image images[] = new Image[countlen];
for (int i = 0; i < countlen; i++) {
URL imageSrc =
getServletContext().getResource(DIR + "/" + count.charAt(i) + ".GIF");
if (imageSrc == null) {
imageSrc = new URL("file:"); // placeholder, handle errors later
}
images[i] = Toolkit.getDefaultToolkit().getImage(imageSrc);
}
// Create an unshown Frame
frame = new Frame();
frame.addNotify();
// Load the images
MediaTracker mt = new MediaTracker(frame);
for (int i = 0; i < countlen; i++) {
mt.addImage(images[i], i);
}
try {
mt.waitForAll();
}
catch (InterruptedException e) {
res.sendError(res.SC_INTERNAL_SERVER_ERROR,
"Interrupted while loading image: " +
ServletUtils.getStackTraceAsString(e));
return;
}
// Check for problems loading the images
if (mt.isErrorAny()) {
// We had a problem, find which image(s)
StringBuffer problemChars = new StringBuffer();
for (int i = 0; i < countlen; i++) {
if (mt.isErrorID(i)) {
problemChars.append(count.charAt(i));
}
}
res.sendError(res.SC_INTERNAL_SERVER_ERROR,
"Could not load an image for these characters: " +
problemChars.toString());
return;
}
// Get the cumulative size of the images
int width = 0;
int height = 0;
for (int i = 0; i < countlen; i++) {
width += images[i].getWidth(frame);
height = Math.max(height, images[i].getHeight(frame));
}
// Get a graphics region to match, using the Frame
Image image = frame.createImage(width, height);
g = image.getGraphics();
// Draw the images
int xindex = 0;
for (int i = 0; i < countlen; i++) {
g.drawImage(images[i], xindex, 0, frame);
xindex += images[i].getWidth(frame);
}
// Encode and return the composite
res.setContentType("image/gif");
GifEncoder encoder = new GifEncoder(image, out);
encoder.encode();
}
finally {
// Clean up resources
if (g != null) g.dispose();
if (frame != null) frame.removeNotify();
}