View Javadoc

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