craigmcc 01/01/27 19:48:03 Modified: . build.xml src/doc struts-html.xml src/share/org/apache/struts/taglib/html LocalStrings.properties web/example index.jsp Added: src/share/org/apache/struts/taglib/html ImgTag.java Log: Add a <html:img> tag that can render an HTML <img> tag, with the abilities to dynamically modify the URLs specified by the "src" and "lowsrc" attributes in the same manner that <html:link> can. Submitted by: Michael Westbay <[EMAIL PROTECTED]> Revision Changes Path 1.34 +2 -0 jakarta-struts/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/jakarta-struts/build.xml,v retrieving revision 1.33 retrieving revision 1.34 diff -u -r1.33 -r1.34 --- build.xml 2001/01/24 21:57:26 1.33 +++ build.xml 2001/01/28 03:48:02 1.34 @@ -57,6 +57,8 @@ <copy todir="${build.home}/example"> <fileset dir="web/example"/> </copy> + <copy tofile="${build.home}/example/struts-power.gif" + file="src/doc/images/struts-power.gif"/> </target> <!-- BUILD: Create directories and copy files for test application --> 1.5 +378 -0 jakarta-struts/src/doc/struts-html.xml Index: struts-html.xml =================================================================== RCS file: /home/cvs/jakarta-struts/src/doc/struts-html.xml,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- struts-html.xml 2001/01/27 23:21:07 1.4 +++ struts-html.xml 2001/01/28 03:48:02 1.5 @@ -1391,6 +1391,384 @@ </tag> + <tag> + + <name>img</name> + <summary>Render an HTML img tag</summary> + <tagclass>org.apache.struts.taglib.html.ImgTag</tagclass> + <bodycontent>empty</bodycontent> + <info> + + <p>Renders an HTML <code><img></code> element with + the image at the specified URL. Like the link tag, URL + rewriting will be applied automatically to the value + specified in <code>src</code>, to maintain session state + in the absence of cookies. This will allow dynamic + generation of an image where the content displayed for this + image will be taken from the attributes of this tag.</p> + + <p>The base URL for this image is calculated based on + the value specified in <code>src</code>.</p> + + <p>Normally, the <code>src</code> you specify will be left + unchanged (other than URL rewriting if necessary). However, + there are two ways you can append one or more dynamically + defined query parameters to the <code>src</code> URL -- + specify a single parameter with the <code>paramId</code> + attribute (at its associated attributes to select the value), + or specify the <code>name</code> (and optional + <code>property</code>) attributes to select a + <code>java.util.Map</code> bean that contains one or more + parameter ids and corresponding values.</p> + + <p>To specify a single parameter, use the <code>paramId</code> + attribute to define the name of the request parameter to be + submitted. To specify the corresponding value, use one of the + following approaches:</p> + <ul> + <li><em>Specify only the <code>paramName</code> attribute</em> + - The named JSP bean (optionally scoped by the value of the + <code>paramScope</code> attribute) must identify a value + that can be converted to a String.</li> + <li><em>Specify both the <code>paramName</code> and + <code>paramProperty</code> attributes</em> - The specified + property getter will be called on the JSP bean identified + by the <code>paramName</code> (and optional + <code>paramScope</code>) attributes, in order to select + a value that can be converted to a String.</li> + </ul> + + <p>If you prefer to specify a <code>java.util.Map</code> that + contains all of the request parameters to be added to the + hyperlink, use one of the following techniques:</p> + <ul> + <li><em>Specify only the <code>name</code> attribute</em> - + The named JSP bean (optionally scoped by the value of + the <code>scope</code> attribute) must identify a + <code>java.util.Map</code> containing the parameters.</li> + <li><em>Specify both <code>name</code> and + <code>property</code> attributes</em> - The specified + property getter method will be called on the bean + identified by the <code>name</code> (and optional + <code>scope</code>) attributes, in order to return the + <code>java.util.Map</code> containing the parameters.</li> + </ul> + + <p>As the <code>Map</code> is processed, the keys are assumed + to be the names of query parameters to be appended to the + <code>src</code> URL. The value associated with each key + must be either a String or a String array representing the + parameter value(s). If a String array is specified, more than + one value for the same query parameter name will be + created.</p> + + </info> + + <attribute> + <name>accesskey</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The keyboard character used to move focus immediately + to this element.</p> + </info> + </attribute> + + <attribute> + <name>align</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>Where the image is aligned to. Can be one of the + following attributes:</p> + <ul> + <li>left - left justify, wrapping text on right</li> + <li>right -right justify, wrapping test on left</li> + <li>top - aligns the image with the top of the text on + the same row</li> + <li>middle - aligns the image's vertical center with the + text base line</li> + <li>bottom - aligns the image with the botton of the + text's base line</li> + <li>texttop - aligns the image's top with that of the + text font on the same line</li> + <li>absmiddle - aligns the image's vertical center with the + absolute center of the text</li> + <li>absbottom - aligns the image with the absolute botton + of the text font on the same row</li> + </ul> + </info> + </attribute> + + <attribute> + <name>alt</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>And alternative text to be displayed in browsers that + don't support graphics. Also used often as type of + context help over images.</p> + </info> + </attribute> + + <attribute> + <name>border</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The width of the border surrounding the image.</p> + </info> + </attribute> + + <attribute> + <name>imageName</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The scriptable name to be defined within this page, so + that you can reference it with intra-page scripts. In other + words, the value specified here will render a "name" element + in the generated image tag.</p> + </info> + </attribute> + + <attribute> + <name>height</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The height of the image being displayed. This parameter + is very nice to specificy (along with <code>width</code>) + to help the browser render the page faster.</p> + </info> + </attribute> + + <attribute> + <name>hspace</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The amount of horizontal spacing between the icon and + the text. The text may be in the same paragraph, or + be wrapped around the image.</p> + </info> + </attribute> + + <attribute> + <name>imageName</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The scriptable name to be defined within this page, so + that you can reference it with intra-page scripts. In other + words, the value specified here will render a "name" element + in the generated image tag.</p> + </info> + </attribute> + + <attribute> + <name>ismap</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The name of the server-side map that this image belongs + to.</p> + </info> + </attribute> + + <attribute> + <name>lowsrc</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>An image for people with low resoution graphics cards. + Is this even necessary any more?</p> + </info> + </attribute> + + <attribute> + <name>name</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The name of a JSP bean that contains a <code>Map</code> + representing the query parameters (if <code>property</code> + is not specified), or a JSP bean whose property getter is + called to return a <code>Map</code> (if <code>property</code> + is specified).</p> + </info> + </attribute> + + <attribute> + <name>src</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The URL to which this image will be transferred from + This image may be dynamically modified + by the inclusion of query parameters, as described in the + tag description. You <strong>must</strong> specify + the <code>src</code> attribute.</p> + </info> + </attribute> + + <attribute> + <name>usemap</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The name of the map as defined within this page for + mapping hot-spot areas of this image.</p> + </info> + </attribute> + + <attribute> + <name>vspace</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The amount of vertical spacing between the icon and + the text, above and below.</p> + </info> + </attribute> + + <attribute> + <name>width</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The width of the image being displayed. This parameter + is very nice to specificy (along with <code>height</code>) + to help the browser render the page faster.</p> + </info> + </attribute> + + <attribute> + <name>onkeydown</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>JavaScript event handler that is executed when + this element receives a key down event.</p> + </info> + </attribute> + + <attribute> + <name>onkeypress</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>JavaScript event handler that is executed when + this element receives a key press event.</p> + </info> + </attribute> + + <attribute> + <name>onkeyup</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>JavaScript event handler that is executed when + this element receives a key up event.</p> + </info> + </attribute> + + <attribute> + <name>paramId</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The name of the request parameter that will be dynamically + added to the generated src URL. The corresponding value is + defined by the <code>paramName</code> and (optional) + <code>paramProperty</code> attributes, optionally scoped by + the <code>paramScope</code> attributel</p> + </info> + </attribute> + + <attribute> + <name>paramName</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The name of a JSP bean that is a String containing the + value for the request parameter named by <code>paramId</code> + (if <code>paramProperty</code> is not specified), or a JSP + bean whose property getter is called to return a String + (if <code>paramProperty</code> is specified). The JSP bean + is constrained to the bean scope specified by the + <code>paramScope</code> property, if it is specified.</p> + </info> + </attribute> + + <attribute> + <name>paramProperty</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The name of a property of the bean specified by the + <code>paramName</code> attribute, whose return value must + be a String containing the value of the request parameter + (named by the <code>paramId</code> attribute) that will be + dynamically added to this src URL.</p> + </info> + </attribute> + + <attribute> + <name>paramScope</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The scope within which to search for the bean specified + by the <code>paramName</code> attribute. If not specified, + all scopes are searched.</p> + </info> + </attribute> + + <attribute> + <name>property</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The name of a property of the bean specified by the + <code>name</code> attribute, whose return value must be + a <code>java.util.Map</code> containing the query parameters + to be added to the src URL. You <strong>must</strong> + specify the <code>name</code> attribute if you specify + this attribute.</p> + </info> + </attribute> + + <attribute> + <name>scope</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>The scope within which to search for the bean specified + by the <code>name</code> attribute. If not specified, all + scopes are searched.</p> + </info> + </attribute> + + <attribute> + <name>style</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>CSS styles to be applied to this element.</p> + </info> + </attribute> + + <attribute> + <name>styleClass</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + <info> + <p>CSS stylesheet class to be applied to this element.</p> + </info> + </attribute> + + </tag> <tag> 1.3 +1 -0 jakarta-struts/src/share/org/apache/struts/taglib/html/LocalStrings.properties Index: LocalStrings.properties =================================================================== RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/LocalStrings.properties,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LocalStrings.properties 2001/01/27 23:21:08 1.2 +++ LocalStrings.properties 2001/01/28 03:48:03 1.3 @@ -14,6 +14,7 @@ getter.name=You must specify a name attribute if the property attribute is present getter.property=Property {0} returned a null value getter.result=Getter for property {0} threw exception: {1} +imgTag.type=Object must be of type Map includeTag.include=Error including page {0}: {1} includeTag.lookup=Cannot find global forward named {0} iterateTag.iterator=Cannot create iterator for {0} 1.1 jakarta-struts/src/share/org/apache/struts/taglib/html/ImgTag.java Index: ImgTag.java =================================================================== /* * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/ImgTag.java,v 1.1 2001/01/28 03:48:03 craigmcc Exp $ * $Revision: 1.1 $ * $Date: 2001/01/28 03:48:03 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * */ package org.apache.struts.taglib.html; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.net.URLEncoder; import java.util.Iterator; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import org.apache.struts.action.Action; import org.apache.struts.util.BeanUtils; import org.apache.struts.util.MessageResources; import org.apache.struts.util.PropertyUtils; import org.apache.struts.util.RequestUtils; /** * Generate an IMG tag to the specified image URI. * <p> * TODO: * <ul> * <li>make the <strong>alt</strong>, <strong>src</strong>, and * <strong>lowsrc</strong> settable from properties (for i18n)</li> * <li>handle <strong>onLoad</strong>, <strong>onAbort</strong>, and * <strong>onError</strong> events (my JavaScript book is very old, * there may be more unsupported events in the past couple of IE * versions) * </ul> * * @author Michael Westbay * @author Craig McClanahan * @version $Revision: 1.1 $ */ public class ImgTag extends BaseHandlerTag { // ------------------------------------------------------------- Properties /** * The property to specify where to align the image. */ protected String align = null; public String getAlign() { return (this.align); } public void setAlign(String align) { this.align = align; } /** * The alternate text to display for the image. This is used for * text based browsers and/or as a "tool-tip" for the image. */ protected String alt = null; public String getAlt() { return (this.alt); } public void setAlt(String alt) { this.alt = alt; } /** * The border size around the image. */ protected String border = null; public String getBorder() { return (this.border); } public void setBorder(String border) { this.border = border; } /** * The image height. */ protected String height = null; public String getHeight() { return (this.height); } public void setHeight(String height) { this.height = height; } /** * The horizontal spacing around the image. */ protected String hspace = null; public String getHspace() { return (this.hspace); } public void setHspace(String hspace) { this.hspace = hspace; } /** * The image name for named images. */ protected String imageName = null; public String getImageName() { return (this.imageName); } public void setImageName(String imageName) { this.imageName = imageName; } /** * Server-side image map declaration. */ protected String ismap = null; public String getIsmap() { return (this.ismap); } public void setIsmap(String ismap) { this.ismap = ismap; } /** * The low resolution image source URI. */ protected String lowsrc = null; public String getlowSrc() { return (this.lowsrc); } public void setLowsrc(String lowsrc) { this.lowsrc = lowsrc; } /** * The message resources for this package. */ protected static MessageResources messages = MessageResources.getMessageResources(Constants.Package + ".LocalStrings"); /** * The JSP bean name for query parameters. */ protected String name = null; public String getName() { return (this.name); } public void setName(String name) { this.name = name; } /** * In situations where an image is dynamically generated (such as to create * a chart graph), this specifies the single-parameter request parameter * name to generate. */ protected String paramId = null; public String getParamId() { return (this.paramId); } public void setParamId(String paramId) { this.paramId = paramId; } /** * The single-parameter JSP bean name. */ protected String paramName = null; public String getParamName() { return (this.paramName); } public void setParamName(String paramName) { this.paramName = paramName; } /** * The single-parameter JSP bean property. */ protected String paramProperty = null; public String getParamProperty() { return (this.paramProperty); } public void setParamProperty(String paramProperty) { this.paramProperty = paramProperty; } /** * The single-parameter JSP bean scope. */ protected String paramScope = null; public String getParamScope() { return (this.paramScope); } public void setParamScope(String paramScope) { this.paramScope = paramScope; } /** * The JSP bean property name for query parameters. */ protected String property = null; public String getProperty() { return (this.property); } public void setProperty(String property) { this.property = property; } /** * The scope of the bean specified by the name property, if any. */ protected String scope = null; public String getScope() { return (this.scope); } public void setScope(String scope) { this.scope = scope; } /** * The image source URI. */ protected String src = null; public String getSrc() { return (this.src); } public void setSrc(String src) { this.src = src; } /** * Client-side image map declaration. */ protected String usemap = null; public String getUsemap() { return (this.usemap); } public void setUsemap(String Usemap) { this.usemap = usemap; } /** * The vertical spacing around the image. */ protected String vspace = null; public String getVspace() { return (this.vspace); } public void setVspace(String vspace) { this.vspace = vspace; } /** * The image width. */ protected String width = null; public String getWidth() { return (this.width); } public void setWidth(String width) { this.width = width; } // --------------------------------------------------------- Public Methods /** * Render the beginning of the IMG tag. * * @exception JspException if a JSP exception has occurred */ public int doStartTag() throws JspException { // Evaluate the body of this tag return (EVAL_BODY_TAG); } /** * Render the end of the IMG tag. * * @exception JspException if a JSP exception has occurred */ public int doEndTag() throws JspException { // Generate the name definition or image element HttpServletResponse response = (HttpServletResponse) pageContext.getResponse(); StringBuffer results = new StringBuffer("<img"); String srcurl = url(this.src); String lowsrcurl = url(this.lowsrc); if (srcurl != null) { results.append(" src=\""); results.append(response.encodeURL(BeanUtils.filter(srcurl))); results.append("\""); } if (lowsrc != null) { results.append(" lowsrc=\""); results.append(response.encodeURL(BeanUtils.filter(lowsrcurl))); results.append("\""); } if (alt != null) { results.append(" alt=\""); results.append(alt); results.append("\""); } if (imageName != null) { results.append(" name=\""); results.append(imageName); results.append("\""); } if (height != null) { results.append(" height=\""); results.append(height); results.append("\""); } if (width != null) { results.append(" width=\""); results.append(width); results.append("\""); } if (align != null) { results.append(" align=\""); results.append(align); results.append("\""); } if (border != null) { results.append(" border=\""); results.append(border); results.append("\""); } if (hspace != null) { results.append(" hspace=\""); results.append(hspace); results.append("\""); } if (vspace != null) { results.append(" vspace=\""); results.append(vspace); results.append("\""); } if (ismap != null) { results.append(" ismap=\""); results.append(ismap); results.append("\""); } if (usemap != null) { results.append(" usemap=\""); results.append(usemap); results.append("\""); } results.append(prepareStyles()); results.append(prepareEventHandlers()); results.append(">"); // Print this element to our output writer JspWriter writer = pageContext.getOut(); try { writer.print(results.toString()); } catch (IOException e) { pageContext.setAttribute(Action.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE); throw new JspException (messages.getMessage("common.io", e.toString())); } return (EVAL_PAGE); } /** * Release any acquired resources. */ public void release() { super.release(); alt = null; border = null; height = null; hspace = null; imageName = null; ismap = null; lowsrc = null; name = null; paramId = null; paramName = null; paramProperty = null; paramScope = null; property = null; scope = null; src = null; usemap = null; vspace = null; width = null; } // ------------------------------------------------------ Protected Methods /** * Return the specified src URL, modified as necessary with optional * request parameters. * <p> * This is based on the way a * <a href="LinkTag.html#hyperlink">hyperlink</a> * is generated for the <a href="LinkTag.html">LinkTag</a>. * * @param url The URL to be modified (or null if this url will not be used) * * @exception JspException if an error occurs preparing the URL * @see LinkTag#hyperlink */ protected String url(String url) throws JspException { if (url == null) return (url); // Start with an unadorned URL as specified String src = url; // Append a single-parameter name and value, if requested if ((paramId != null) && (paramName != null)) { if (src.indexOf('?') < 0) src += '?'; else src += '&'; src += paramId; src += '='; Object bean = RequestUtils.lookup(pageContext, paramName, paramScope); if (bean != null) { if (paramProperty == null) src += bean.toString(); else { try { Object value = PropertyUtils.getProperty(bean, paramProperty); if (value != null) src += value.toString(); } catch (IllegalAccessException e) { pageContext.setAttribute(Action.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE); throw new JspException (messages.getMessage("getter.access", paramProperty, paramName)); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); pageContext.setAttribute(Action.EXCEPTION_KEY, t, PageContext.REQUEST_SCOPE); throw new JspException (messages.getMessage("getter.result", paramProperty, t.toString())); } catch (NoSuchMethodException e) { pageContext.setAttribute(Action.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE); throw new JspException (messages.getMessage("getter.method", paramProperty, paramName)); } } } } // Just return the URL if there is no bean to look up if ((property != null) && (name == null)) { JspException e = new JspException (messages.getMessage("getter.name")); pageContext.setAttribute(Action.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE); throw e; } if (name == null) return (src); // Look up the map we will be using Object bean = RequestUtils.lookup(pageContext, name, scope); if (bean == null) { JspException e = new JspException (messages.getMessage("getter.bean", name)); pageContext.setAttribute(Action.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE); throw e; } Map map = null; if (property == null) { try { map = (Map) bean; } catch (ClassCastException e) { pageContext.setAttribute(Action.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE); throw new JspException (messages.getMessage("imgTag.type")); } } else { try { map = (Map) PropertyUtils.getProperty(bean, property); if (map == null) { JspException e = new JspException (messages.getMessage("getter.property", property)); pageContext.setAttribute(Action.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE); throw e; } } catch (IllegalAccessException e) { pageContext.setAttribute(Action.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE); throw new JspException (messages.getMessage("getter.access", property, name)); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); pageContext.setAttribute(Action.EXCEPTION_KEY, t, PageContext.REQUEST_SCOPE); throw new JspException (messages.getMessage("getter.result", property, t.toString())); } catch (ClassCastException e) { pageContext.setAttribute(Action.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE); throw new JspException (messages.getMessage("imgTag.type")); } catch (NoSuchMethodException e) { pageContext.setAttribute(Action.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE); throw new JspException (messages.getMessage("getter.method", property, name)); } } // Append the required query parameters StringBuffer sb = new StringBuffer(src); boolean question = (src.indexOf("?") >= 0); Iterator keys = map.keySet().iterator(); while (keys.hasNext()) { String key = (String) keys.next(); Object value = map.get(key); if (value == null) { if (question) sb.append('&'); else { sb.append('?'); question = true; } sb.append(key); sb.append('='); // Interpret null as "no value specified" } else if (value instanceof String[]) { String values[] = (String[]) value; for (int i = 0; i < values.length; i++) { if (question) sb.append('&'); else { sb.append('?'); question = true; } sb.append(key); sb.append('='); sb.append(URLEncoder.encode(values[i])); } } else { if (question) sb.append('&'); else { sb.append('?'); question = true; } sb.append(key); sb.append('='); sb.append(URLEncoder.encode(value.toString())); } } // Return the final result return (sb.toString()); } } 1.14 +2 -0 jakarta-struts/web/example/index.jsp Index: index.jsp =================================================================== RCS file: /home/cvs/jakarta-struts/web/example/index.jsp,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- index.jsp 2001/01/12 03:04:59 1.13 +++ index.jsp 2001/01/28 03:48:03 1.14 @@ -34,5 +34,7 @@ <p> </p> <p><a target="_blank" href="tour.htm"><font size="1">A Walking Tour of the Example Application</font></a></p> +<html:img src="struts-power.gif" alt="Powered by Struts"/> + </body> </html:html>