View Javadoc

    1   /*
    2    * $Id: HtmlTag.java 482895 2006-12-06 05:12:27Z niallp $
    3    *
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
    10   * with the License.  You may obtain a copy of the License at
    11   *
    12   *  http://www.apache.org/licenses/LICENSE-2.0
    13   *
    14   * Unless required by applicable law or agreed to in writing,
    15   * software distributed under the License is distributed on an
    16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    17   * KIND, either express or implied.  See the License for the
    18   * specific language governing permissions and limitations
    19   * under the License.
    20   */
    21  package org.apache.struts.taglib.html;
    22
    23  import org.apache.struts.Globals;
    24  import org.apache.struts.taglib.TagUtils;
    25  import org.apache.struts.util.MessageResources;
    26
    27  import javax.servlet.jsp.JspException;
    28  import javax.servlet.jsp.PageContext;
    29  import javax.servlet.jsp.tagext.TagSupport;
    30
    31  import java.util.Locale;
    32
    33  /**
    34   * Renders an HTML <html> element with appropriate language attributes if
    35   * there is a current Locale available in the user's session.
    36   *
    37   * @version $Rev: 482895 $ $Date: 2005-08-21 19:08:45 -0400 (Sun, 21 Aug 2005)
    38   *          $
    39   */
    40  public class HtmlTag extends TagSupport {
    41      // ------------------------------------------------------------- Properties
    42
    43      /**
    44       * The message resources for this package.
    45       */
    46      protected static MessageResources messages =
    47          MessageResources.getMessageResources(Constants.Package
    48              + ".LocalStrings");
    49
    50      /**
    51       * Are we rendering an xhtml page?
    52       */
    53      protected boolean xhtml = false;
    54
    55      /**
    56       * Are we rendering a lang attribute?
    57       *
    58       * @since Struts 1.2
    59       */
    60      protected boolean lang = false;
    61
    62      public boolean getXhtml() {
    63          return this.xhtml;
    64      }
    65
    66      public void setXhtml(boolean xhtml) {
    67          this.xhtml = xhtml;
    68      }
    69
    70      /**
    71       * Returns true if the tag should render a lang attribute.
    72       *
    73       * @since Struts 1.2
    74       */
    75      public boolean getLang() {
    76          return this.lang;
    77      }
    78
    79      /**
    80       * Sets whether the tag should render a lang attribute.
    81       *
    82       * @since Struts 1.2
    83       */
    84      public void setLang(boolean lang) {
    85          this.lang = lang;
    86      }
    87
    88      /**
    89       * Process the start of this tag.
    90       *
    91       * @throws JspException if a JSP exception has occurred
    92       */
    93      public int doStartTag() throws JspException {
    94          TagUtils.getInstance().write(this.pageContext,
    95              this.renderHtmlStartElement());
    96
    97          return EVAL_BODY_INCLUDE;
    98      }
    99
    100     /**
    101      * Renders an &lt;html&gt; element with appropriate language attributes.
    102      *
    103      * @since Struts 1.2
    104      */
    105     protected String renderHtmlStartElement() {
    106         StringBuffer sb = new StringBuffer("<html");
    107
    108         String language = null;
    109         String country = "";
    110
    111         Locale currentLocale =
    112             TagUtils.getInstance().getUserLocale(pageContext, Globals.LOCALE_KEY);
    113
    114         language = currentLocale.getLanguage();
    115         country = currentLocale.getCountry();
    116
    117         boolean validLanguage = isValidRfc2616(language);
    118         boolean validCountry  = isValidRfc2616(country);
    119
    120         if (this.xhtml) {
    121             this.pageContext.setAttribute(Globals.XHTML_KEY, "true",
    122                 PageContext.PAGE_SCOPE);
    123
    124             sb.append(" xmlns=\"http://www.w3.org/1999/xhtml\"");
    125         }
    126
    127         if ((this.lang || this.xhtml) && validLanguage) {
    128             sb.append(" lang=\"");
    129             sb.append(language);
    130
    131             if (validCountry) {
    132                 sb.append("-");
    133                 sb.append(country);
    134             }
    135
    136             sb.append("\"");
    137         }
    138
    139         if (this.xhtml && validLanguage) {
    140             sb.append(" xml:lang=\"");
    141             sb.append(language);
    142
    143             if (validCountry) {
    144                 sb.append("-");
    145                 sb.append(country);
    146             }
    147
    148             sb.append("\"");
    149         }
    150
    151         sb.append(">");
    152
    153         return sb.toString();
    154     }
    155
    156     /**
    157      * Process the end of this tag.
    158      *
    159      * @throws JspException if a JSP exception has occurred
    160      */
    161     public int doEndTag() throws JspException {
    162         TagUtils.getInstance().write(pageContext, "</html>");
    163
    164         // Evaluate the remainder of this page
    165         return (EVAL_PAGE);
    166     }
    167
    168     /**
    169      * Release any acquired resources.
    170      */
    171     public void release() {
    172         this.xhtml = false;
    173         this.lang = false;
    174     }
    175
    176     /**
    177      * Check whether the value contains valid characters for the
    178      * "Accept-Language" header according to RFC 2616 (section 14.4).
    179      *
    180      * @param value The value to check
    181      * @return <code>true</code> if valid, otherwise <code>false</code>
    182      */
    183     private boolean isValidRfc2616(String value) {
    184         if (value == null || value.length() == 0) {
    185             return false;
    186         }
    187         for (int i = 0; i < value.length(); i++) {
    188             char c = value.charAt(i);
    189
    190             if (!(Character.isLetter(c) || c == '-')) {
    191                 return false;
    192             }
    193         }
    194         return true;
    195     }
    196 }