You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by cr...@locus.apache.org on 2000/11/04 01:46:30 UTC

cvs commit: jakarta-struts/src/share/org/apache/struts/taglib/form ErrorsTag.java LinkTag.java

craigmcc    00/11/03 16:46:30

  Modified:    src/doc  struts-bean.xml struts-form.xml
  Added:       src/share/org/apache/struts/taglib/bean MessageTag.java
               src/share/org/apache/struts/taglib/form ErrorsTag.java
                        LinkTag.java
  Log:
  Migrate the <struts:message> tag to the struts-bean library, and the
  <struts:errors> and <struts:link> tags to the struts-form library (which
  is now more generally focused on HTML presentations, not just forms.
  
  Revision  Changes    Path
  1.7       +96 -0     jakarta-struts/src/doc/struts-bean.xml
  
  Index: struts-bean.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/doc/struts-bean.xml,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- struts-bean.xml	2000/11/03 20:57:44	1.6
  +++ struts-bean.xml	2000/11/04 00:46:29	1.7
  @@ -272,6 +272,102 @@
   
     <tag>
   
  +    <name>message</name>
  +    <summary>
  +    Render an internationalized message string to the response.
  +    </summary>
  +    <tagclass>org.apache.struts.taglib.bean.MessageTag</tagclass>
  +    <bodycontent>empty</bodycontent>
  +    <info>
  +    <p>Retrieves an internationalized message for the specified locale,
  +    using the specified message key, and write it to the output stream.
  +    Up to five parametric replacements (such as "{0}") may be specified.</p>
  +    </info>
  +
  +    <attribute>
  +      <name>arg0</name>
  +      <required>false</required>
  +      <rtexprvalue>true</rtexprvalue>
  +      <info>
  +      <p>First parametric replacement value, if any.</p>
  +      </info>
  +    </attribute>
  +
  +    <attribute>
  +      <name>arg1</name>
  +      <required>false</required>
  +      <rtexprvalue>true</rtexprvalue>
  +      <info>
  +      <p>Second parametric replacement value, if any.</p>
  +      </info>
  +    </attribute>
  +
  +    <attribute>
  +      <name>arg2</name>
  +      <required>false</required>
  +      <rtexprvalue>true</rtexprvalue>
  +      <info>
  +      <p>Third parametric replacement value, if any.</p>
  +      </info>
  +    </attribute>
  +
  +    <attribute>
  +      <name>arg3</name>
  +      <required>false</required>
  +      <rtexprvalue>true</rtexprvalue>
  +      <info>
  +      <p>Fourth parametric replacement value, if any.</p>
  +      </info>
  +    </attribute>
  +
  +    <attribute>
  +      <name>arg4</name>
  +      <required>false</required>
  +      <rtexprvalue>true</rtexprvalue>
  +      <info>
  +      <p>Fifth parametric replacement value, if any.</p>
  +      </info>
  +    </attribute>
  +
  +    <attribute>
  +      <name>bundle</name>
  +      <required>false</required>
  +      <rtexprvalue>true</rtexprvalue>
  +      <info>
  +      <p>The name of the application scope bean under which the
  +      <code>MessageResources</code> object containing our messages
  +      is stored.  If not specified, the default name (the value of
  +      the <code>Action.MESSAGES_KEY</code> constant string) is used.</p>
  +      </info>
  +    </attribute>
  +
  +    <attribute>
  +      <name>key</name>
  +      <required>true</required>
  +      <rtexprvalue>true</rtexprvalue>
  +      <info>
  +      <p>The message key of the requested message, which must have
  +      a corresponding value in the message resources.</p>
  +      </info>
  +    </attribute>
  +
  +    <attribute>
  +      <name>locale</name>
  +      <required>false</required>
  +      <rtexprvalue>true</rtexprvalue>
  +      <info>
  +      <p>The name of the session scope bean under which our currently
  +      selected <code>Locale</code> object is stored.  If not specified,
  +      the default name (the value of the <code>Action.LOCALE_KEY</code>
  +      constant string) is used.</p>
  +      </info>
  +    </attribute>
  +
  +  </tag>
  +
  +
  +  <tag>
  +
       <name>page</name>
       <summary>
       Expose a specified item from the page context as a bean.
  
  
  
  1.3       +166 -1    jakarta-struts/src/doc/struts-form.xml
  
  Index: struts-form.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/doc/struts-form.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- struts-form.xml	2000/11/03 20:57:45	1.2
  +++ struts-form.xml	2000/11/04 00:46:29	1.3
  @@ -18,7 +18,8 @@
     <info>
     <p>
   		This taglib contains tags used to create struts 
  -		input forms.
  +		input forms, as well as other tags generally useful
  +                in the creation of HTML-based user interfaces.
     </p>
     </info>
   
  @@ -654,6 +655,48 @@
   		</attribute>
   	</tag>
   	
  +        <tag>
  +                <name>errors</name>
  +                <summary>
  +                Conditionally display a set of accumulated error messages.
  +                </summary>
  +                <tagclass>org.apache.struts.taglib.form.ErrorsTag</tagclass>
  +                <bodycontent>empty</bodycontent>
  +                <info>
  +                <p>Displays a set of error messages prepared by a business
  +                logic component and stored as an <code>ActionErrors</code>
  +                object, a String, or a String array in request scope.  If
  +                such a bean is not found, nothing will be rendered.</p>
  +
  +                <p>In order to use this tag successfully, you must have
  +                defined an application scope <code>MessageResources</code>
  +                bean under the default attribute name, with at least the
  +                following message keys:</p>
  +                <ul>
  +                <li><strong>errors.header</strong> - Text that will be rendered
  +                before the error messages list.  Typically, this message text
  +                will end with <code>&lt;ul&gt;</code> to start the
  +                error messages list.</li>
  +                <li><strong>errors.footer</strong> - Text that will be rendered
  +                after the error messages list.  Typically, this message text
  +                will begin with <code>&lt;/ul&gt;</code> to end the error
  +                messages list.</li>
  +                </ul>
  +                </info>
  +
  +                <attribute>
  +                  <name>name</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                  Name of the request scope bean under which our error messages
  +                  have been stored.  If not present, the name specified by the
  +                  <code>Action.ERROR_KEY</code> constant string will be used.
  +                  </info>
  +                </attribute>
  +
  +        </tag>
  +
   	<tag>
   		
   		<name>file</name>
  @@ -1089,6 +1132,128 @@
   		</attribute>
   	</tag>
   	
  +
  +        <tag>
  +
  +                <name>link</name>
  +                <summary>Render an HTML hyperlink</summary>
  +                <tagclass>org.apache.struts.taglib.form.LinkTag</tagclass>
  +                <info>
  +
  +                <p>Renders an HTML <code>&lt;a&gt;</code> element as a
  +                hyperlink to the specified URL.  URL rewriting will be
  +                applied automatically, to maintain session state in the
  +                absence of cookies.  The content displayed for this
  +                hyperlink will be taken from the body of this tag.</p>
  +
  +                <p>Normally, the hyperlink you specify with the
  +                <code>forward</code> or <code>href</code> attribute will be
  +                unchanged (other than URL rewriting if necessary).  However,
  +                you can also specify instructions for locating a
  +                <code>Map</code> implementation that defines query parameters
  +                to be added to the hyperlink, in one of two manners:</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
  +                hyperlink.  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>forward</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                  <p>Logical name of a global <code>ActionForward</code> that
  +                  contains the actual content-relative URI of the destination
  +                  of this transfer.  This hyperlink may be dynamically
  +                  modified by the inclusion of query parameters, as described
  +                  in the tag description.  You <strong>must</strong> specify
  +                  either the <code>forward</code> attribute or the
  +                  <code>href</code> attribute.</p>
  +                  </info>
  +                </attribute>
  +
  +                <attribute>
  +                  <name>href</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                  <p>The URL to which this hyperlink will transfer control
  +                  if activated.  This hyperlink may be dynamically modified
  +                  by the inclusion of query parameters, as described in the
  +                  tag description.  You <strong>must</strong> specify
  +                  either the <code>forward</code> attribute or the
  +                  <code>href</code> attribute.</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>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 hyperlink.  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>target</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                  <p>The window target in which the resource requested by this
  +                  hyperlink will be displayed, for example in a framed
  +                  presentation.</p>
  +                  </info>
  +                </attribute>
  +
  +        </tag>
  +
  +
   	<tag>
   		
   		<name>multibox</name>
  
  
  
  1.1                  jakarta-struts/src/share/org/apache/struts/taglib/bean/MessageTag.java
  
  Index: MessageTag.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/MessageTag.java,v 1.1 2000/11/04 00:46:29 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/11/04 00:46:29 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 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 apache@apache.org.
   *
   * 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.bean;
  
  
  import java.io.IOException;
  import java.util.Locale;
  import javax.servlet.jsp.JspException;
  import javax.servlet.jsp.JspWriter;
  import javax.servlet.jsp.PageContext;
  import javax.servlet.jsp.tagext.TagSupport;
  import org.apache.struts.action.Action;
  import org.apache.struts.util.MessageResources;
  
  
  /**
   * Custom tag that retrieves an internationalized messages string (with
   * optional parametric replacement) from the <code>ActionResources</code>
   * object stored as a context attribute by our associated
   * <code>ActionServlet</code> implementation.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/11/04 00:46:29 $
   */
  
  public class MessageTag extends TagSupport {
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * The first optional argument.
       */
      protected String arg0 = null;
  
      public String getArg0() {
  	return (this.arg0);
      }
  
      public void setArg0(String arg0) {
  	this.arg0 = arg0;
      }
  
  
      /**
       * The second optional argument.
       */
      protected String arg1 = null;
  
      public String getArg1() {
  	return (this.arg1);
      }
  
      public void setArg1(String arg1) {
  	this.arg1 = arg1;
      }
  
  
      /**
       * The third optional argument.
       */
      protected String arg2 = null;
  
      public String getArg2() {
  	return (this.arg2);
      }
  
      public void setArg2(String arg2) {
  	this.arg2 = arg2;
      }
  
  
      /**
       * The fourth optional argument.
       */
      protected String arg3 = null;
  
      public String getArg3() {
  	return (this.arg3);
      }
  
      public void setArg3(String arg3) {
  	this.arg3 = arg3;
      }
  
  
      /**
       * The fifth optional argument.
       */
      protected String arg4 = null;
  
      public String getArg4() {
  	return (this.arg4);
      }
  
      public void setArg4(String arg4) {
  	this.arg4 = arg4;
      }
  
  
      /**
       * The servlet context attribute key for our resources.
       */
      protected String bundle = Action.MESSAGES_KEY;
  
      public String getBundle() {
  	return (this.bundle);
      }
  
      public void setBundle(String bundle) {
  	this.bundle = bundle;
      }
  
  
      /**
       * The default Locale for our server.
       */
      protected static final Locale defaultLocale = Locale.getDefault();
  
  
      /**
       * The message key of the message to be retrieved.
       */
      protected String key = null;
  
      public String getKey() {
  	return (this.key);
      }
  
      public void setKey(String key) {
  	this.key = key;
      }
  
  
      /**
       * The session scope key under which our Locale is stored.
       */
      protected String localeKey = Action.LOCALE_KEY;
  
      public String getLocale() {
  	return (this.localeKey);
      }
  
      public void setLocale(String localeKey) {
  	this.localeKey = localeKey;
      }
  
  
      /**
       * The message resources for this package.
       */
      protected static MessageResources messages =
  	MessageResources.getMessageResources
  	("org.apache.struts.taglib.LocalStrings");
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Process the start tag.
       *
       * @exception JspException if a JSP exception has occurred
       */
      public int doStartTag() throws JspException {
  
  	// Acquire the resources object containing our messages
  	MessageResources resources = (MessageResources)
  	    pageContext.getAttribute(bundle, PageContext.APPLICATION_SCOPE);
  	if (resources == null) {
              JspException e = new JspException
  		(messages.getMessage("messageTag.resources", bundle));
              pageContext.setAttribute(Action.EXCEPTION_KEY, e,
                                       PageContext.REQUEST_SCOPE);
              throw e;
          }
  
  	// Calculate the Locale we will be using
  	Locale locale = null;
  	try {
  	    locale = (Locale)
  		pageContext.getAttribute(localeKey, PageContext.SESSION_SCOPE);
  	} catch (IllegalStateException e) {	// Invalidated session
  	    locale = null;
  	}
  	if (locale == null)
  	    locale = defaultLocale;
  
  	// Construct the optional arguments array we will be using
  	Object args[] = new Object[5];
  	args[0] = arg0;
  	args[1] = arg1;
  	args[2] = arg2;
  	args[3] = arg3;
  	args[4] = arg4;
  
  	// Retrieve the message string we are looking for
  	String message = resources.getMessage(locale, key, args);
  	if (message == null) {
  	    JspException e = new JspException
  		(messages.getMessage("messageTag.message", key));
              pageContext.setAttribute(Action.EXCEPTION_KEY, e,
                                       PageContext.REQUEST_SCOPE);
              throw e;
          }
  
  	// Print the retrieved message to our output writer
  	JspWriter writer = pageContext.getOut();
  	try {
  	    writer.print(message);
  	} catch (IOException e) {
              JspException t = new JspException
  		(messages.getMessage("common.io", e.toString()));
              pageContext.setAttribute(Action.EXCEPTION_KEY, e,
                                       PageContext.REQUEST_SCOPE);
              throw t;
  	}
  
  	// Continue processing this page
  	return (SKIP_BODY);
  
      }
  
  
      /**
       * Release any acquired resources.
       */
      public void release() {
  
  	super.release();
  	arg0 = null;
  	arg1 = null;
  	arg2 = null;
  	arg3 = null;
  	arg4 = null;
  	bundle = Action.MESSAGES_KEY;
  	key = null;
  	localeKey = Action.LOCALE_KEY;
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-struts/src/share/org/apache/struts/taglib/form/ErrorsTag.java
  
  Index: ErrorsTag.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/form/ErrorsTag.java,v 1.1 2000/11/04 00:46:30 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/11/04 00:46:30 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 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 apache@apache.org.
   *
   * 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.form;
  
  
  import java.io.IOException;
  import java.util.Iterator;
  import java.util.Locale;
  import javax.servlet.jsp.JspException;
  import javax.servlet.jsp.JspWriter;
  import javax.servlet.jsp.PageContext;
  import javax.servlet.jsp.tagext.TagSupport;
  import org.apache.struts.action.Action;
  import org.apache.struts.action.ActionError;
  import org.apache.struts.action.ActionErrors;
  import org.apache.struts.util.BeanUtils;
  import org.apache.struts.util.ErrorMessages;
  import org.apache.struts.util.MessageResources;
  
  
  /**
   * Custom tag that renders error messages if an appropriate request attribute
   * has been created.  The tag looks for a request attribute with a reserved
   * key, and assumes that it is either a String, or a String array, containing
   * message keys to be looked up in the application's MessageResources.
   * <p>
   * The following optional message keys will be utilized if corresponding
   * messages exist for them in the application resources:
   * <ul>
   * <li><b>errors.header</b> - If present, the corresponding message will be
   *     rendered prior to the individual list of error messages.
   * <li><b>errors.footer</b> - If present, the corresponding message will be
   *     rendered following the individual list of error messages.
   * <li><b>
   * </ul>
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/11/04 00:46:30 $
   */
  
  public class ErrorsTag extends TagSupport {
  
  
      // ----------------------------------------------------------- Properties
  
  
      /**
       * The default locale on our server.
       */
      protected static Locale defaultLocale = Locale.getDefault();
  
  
      /**
       * Name of the request scope attribute containing our error messages,
       * if any.
       */
      protected String name = Action.ERROR_KEY;
  
      public String getName() {
  	return (this.name);
      }
  
      public void setName(String name) {
  	this.name = name;
      }
  
  
      // ------------------------------------------------------- Public Methods
  
  
      /**
       * Render the specified error messages if there are any.
       *
       * @exception JspException if a JSP exception has occurred
       */
      public int doStartTag() throws JspException {
  
  	// Were any error messages specified?
  	ActionErrors errors = new ActionErrors();
  	try {
  	    Object value = pageContext.getAttribute
                  (name, PageContext.REQUEST_SCOPE);
  	    if (value == null) {
  		;
  	    } else if (value instanceof String) {
  		errors.add(ActionErrors.GLOBAL_ERROR,
                             new ActionError((String) value));
  	    } else if (value instanceof String[]) {
                  String keys[] = (String[]) value;
                  for (int i = 0; i < keys.length; i++)
                      errors.add(ActionErrors.GLOBAL_ERROR,
                                 new ActionError(keys[i]));
              } else if (value instanceof ErrorMessages) {
  		String keys[] = ((ErrorMessages) value).getErrors();
                  if (keys == null)
                      keys = new String[0];
                  for (int i = 0; i < keys.length; i++)
                      errors.add(ActionErrors.GLOBAL_ERROR,
                                 new ActionError(keys[i]));
              } else if (value instanceof ActionErrors) {
                  errors = (ActionErrors) value;
  	    }
          } catch (Exception e) {
              ;
  	}
          if (errors.empty())
  	    return (EVAL_BODY_INCLUDE);
  
  	// Render the error messages appropriately
  	Locale locale = null;
  	try {
  	    locale = (Locale) pageContext.getAttribute
  		(Action.LOCALE_KEY, PageContext.SESSION_SCOPE);
  	} catch (IllegalStateException e) {	// Invalidated session
  	    locale = null;
  	}
  	if (locale == null)
  	    locale = defaultLocale;
  	MessageResources messages = (MessageResources)
  	  pageContext.getAttribute(Action.MESSAGES_KEY,
  				   PageContext.APPLICATION_SCOPE);
  	String message = null;
  	StringBuffer results = new StringBuffer();
          if (messages != null)
              message = messages.getMessage(locale, "errors.header");
          else
              message = null;
  	if (message != null) {
  	    results.append(message);
  	    results.append("\r\n");
  	}
          Iterator reports = errors.get();
          while (reports.hasNext()) {
              ActionError report = (ActionError) reports.next();
              if (messages != null)
                  message =
                      messages.getMessage(locale,
                                          report.getKey(), report.getValues());
              else
                  message = null;
  	    if (message != null) {
  		results.append(message);
  		results.append("\r\n");
  	    }
  	}
          if (messages != null)
              message = messages.getMessage(locale, "errors.footer");
          else
              message = null;
  	if (message != null) {
  	    results.append(message);
  	    results.append("\r\n");
  	}
  
  	// Print the results to our output writer
  	JspWriter writer = pageContext.getOut();
  	try {
  	    writer.print(results.toString());
  	} catch (IOException e) {
  	    throw new JspException(e.toString());
  	}
  
  	// Continue processing this page
  	return (EVAL_BODY_INCLUDE);
  
      }
  
  
      /**
       * Release any acquired resources.
       */
      public void release() {
  
  	super.release();
  	name = Action.ERROR_KEY;
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-struts/src/share/org/apache/struts/taglib/form/LinkTag.java
  
  Index: LinkTag.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/form/LinkTag.java,v 1.1 2000/11/04 00:46:30 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/11/04 00:46:30 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 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 apache@apache.org.
   *
   * 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.form;
  
  
  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 javax.servlet.jsp.tagext.TagSupport;
  import org.apache.struts.action.Action;
  import org.apache.struts.action.ActionForward;
  import org.apache.struts.action.ActionForwards;
  import org.apache.struts.util.BeanUtils;
  import org.apache.struts.util.MessageResources;
  
  
  /**
   * Generate a URL-encoded hyperlink to the specified URI.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/11/04 00:46:30 $
   */
  
  public class LinkTag extends TagSupport {
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * The logical forward name from which to retrieve the hyperlink URI.
       */
      protected String forward = null;
  
      public String getForward() {
  	return (this.forward);
      }
  
      public void setForward(String forward) {
  	this.forward = forward;
      }
  
  
      /**
       * The hyperlink URI.
       */
      protected String href = null;
  
      public String getHref() {
  	return (this.href);
      }
  
      public void setHref(String href) {
  	this.href = href;
      }
  
  
      /**
       * The message resources for this package.
       */
      protected static MessageResources messages =
  	MessageResources.getMessageResources
  	("org.apache.struts.taglib.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;
      }
  
  
      /**
       * 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 window target.
       */
      protected String target = null;
  
      public String getTarget() {
  	return (this.target);
      }
  
      public void setTarget(String target) {
  	this.target = target;
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Render the beginning of the hyperlink.
       *
       * @exception JspException if a JSP exception has occurred
       */
      public int doStartTag() throws JspException {
  
  	// Validate our attributes
  	if ((forward == null) && (href == null)) {
  	    JspException e = new JspException
  		(messages.getMessage("linkTag.destination"));
              pageContext.setAttribute(Action.EXCEPTION_KEY, e,
                                       PageContext.REQUEST_SCOPE);
              throw e;
          } else if ((forward != null) && (href != null)) {
  	    JspException e = new JspException
  		(messages.getMessage("linkTag.destination"));
              pageContext.setAttribute(Action.EXCEPTION_KEY, e,
                                       PageContext.REQUEST_SCOPE);
              throw e;
          }
  
  	// Generate the hyperlink start element
  	HttpServletResponse response =
  	  (HttpServletResponse) pageContext.getResponse();
  	StringBuffer results = new StringBuffer("<a href=\"");
  	results.append(response.encodeURL(BeanUtils.filter(hyperlink())));
  	results.append("\"");
  	if (target != null) {
  	    results.append(" target=\"");
  	    results.append(target);
  	    results.append("\"");
  	}
  	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()));
  	}
  
  	// Evaluate the body of this tag
  	return (EVAL_BODY_INCLUDE);
  
      }
  
  
  
      /**
       * Render the end of the hyperlink.
       *
       * @exception JspException if a JSP exception has occurred
       */
      public int doEndTag() throws JspException {
  
  
  	// Print the ending element to our output writer
  	JspWriter writer = pageContext.getOut();
  	try {
  	    writer.print("</a>");
  	} catch (IOException e) {
  	    throw new JspException
  	        (messages.getMessage("common.io", e.toString()));
  	}
  
  	return (EVAL_PAGE);
  
      }
  
  
      /**
       * Release any acquired resources.
       */
      public void release() {
  
  	super.release();
  	forward = null;
  	href = null;
  	name = null;
  	property = null;
          scope = null;
  	target = null;
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Return the specified hyperlink, modified as necessary with optional
       * request parameters.
       *
       * @exception JspException if an error occurs preparing the hyperlink
       */
      protected String hyperlink() throws JspException {
  
  	String href = this.href;
  
  	// If "forward" was specified, compute the "href" to forward to
  	if (forward != null) {
  	    ActionForwards forwards = (ActionForwards)
  		pageContext.getAttribute(Action.FORWARDS_KEY,
  					 PageContext.APPLICATION_SCOPE);
  	    if (forwards == null)
  		throw new JspException
  		    (messages.getMessage("linkTag.forwards"));
  	    ActionForward forward = forwards.findForward(this.forward);
  	    if (forward == null)
  		throw new JspException
  		    (messages.getMessage("linkTag.forward"));
  	    HttpServletRequest request =
  		(HttpServletRequest) pageContext.getRequest();
  	    href = request.getContextPath() + forward.getPath();
  	}
  
  	// Just return the "href" attribute 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 (href);
  
  	// Look up the map we will be using
  	Object bean = BeanUtils.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("linkTag.type"));
  	    }
  	} else {
  	    try {
  		map = (Map) BeanUtils.getPropertyValue(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("linkTag.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(href);
  	boolean question = (href.indexOf("?") >= 0);
  	Iterator keys = map.keySet().iterator();
  	while (keys.hasNext()) {
  	    String key = (String) keys.next();
  	    Object value = map.get(key);
  	    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());
  
      }
  
  
  }