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