View Javadoc

1   /*
2    * $Id: ImgTag.java 471754 2006-11-06 14:55:09Z husted $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.struts.taglib.html;
22  
23  import org.apache.struts.config.ModuleConfig;
24  import org.apache.struts.taglib.TagUtils;
25  import org.apache.struts.util.MessageResources;
26  import org.apache.struts.util.ModuleUtils;
27  
28  import javax.servlet.http.HttpServletRequest;
29  import javax.servlet.http.HttpServletResponse;
30  import javax.servlet.jsp.JspException;
31  
32  import java.util.Iterator;
33  import java.util.Map;
34  
35  /**
36   * <p>Generate an IMG tag to the specified image URI. </p>
37   *
38   * <p>TODO:</p>
39   *
40   * <ul>
41   *
42   * <li>Make the <strong>alt</strong> and <strong>src</strong> settable from
43   * properties (for i18n)</li>
44   *
45   * </ul>
46   *
47   * @version $Rev: 471754 $
48   */
49  public class ImgTag extends BaseHandlerTag {
50      /**
51       * The message resources for this package.
52       */
53      protected static MessageResources messages =
54          MessageResources.getMessageResources(Constants.Package
55              + ".LocalStrings");
56  
57      // ------------------------------------------------------------- Properties
58  
59      /**
60       * The property to specify where to align the image.
61       */
62      protected String align = null;
63  
64      /**
65       * The border size around the image.
66       */
67      protected String border = null;
68  
69      /**
70       * The image height.
71       */
72      protected String height = null;
73  
74      /**
75       * The horizontal spacing around the image.
76       */
77      protected String hspace = null;
78  
79      /**
80       * The image name for named images.
81       */
82      protected String imageName = null;
83  
84      /**
85       * Server-side image map declaration.
86       */
87      protected String ismap = null;
88  
89      /**
90       * The JSP bean name for query parameters.
91       */
92      protected String name = null;
93  
94      /**
95       * The module-relative path, starting with a slash character, of the image
96       * to be displayed by this rendered tag.
97       */
98      protected String page = null;
99  
100     /**
101      * The message resources key under which we should look up the
102      * <code>page</code> attribute for this generated tag, if any.
103      */
104     protected String pageKey = null;
105 
106     /**
107      * The module-relative action (beginning with a slash) which will be used
108      * as the source for this image.
109      */
110     protected String action = null;
111 
112     /**
113      * The module prefix (beginning with a slash) which will be used to find
114      * the action for this link.
115      */
116     protected String module = null;
117 
118     /**
119      * In situations where an image is dynamically generated (such as to
120      * create a chart graph), this specifies the single-parameter request
121      * parameter name to generate.
122      */
123     protected String paramId = null;
124 
125     /**
126      * The single-parameter JSP bean name.
127      */
128     protected String paramName = null;
129 
130     /**
131      * The single-parameter JSP bean property.
132      */
133     protected String paramProperty = null;
134 
135     /**
136      * The single-parameter JSP bean scope.
137      */
138     protected String paramScope = null;
139 
140     /**
141      * The JSP bean property name for query parameters.
142      */
143     protected String property = null;
144 
145     /**
146      * The scope of the bean specified by the name property, if any.
147      */
148     protected String scope = null;
149 
150     /**
151      * The image source URI.
152      */
153     protected String src = null;
154 
155     /**
156      * The message resources key under which we should look up the
157      * <code>src</code> attribute for this generated tag, if any.
158      */
159     protected String srcKey = null;
160 
161     /**
162      * Client-side image map declaration.
163      */
164     protected String usemap = null;
165 
166     /**
167      * The vertical spacing around the image.
168      */
169     protected String vspace = null;
170 
171     /**
172      * The image width.
173      */
174     protected String width = null;
175     protected boolean useLocalEncoding = false;
176 
177     // ----------------------------------------------------- Constructor
178     public ImgTag() {
179         super();
180         doDisabled = false;
181     }
182 
183     public String getAlign() {
184         return (this.align);
185     }
186 
187     public void setAlign(String align) {
188         this.align = align;
189     }
190 
191     public String getBorder() {
192         return (this.border);
193     }
194 
195     public void setBorder(String border) {
196         this.border = border;
197     }
198 
199     public String getHeight() {
200         return (this.height);
201     }
202 
203     public void setHeight(String height) {
204         this.height = height;
205     }
206 
207     public String getHspace() {
208         return (this.hspace);
209     }
210 
211     public void setHspace(String hspace) {
212         this.hspace = hspace;
213     }
214 
215     public String getImageName() {
216         return (this.imageName);
217     }
218 
219     public void setImageName(String imageName) {
220         this.imageName = imageName;
221     }
222 
223     public String getIsmap() {
224         return (this.ismap);
225     }
226 
227     public void setIsmap(String ismap) {
228         this.ismap = ismap;
229     }
230 
231     public String getName() {
232         return (this.name);
233     }
234 
235     public void setName(String name) {
236         this.name = name;
237     }
238 
239     public String getPage() {
240         return (this.page);
241     }
242 
243     public void setPage(String page) {
244         this.page = page;
245     }
246 
247     public String getPageKey() {
248         return (this.pageKey);
249     }
250 
251     public void setPageKey(String pageKey) {
252         this.pageKey = pageKey;
253     }
254 
255     public String getAction() {
256         return (this.action);
257     }
258 
259     public void setAction(String action) {
260         this.action = action;
261     }
262 
263     public String getModule() {
264         return (this.module);
265     }
266 
267     public void setModule(String module) {
268         this.module = module;
269     }
270 
271     public String getParamId() {
272         return (this.paramId);
273     }
274 
275     public void setParamId(String paramId) {
276         this.paramId = paramId;
277     }
278 
279     public String getParamName() {
280         return (this.paramName);
281     }
282 
283     public void setParamName(String paramName) {
284         this.paramName = paramName;
285     }
286 
287     public String getParamProperty() {
288         return (this.paramProperty);
289     }
290 
291     public void setParamProperty(String paramProperty) {
292         this.paramProperty = paramProperty;
293     }
294 
295     public String getParamScope() {
296         return (this.paramScope);
297     }
298 
299     public void setParamScope(String paramScope) {
300         this.paramScope = paramScope;
301     }
302 
303     public String getProperty() {
304         return (this.property);
305     }
306 
307     public void setProperty(String property) {
308         this.property = property;
309     }
310 
311     public String getScope() {
312         return (this.scope);
313     }
314 
315     public void setScope(String scope) {
316         this.scope = scope;
317     }
318 
319     public String getSrc() {
320         return (this.src);
321     }
322 
323     public void setSrc(String src) {
324         this.src = src;
325     }
326 
327     public String getSrcKey() {
328         return (this.srcKey);
329     }
330 
331     public void setSrcKey(String srcKey) {
332         this.srcKey = srcKey;
333     }
334 
335     public String getUsemap() {
336         return (this.usemap);
337     }
338 
339     public void setUsemap(String usemap) {
340         this.usemap = usemap;
341     }
342 
343     public String getVspace() {
344         return (this.vspace);
345     }
346 
347     public void setVspace(String vspace) {
348         this.vspace = vspace;
349     }
350 
351     public String getWidth() {
352         return (this.width);
353     }
354 
355     public void setWidth(String width) {
356         this.width = width;
357     }
358 
359     public boolean isUseLocalEncoding() {
360         return useLocalEncoding;
361     }
362 
363     public void setUseLocalEncoding(boolean b) {
364         useLocalEncoding = b;
365     }
366 
367     // --------------------------------------------------------- Public Methods
368 
369     /**
370      * Render the beginning of the IMG tag.
371      *
372      * @throws JspException if a JSP exception has occurred
373      */
374     public int doStartTag() throws JspException {
375         // Evaluate the body of this tag
376         return (EVAL_BODY_TAG);
377     }
378 
379     /**
380      * Render the end of the IMG tag.
381      *
382      * @throws JspException if a JSP exception has occurred
383      */
384     public int doEndTag() throws JspException {
385         // Generate the name definition or image element
386         HttpServletResponse response =
387             (HttpServletResponse) pageContext.getResponse();
388         StringBuffer results = new StringBuffer("<img");
389         String tmp = src();
390         String srcurl = url(tmp);
391 
392         if (srcurl != null) {
393             prepareAttribute(results, "src", response.encodeURL(srcurl));
394         }
395 
396         prepareAttribute(results, "name", getImageName());
397         prepareAttribute(results, "height", getHeight());
398         prepareAttribute(results, "width", getWidth());
399         prepareAttribute(results, "align", getAlign());
400         prepareAttribute(results, "border", getBorder());
401         prepareAttribute(results, "hspace", getHspace());
402         prepareAttribute(results, "vspace", getVspace());
403         prepareAttribute(results, "ismap", getIsmap());
404         prepareAttribute(results, "usemap", getUsemap());
405         results.append(prepareStyles());
406         results.append(prepareEventHandlers());
407         prepareOtherAttributes(results);
408         results.append(getElementClose());
409 
410         TagUtils.getInstance().write(pageContext, results.toString());
411 
412         return (EVAL_PAGE);
413     }
414 
415     /**
416      * Release any acquired resources.
417      */
418     public void release() {
419         super.release();
420 
421         border = null;
422         height = null;
423         hspace = null;
424         imageName = null;
425         ismap = null;
426         name = null;
427         page = null;
428         pageKey = null;
429         action = null;
430         paramId = null;
431         paramName = null;
432         paramProperty = null;
433         paramScope = null;
434         property = null;
435         scope = null;
436         src = null;
437         srcKey = null;
438         usemap = null;
439         vspace = null;
440         width = null;
441     }
442 
443     // ------------------------------------------------------ Protected Methods
444 
445     /**
446      * Convenience method to throw a "imgTag.src" exception.
447      *
448      * @throws JspException
449      */
450     private void throwImgTagSrcException()
451         throws JspException {
452         JspException e = new JspException(messages.getMessage("imgTag.src"));
453 
454         TagUtils.getInstance().saveException(pageContext, e);
455         throw e;
456     }
457 
458     /**
459      * Convenience method to test whether this is the default module.
460      *
461      * @param config Our Moduleconfig
462      * @return True if this is the default module or contextRelative is set
463      */
464     private boolean srcDefaultReference(ModuleConfig config) {
465         return (config == null);
466     }
467 
468     /**
469      * Return the base source URL that will be rendered in the
470      * <code>src</code> property for this generated element, or
471      * <code>null</code> if there is no such URL.
472      *
473      * @throws JspException if an error occurs
474      */
475     protected String src() throws JspException {
476         // Deal with a direct context-relative page that has been specified
477         if (this.page != null) {
478             if ((this.src != null) || (this.srcKey != null)
479                 || (this.pageKey != null)) {
480                 throwImgTagSrcException();
481             }
482 
483             ModuleConfig config =
484                 ModuleUtils.getInstance().getModuleConfig(this.module,
485                     (HttpServletRequest) pageContext.getRequest(),
486                     pageContext.getServletContext());
487 
488             HttpServletRequest request =
489                 (HttpServletRequest) pageContext.getRequest();
490             String pageValue = this.page;
491 
492             if (!srcDefaultReference(config)) {
493                 pageValue =
494                     TagUtils.getInstance().pageURL(request, this.page, config);
495             }
496 
497             return (request.getContextPath() + pageValue);
498         }
499 
500         // Deal with an indirect context-relative page that has been specified
501         if (this.pageKey != null) {
502             if ((this.src != null) || (this.srcKey != null)) {
503                 throwImgTagSrcException();
504             }
505 
506             ModuleConfig config =
507                 ModuleUtils.getInstance().getModuleConfig(this.module,
508                     (HttpServletRequest) pageContext.getRequest(),
509                     pageContext.getServletContext());
510 
511             HttpServletRequest request =
512                 (HttpServletRequest) pageContext.getRequest();
513             String pageValue =
514                 TagUtils.getInstance().message(pageContext, getBundle(),
515                     getLocale(), this.pageKey);
516 
517             if (!srcDefaultReference(config)) {
518                 pageValue =
519                     TagUtils.getInstance().pageURL(request, pageValue, config);
520             }
521 
522             return (request.getContextPath() + pageValue);
523         }
524 
525         if (this.action != null) {
526             if ((this.src != null) || (this.srcKey != null)) {
527                 throwImgTagSrcException();
528             }
529 
530             return TagUtils.getInstance().getActionMappingURL(action, module,
531                 pageContext, false);
532         }
533 
534         // Deal with an absolute source that has been specified
535         if (this.src != null) {
536             if (this.srcKey != null) {
537                 throwImgTagSrcException();
538             }
539 
540             return (this.src);
541         }
542 
543         // Deal with an indirect source that has been specified
544         if (this.srcKey == null) {
545             throwImgTagSrcException();
546         }
547 
548         return TagUtils.getInstance().message(pageContext, getBundle(),
549             getLocale(), this.srcKey);
550     }
551 
552     /**
553      * Return the specified src URL, modified as necessary with optional
554      * request parameters.
555      *
556      * @param url The URL to be modified (or null if this url will not be
557      *            used)
558      * @throws JspException if an error occurs preparing the URL
559      */
560     protected String url(String url)
561         throws JspException {
562         if (url == null) {
563             return (url);
564         }
565 
566         String charEncoding = "UTF-8";
567 
568         if (useLocalEncoding) {
569             charEncoding = pageContext.getResponse().getCharacterEncoding();
570         }
571 
572         // Start with an unadorned URL as specified
573         StringBuffer src = new StringBuffer(url);
574 
575         // Append a single-parameter name and value, if requested
576         if ((paramId != null) && (paramName != null)) {
577             if (src.toString().indexOf('?') < 0) {
578                 src.append('?');
579             } else {
580                 src.append("&amp;");
581             }
582 
583             src.append(paramId);
584             src.append('=');
585 
586             Object value =
587                 TagUtils.getInstance().lookup(pageContext, paramName,
588                     paramProperty, paramScope);
589 
590             if (value != null) {
591                 src.append(TagUtils.getInstance().encodeURL(value.toString(),
592                         charEncoding));
593             }
594         }
595 
596         // Just return the URL if there is no bean to look up
597         if ((property != null) && (name == null)) {
598             JspException e =
599                 new JspException(messages.getMessage("getter.name"));
600 
601             TagUtils.getInstance().saveException(pageContext, e);
602             throw e;
603         }
604 
605         if (name == null) {
606             return (src.toString());
607         }
608 
609         // Look up the map we will be using
610         Object mapObject =
611             TagUtils.getInstance().lookup(pageContext, name, property, scope);
612         Map map = null;
613 
614         try {
615             map = (Map) mapObject;
616         } catch (ClassCastException e) {
617             TagUtils.getInstance().saveException(pageContext, e);
618             throw new JspException(messages.getMessage("imgTag.type"));
619         }
620 
621         // Append the required query parameters
622         boolean question = (src.toString().indexOf("?") >= 0);
623         Iterator keys = map.keySet().iterator();
624 
625         while (keys.hasNext()) {
626             String key = (String) keys.next();
627             Object value = map.get(key);
628 
629             if (value == null) {
630                 if (question) {
631                     src.append("&amp;");
632                 } else {
633                     src.append('?');
634                     question = true;
635                 }
636 
637                 src.append(key);
638                 src.append('=');
639 
640                 // Interpret null as "no value specified"
641             } else if (value instanceof String[]) {
642                 String[] values = (String[]) value;
643 
644                 for (int i = 0; i < values.length; i++) {
645                     if (question) {
646                         src.append("&amp;");
647                     } else {
648                         src.append('?');
649                         question = true;
650                     }
651 
652                     src.append(key);
653                     src.append('=');
654                     src.append(TagUtils.getInstance().encodeURL(values[i],
655                             charEncoding));
656                 }
657             } else {
658                 if (question) {
659                     src.append("&amp;");
660                 } else {
661                     src.append('?');
662                     question = true;
663                 }
664 
665                 src.append(key);
666                 src.append('=');
667                 src.append(TagUtils.getInstance().encodeURL(value.toString(),
668                         charEncoding));
669             }
670         }
671 
672         // Return the final result
673         return (src.toString());
674     }
675 }