KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > bridge > jsp > taglib > ImageTag


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.bridge.jsp.taglib;
11
12 import java.io.File JavaDoc;
13 import org.mmbase.bridge.jsp.taglib.util.Attribute;
14 import javax.servlet.http.HttpServletRequest JavaDoc;
15 import javax.servlet.http.HttpServletResponse JavaDoc;
16 import javax.servlet.jsp.JspTagException JavaDoc;
17
18 import org.mmbase.bridge.*;
19 import org.mmbase.util.functions.*;
20 import org.mmbase.util.images.*;
21 import org.mmbase.util.UriParser;
22 import org.mmbase.module.builders.Images;
23
24 import org.mmbase.util.logging.Logger;
25 import org.mmbase.util.logging.Logging;
26
27 /**
28  * Produces an url to the image servlet mapping. Using this tag makes
29  * your pages more portable to other system, and hopefully less
30  * sensitive for future changes in how the image servlet works.
31  *
32  * @author Michiel Meeuwissen
33  * @version $Id: ImageTag.java,v 1.73.2.1 2006/10/13 15:56:47 nklasens Exp $
34  */

35
36 public class ImageTag extends FieldTag {
37
38     private static final Logger log = Logging.getLoggerInstance(ImageTag.class);
39
40     public static final int MODE_URL = 0;
41     public static final int MODE_HTML_ATTRIBUTES = 1;
42     public static final int MODE_HTML_IMG = 2;
43
44     public static final String JavaDoc CROP_BEGIN = "begin";
45     public static final String JavaDoc CROP_MIDDLE = "middle";
46     public static final String JavaDoc CROP_END = "end";
47
48
49     private static Boolean JavaDoc makeRelative = null;
50     private static Boolean JavaDoc urlConvert = null;
51
52     /** Holds value of property template. */
53     private Attribute template = Attribute.NULL;
54
55     /** Holds value of property mode. */
56     private Attribute mode = Attribute.NULL;
57
58     /** Holds value of property width. */
59     private Attribute width = Attribute.NULL;
60
61     /** Holds value of property height. */
62     private Attribute height = Attribute.NULL;
63
64     /** Holds value of property crop. */
65     private Attribute crop = Attribute.NULL;
66
67     /** Holds value of property style. */
68     private Attribute style = Attribute.NULL;
69
70     /** Holds value of property clazz. */
71     private Attribute styleClass = Attribute.NULL;
72
73     /** Holds value of property align. */
74     private Attribute align = Attribute.NULL;
75
76     /** Holds value of property border. */
77     private Attribute border = Attribute.NULL;
78
79     /** Holds value of property hspace. */
80     private Attribute hspace = Attribute.NULL;
81
82     /** Holds value of property vspace. */
83     private Attribute vspace = Attribute.NULL;
84
85
86     private Object JavaDoc prevDimension;
87
88     /**
89      * The transformation template
90      */

91     public void setTemplate(String JavaDoc t) throws JspTagException JavaDoc {
92         template = getAttribute(t);
93     }
94
95     public void setMode(String JavaDoc m) throws JspTagException JavaDoc {
96         mode = getAttribute(m);
97     }
98
99     public void setAlign(String JavaDoc align) throws JspTagException JavaDoc {
100         this.align = getAttribute(align);
101     }
102
103
104     public void setBorder(String JavaDoc border) throws JspTagException JavaDoc {
105         this.border = getAttribute(border);
106     }
107
108
109     public void setStyleClass(String JavaDoc styleClass) throws JspTagException JavaDoc {
110         this.styleClass = getAttribute(styleClass);
111     }
112
113
114     public void setCrop(String JavaDoc crop) throws JspTagException JavaDoc {
115         this.crop = getAttribute(crop);
116     }
117
118
119     public void setHeight(String JavaDoc height) throws JspTagException JavaDoc {
120         this.height = getAttribute(height);
121     }
122
123
124     public void setHspace(String JavaDoc hspace) throws JspTagException JavaDoc {
125         this.hspace = getAttribute(hspace);
126     }
127
128     public void setStyle(String JavaDoc style) throws JspTagException JavaDoc {
129         this.style = getAttribute(style);
130     }
131
132
133     public void setVspace(String JavaDoc vspace) throws JspTagException JavaDoc {
134         this.vspace = getAttribute(vspace);
135     }
136
137
138     public void setWidth(String JavaDoc width) throws JspTagException JavaDoc {
139         this.width = getAttribute(width);
140     }
141
142     private int getMode() throws JspTagException JavaDoc {
143         String JavaDoc m = mode.getString(this).toLowerCase();
144         if (m.equals("") || m.equals("url")) {
145             return MODE_URL;
146         } else if (m.equals("attributes")) {
147             return MODE_HTML_ATTRIBUTES;
148         } else if (m.equals("img")) {
149             return MODE_HTML_IMG;
150         } else {
151             throw new JspTagException JavaDoc("Value '" + m + "' not known for 'mode' attribute");
152         }
153     }
154
155
156     private String JavaDoc getCrop() throws JspTagException JavaDoc {
157         String JavaDoc m = crop.getString(this).toLowerCase();
158         if (m.equals("")) {
159             return null;
160         } else if (m.equals("middle")) {
161             return CROP_MIDDLE;
162         } else if (m.equals("begin")) {
163             return CROP_BEGIN;
164         } else if (m.equals("end")) {
165             return CROP_END;
166         } else {
167             throw new JspTagException JavaDoc("Value '" + m + "' not known for 'crop' attribute");
168         }
169     }
170
171     private boolean makeRelative() {
172         if (makeRelative == null) {
173             String JavaDoc setting = pageContext.getServletContext().getInitParameter("mmbase.taglib.url.makerelative");
174             makeRelative = Boolean.valueOf("true".equals(setting));
175         }
176         return makeRelative.booleanValue();
177     }
178
179     protected Node getServletNode(Node node, String JavaDoc template) {
180         if (urlConvert() || "".equals(template)) {
181             return node;
182         } else {
183             // the cached image
184
return node.getFunctionValue("cachednode", new Parameters(Images.CACHE_PARAMETERS).set("template", template)).toNode();
185         }
186
187     }
188
189     private boolean urlConvert() {
190         if (urlConvert == null) {
191             urlConvert = Boolean.valueOf("true".equals(pageContext.getServletContext().getInitParameter("mmbase.taglib.image.urlconvert")));
192         }
193         return urlConvert.booleanValue();
194     }
195
196     public int doStartTag() throws JspTagException JavaDoc {
197         Node originalNode = getNode();
198         if (!originalNode.getNodeManager().hasField("handle")) {
199             throw new JspTagException JavaDoc(
200                 "Found parent node '" + originalNode.getNumber() + "' of type " +
201                 originalNode.getNodeManager().getName() +
202                 " does not have 'handle' field, therefore cannot be a image." +
203                 " Perhaps you have the wrong node, perhaps you'd have to use the 'node' attribute?");
204         }
205
206         helper.useEscaper(false);
207         prevDimension = pageContext.getAttribute("dimension");
208
209         String JavaDoc templateStr = getTemplate(originalNode, template.getString(this), width.getInt(this, 0), height.getInt(this, 0), getCrop());
210         Dimension dim = getDimension(originalNode, templateStr);
211
212         Node node = getServletNode(originalNode, templateStr);
213
214         String JavaDoc servletArgument;
215         if (node == null) {
216             node = originalNode;
217             log.warn("Found null from " + node + " with '" + templateStr + "'");
218             servletArgument = node.getStringValue("number");
219         } else {
220             servletArgument = getServletArgument(node, templateStr);
221         }
222
223         String JavaDoc servletPath = getServletPath(node, servletArgument);
224         String JavaDoc outputValue = getOutputValue(getMode(), originalNode, servletPath, dim);
225
226         if (outputValue != null) {
227             helper.setValue(outputValue);
228         }
229         pageContext.setAttribute("dimension", dim);
230
231         if (getId() != null) {
232             getContextProvider().getContextContainer().register(getId(), helper.getValue());
233         }
234
235         return EVAL_BODY_BUFFERED;
236     }
237
238     public int doEndTag() throws JspTagException JavaDoc {
239         if (prevDimension == null) {
240             pageContext.removeAttribute("dimension");
241         } else {
242             pageContext.setAttribute("dimension", prevDimension);
243         }
244         helper.doEndTag();
245         return super.doEndTag();
246     }
247
248     public String JavaDoc getServletArgument(Node node, String JavaDoc t) {
249         String JavaDoc servletArgument; // can be the node-number or a template (if that is configured to be allowed).
250
if ("".equals(t) || ! urlConvert()) {
251             // the node/image itself
252
servletArgument = node.getStringValue("number");
253         } else {
254             try {
255                 servletArgument = "" + node.getNumber() + "+" + java.net.URLEncoder.encode(t, "UTF-8");
256             } catch (java.io.UnsupportedEncodingException JavaDoc uee) {
257                 // cannot happen 'UTF-8' is supported.
258
servletArgument = "" + node.getNumber() + "+" + t;
259             }
260         }
261         return servletArgument;
262     }
263
264     public String JavaDoc getServletPath(Node node, String JavaDoc servletArgument) throws JspTagException JavaDoc {
265         Function servletPathFunction = getServletFunction(node);
266         Parameters args = getServletArguments(servletArgument, servletPathFunction);
267         fillStandardParameters(args);
268         return servletPathFunction.getFunctionValue( args).toString();
269     }
270
271     public Function getServletFunction(Node node) {
272         Function servletPathFunction = node.getFunction("servletpath");
273         return servletPathFunction;
274     }
275
276     public Parameters getServletArguments(String JavaDoc servletArgument, Function servletPathFunction) {
277         HttpServletRequest JavaDoc req = (HttpServletRequest JavaDoc) pageContext.getRequest();
278         Parameters args = servletPathFunction.createParameters();
279         args.set("context", makeRelative() ? UriParser.makeRelative(new File JavaDoc(req.getServletPath()).getParent(), "/") : req.getContextPath())
280             .set("argument", servletArgument);
281         return args;
282     }
283
284     public String JavaDoc getOutputValue(int mode, Node node, String JavaDoc servletPath, Dimension dim) throws JspTagException JavaDoc {
285         String JavaDoc outputValue = null;
286         switch(mode) {
287         case MODE_URL:
288             outputValue = ((HttpServletResponse JavaDoc) pageContext.getResponse()).encodeURL(servletPath);
289             break;
290         case MODE_HTML_ATTRIBUTES: {
291             String JavaDoc url = ((HttpServletResponse JavaDoc) pageContext.getResponse()).encodeURL(servletPath);
292             if (dim.getHeight() > 0 && dim.getWidth() > 0) {
293                 outputValue = getBaseAttributes(url, dim);
294             } else {
295                 log.warn("Found odd dimension " + dim);
296                 outputValue = getSrcAttribute(url);
297             }
298             break;
299         }
300         case MODE_HTML_IMG: {
301             String JavaDoc url = ((HttpServletResponse JavaDoc) pageContext.getResponse()).encodeURL(servletPath);
302             if (dim.getHeight() > 0 && dim.getWidth() > 0) {
303                 outputValue = "<img " + getBaseAttributes(url, dim) + getAltAttribute(node) + getOtherAttributes() + " />";
304             } else {
305                 log.warn("Found odd dimension " + dim);
306                 outputValue = "<img " + getSrcAttribute(url) + getAltAttribute(node) + getOtherAttributes() + " />";
307             }
308         }
309         }
310         return outputValue;
311     }
312
313     public String JavaDoc getSrcAttribute(String JavaDoc url) throws JspTagException JavaDoc {
314         return " SRC=\"" + url + "\"";
315     }
316
317     public String JavaDoc getBaseAttributes(String JavaDoc url, Dimension dim) throws JspTagException JavaDoc {
318         return getSrcAttribute(url) + " height=\"" + dim.getHeight() + "\" width=\"" + dim.getWidth() + "\"";
319     }
320
321     public String JavaDoc getAltAttribute(Node node) throws JspTagException JavaDoc {
322         String JavaDoc alt = null;
323         if (node.getNodeManager().hasField("alt")) {
324             alt = org.mmbase.util.transformers.Xml.XMLAttributeEscape(node.getStringValue("alt"), '\"');
325         }
326         if ((alt == null || "".equals(alt)) && node.getNodeManager().hasField("title")) {
327             alt = org.mmbase.util.transformers.Xml.XMLAttributeEscape(node.getStringValue("title"), '\"');
328         }
329         if ((alt == null || "".equals(alt)) && node.getNodeManager().hasField("name")) {
330             alt = org.mmbase.util.transformers.Xml.XMLAttributeEscape(node.getStringValue("name"), '\"');
331         }
332         if ((alt == null || "".equals(alt)) && node.getNodeManager().hasField("description")) {
333             alt = org.mmbase.util.transformers.Xml.XMLAttributeEscape(node.getStringValue("description"), '\"');
334         }
335
336
337         return (alt == null ? " alt=\"\"" : " alt=\"" + alt + "\" title=\"" + alt + "\"");
338     }
339
340     protected String JavaDoc getOtherAttributes() throws JspTagException JavaDoc {
341         StringBuffer JavaDoc attributes = new StringBuffer JavaDoc();
342         attributes.append((styleClass != Attribute.NULL) ? (" class=\"" + styleClass.getString(this) + "\"") : "");
343         attributes.append((style != Attribute.NULL) ? (" style=\"" + style.getString(this) + "\"") : "");
344         attributes.append((align != Attribute.NULL) ? (" align=\"" + align.getString(this) + "\"") : "");
345         attributes.append((border != Attribute.NULL) ? (" border=\"" + border.getString(this) + "\"") : "");
346         attributes.append((hspace != Attribute.NULL) ? (" hspace=\"" + hspace.getString(this) + "\"") : "");
347         attributes.append((vspace != Attribute.NULL) ? (" vspace=\"" + vspace.getString(this) + "\"") : "");
348         return attributes.toString();
349     }
350
351     public Dimension getDimension(Node node, String JavaDoc template) {
352         return new LazyDimension(node, template);
353     }
354
355     /**
356      * Get template to manipulate image
357      * @param node - image node
358      * @param t - custom template string
359      * @param widthTemplate - width of image, which is used when custom is not provided
360      * @param heightTemplate - height of image, which is used when custom is not provided
361      * @param cropTemplate - crop the image. values are 'begin', 'middle' and 'end'.
362      * @return template for image
363      */

364     public String JavaDoc getTemplate(Node node, String JavaDoc t, int widthTemplate, int heightTemplate, String JavaDoc cropTemplate) {
365         if (t == null || t.length() == 0) {
366             if ((widthTemplate <= 0) && (heightTemplate <= 0)) {
367                 t = "";
368             } else {
369                 if (cropTemplate != null && cropTemplate.length() != 0) {
370                     t = getCropTemplate(node, widthTemplate, heightTemplate, cropTemplate);
371                 } else {
372                     t = getResizeTemplate(node, widthTemplate, heightTemplate);
373                 }
374             }
375         }
376         boolean asis = "true".equals(pageContext.getServletContext().getInitParameter("mmbase.taglib.image.format.asis"));
377         if (asis) {
378             if (t.length() > 0) {
379                 t = t + "+f(asis)";
380             } else {
381                 t = "f(asis)";
382             }
383         }
384         return t;
385     }
386
387     /**
388      * Returns the crop template string to be used by img servlet
389      * @param node - get template for this node
390      * @param width - template width
391      * @param height - template height
392      * @return the crop template
393      */

394     public String JavaDoc getCropTemplate(Node node, int width, int height, String JavaDoc cropTemplate) {
395         Dimension imageDimension = getDimension(node, null);
396         int imageWidth = imageDimension.getWidth();
397         int imageHeight = imageDimension.getHeight();
398         int newWidth = width > 0 ? width : imageWidth;
399         int newHeight = height > 0 ? height : imageHeight;
400
401         // define orientation of images
402
StringBuffer JavaDoc template = new StringBuffer JavaDoc();
403         float horizontalMultiplier = (float) newWidth / (float) imageWidth;
404         float verticalMultiplier = (float) newHeight / (float) imageHeight;
405         int tempWidth = (int) (imageWidth * verticalMultiplier);
406         int tempHeight = (int) (imageHeight * horizontalMultiplier);
407         int xOffset = 0;
408         int yOffset = 0;
409
410         if (horizontalMultiplier == verticalMultiplier) {
411             // only scaling
412
template.append("s(").append(width).append(")");
413         } else {
414             if (horizontalMultiplier > verticalMultiplier) {
415                 // scale horizontal, crop vertical
416
if (cropTemplate.equals(CROP_END)) {
417                     yOffset = 0;
418                 } else {
419                     if (cropTemplate.equals(CROP_BEGIN)) {
420                         yOffset = (tempHeight - newHeight);
421                     } else {
422                         // CROP_MIDDLE
423
yOffset = (tempHeight - newHeight) / 2;
424                     }
425                 }
426                 template.append("s(").append(newWidth).append(")");
427                 template.append("+part(").append(xOffset).append(",").append(yOffset).append(",");
428                 template.append(xOffset + newWidth).append(",").append(yOffset + newHeight).append(")");
429             } else {
430                 // scale vertical, crop horizontal
431
if (cropTemplate.equals(CROP_END)) {
432                     xOffset = 0;
433                 } else {
434                     if (cropTemplate.equals(CROP_BEGIN)) {
435                         xOffset = (tempWidth - newWidth);
436                     } else {
437                         // CROP_MIDDLE
438
xOffset = (tempWidth - newWidth) / 2;
439                     }
440                 }
441                 template.append("s(x").append(newHeight).append(")");
442                 template.append("+part(").append(xOffset).append(",").append(yOffset).append(",");
443                 template.append(xOffset + newWidth).append(",").append(yOffset + newHeight).append(")");
444             }
445         }
446         log.debug(template.toString());
447         return template.toString();
448     }
449
450     /**
451      * Returns the resize template string to be used by img servlet without cropping
452      * @param node - get template for this node
453      * @param width - template width
454      * @param height - template height
455      * @return the resize template
456      */

457     public String JavaDoc getResizeTemplate(Node node, int width, int height) {
458         Dimension imageDimension = getDimension(node, null);
459         int imageWidth = imageDimension.getWidth();
460         int imageHeight = imageDimension.getHeight();
461         int newWidth = width > 0 ? width : imageWidth;
462         int newHeight = height > 0 ? height : imageHeight;
463
464         // define orientation of images
465
StringBuffer JavaDoc template = new StringBuffer JavaDoc();
466         float horizontalMultiplier = (float) newWidth / (float) imageWidth;
467         float verticalMultiplier = (float) newHeight / (float) imageHeight;
468
469         if (horizontalMultiplier <= verticalMultiplier) {
470             // scale horizontal
471
template.append("+s(").append(newWidth).append(")");
472         }
473         else {
474             // scale vertical
475
template.append("+s(x").append(newHeight).append(")");
476         }
477
478         log.debug(template.toString());
479         return template.toString();
480     }
481
482 }
483
484
Popular Tags