View Javadoc

    1   /*
    2    * $Id: Text.java 497654 2007-01-19 00:21:57Z rgielen $
    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.struts2.components;
    22
    23  import java.io.IOException;
    24  import java.io.Writer;
    25  import java.util.ArrayList;
    26  import java.util.Collections;
    27  import java.util.Iterator;
    28  import java.util.List;
    29
    30  import org.apache.commons.logging.Log;
    31  import org.apache.commons.logging.LogFactory;
    32  import org.apache.struts2.views.annotations.StrutsTag;
    33  import org.apache.struts2.views.annotations.StrutsTagAttribute;
    34
    35  import com.opensymphony.xwork2.util.TextUtils;
    36  import com.opensymphony.xwork2.util.ValueStack;
    37  import com.opensymphony.xwork2.TextProvider;
    38
    39  /***
    40   * <!-- START SNIPPET: javadoc -->
    41   * Render a I18n text message.
    42   *
    43   * <p/>
    44   *
    45   * The message must be in a resource bundle
    46   * with the same name as the action that it is associated with. In practice
    47   * this means that you should create a properties file in the same package
    48   * as your Java class with the same name as your class, but with .properties
    49   * extension.
    50   *
    51   * <p/>
    52   *
    53   * If the named message is not found, then the body of the tag will be used as default message.
    54   * If no body is used, then the name of the message will be used.
    55   *
    56   * <!-- END SNIPPET: javadoc -->
    57   *
    58   *
    59   *
    60   * <!-- START SNIPPET: params -->
    61   *
    62   * <ul>
    63   *      <li>name* (String) - the i18n message key</li>
    64   * </ul>
    65   *
    66   * <!-- END SNIPPET: params -->
    67   *
    68   * <p/>
    69   *
    70   * Example:
    71   * <pre>
    72   * <!-- START SNIPPET: exdescription -->
    73   *
    74   * Accessing messages from a given bundle (the i18n Shop example bundle in the first example) and using bundle defined through the framework in the second example.</p>
    75   *
    76   * <!-- END SNIPPET: exdescription -->
    77   * </pre>
    78   *
    79   * <pre>
    80   * <!-- START SNIPPET: example -->
    81   *
    82   * &lt;!-- First Example --&gt;
    83   * &lt;s:i18n name="struts.action.test.i18n.Shop"&gt;
    84   *     &lt;s:text name="main.title"/&gt;
    85   * &lt;/s:i18n&gt;
    86   *
    87   * &lt;!-- Second Example --&gt;
    88   * &lt;s:text name="main.title" /&gt;
    89   *
    90   * &lt;!-- Third Examlpe --&gt;
    91   * &lt;s:text name="i18n.label.greetings"&gt;
    92   *    &lt;s:param &gt;Mr Smith&lt;/s:param&gt;
    93   * &lt;/s:text&gt;
    94   *
    95   * <!-- END SNIPPET: example -->
    96   * </pre>
    97   *
    98   *
    99   * <pre>
    100  * <!-- START SNIPPET: i18nExample -->
    101  *
    102  * &lt;-- Fourth Example --&gt;
    103  * &lt;s:text name="some.key" /&gt;
    104  *
    105  * &lt;-- Fifth Example --&gt;
    106  * &lt;s:text name="some.invalid.key" &gt;
    107  *    The Default Message That Will Be Displayed
    108  * &lt;/s:text&gt;
    109  *
    110  * <!-- END SNIPPET: i18nExample -->
    111  * </pre>
    112  *
    113  * @see Param
    114  *
    115  */
    116 @StrutsTag(name="text", tldTagClass="org.apache.struts2.views.jsp.TextTag", description="Render a I18n text message")
    117 public class Text extends Component implements Param.UnnamedParametric {
    118     private static final Log LOG = LogFactory.getLog(Text.class);
    119
    120     protected List values = Collections.EMPTY_LIST;
    121     protected String actualName;
    122     protected String name;
    123
    124     public Text(ValueStack stack) {
    125         super(stack);
    126     }
    127
    128     @StrutsTagAttribute(description=" Name of resource property to fetch", required=true)
    129     public void setName(String name) {
    130         this.name = name;
    131     }
    132
    133
    134     public boolean usesBody() {
    135         // overriding this to true such that EVAL_BODY_BUFFERED is return and
    136         // bodyContent will be valid hence, text between start & end tag will
    137         // be honoured as default message (WW-1268)
    138         return true;
    139     }
    140
    141     public boolean end(Writer writer, String body) {
    142         actualName = findString(name, "name", "You must specify the i18n key. Example: welcome.header");
    143         String defaultMessage;
    144         if (TextUtils.stringSet(body)) {
    145             defaultMessage = body;
    146         } else {
    147             defaultMessage = actualName;
    148         }
    149         String msg = null;
    150         ValueStack stack = getStack();
    151
    152         for (Iterator iterator = getStack().getRoot().iterator();
    153              iterator.hasNext();) {
    154             Object o = iterator.next();
    155
    156             if (o instanceof TextProvider) {
    157                 TextProvider tp = (TextProvider) o;
    158                 msg = tp.getText(actualName, defaultMessage, values, stack);
    159
    160                 break;
    161             }
    162         }
    163
    164         if (msg != null) {
    165             try {
    166                 if (getId() == null) {
    167                     writer.write(msg);
    168                 } else {
    169                     stack.getContext().put(getId(), msg);
    170                 }
    171             } catch (IOException e) {
    172                 LOG.error("Could not write out Text tag", e);
    173             }
    174         }
    175
    176         return super.end(writer, "");
    177     }
    178
    179     public void addParameter(String key, Object value) {
    180         addParameter(value);
    181     }
    182
    183     public void addParameter(Object value) {
    184         if (values.isEmpty()) {
    185             values = new ArrayList(4);
    186         }
    187
    188         values.add(value);
    189     }
    190 }