View Javadoc

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