001: /*
002: * $Id: Text.java 497654 2007-01-19 00:21:57Z rgielen $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts2.components;
022:
023: import java.io.IOException;
024: import java.io.Writer;
025: import java.util.ArrayList;
026: import java.util.Collections;
027: import java.util.Iterator;
028: import java.util.List;
029:
030: import org.apache.commons.logging.Log;
031: import org.apache.commons.logging.LogFactory;
032: import org.apache.struts2.views.annotations.StrutsTag;
033: import org.apache.struts2.views.annotations.StrutsTagAttribute;
034:
035: import com.opensymphony.xwork2.util.TextUtils;
036: import com.opensymphony.xwork2.util.ValueStack;
037: import com.opensymphony.xwork2.TextProvider;
038:
039: /**
040: * <!-- START SNIPPET: javadoc -->
041: * Render a I18n text message.
042: *
043: * <p/>
044: *
045: * The message must be in a resource bundle
046: * with the same name as the action that it is associated with. In practice
047: * this means that you should create a properties file in the same package
048: * as your Java class with the same name as your class, but with .properties
049: * extension.
050: *
051: * <p/>
052: *
053: * If the named message is not found, then the body of the tag will be used as default message.
054: * If no body is used, then the name of the message will be used.
055: *
056: * <!-- END SNIPPET: javadoc -->
057: *
058: *
059: *
060: * <!-- START SNIPPET: params -->
061: *
062: * <ul>
063: * <li>name* (String) - the i18n message key</li>
064: * </ul>
065: *
066: * <!-- END SNIPPET: params -->
067: *
068: * <p/>
069: *
070: * Example:
071: * <pre>
072: * <!-- START SNIPPET: exdescription -->
073: *
074: * 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>
075: *
076: * <!-- END SNIPPET: exdescription -->
077: * </pre>
078: *
079: * <pre>
080: * <!-- START SNIPPET: example -->
081: *
082: * <!-- First Example -->
083: * <s:i18n name="struts.action.test.i18n.Shop">
084: * <s:text name="main.title"/>
085: * </s:i18n>
086: *
087: * <!-- Second Example -->
088: * <s:text name="main.title" />
089: *
090: * <!-- Third Examlpe -->
091: * <s:text name="i18n.label.greetings">
092: * <s:param >Mr Smith</s:param>
093: * </s:text>
094: *
095: * <!-- END SNIPPET: example -->
096: * </pre>
097: *
098: *
099: * <pre>
100: * <!-- START SNIPPET: i18nExample -->
101: *
102: * <-- Fourth Example -->
103: * <s:text name="some.key" />
104: *
105: * <-- Fifth Example -->
106: * <s:text name="some.invalid.key" >
107: * The Default Message That Will Be Displayed
108: * </s:text>
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: 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",
142: "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(); iterator
153: .hasNext();) {
154: Object o = iterator.next();
155:
156: if (o instanceof TextProvider) {
157: TextProvider tp = (TextProvider) o;
158: msg = tp.getText(actualName, defaultMessage, values,
159: stack);
160:
161: break;
162: }
163: }
164:
165: if (msg != null) {
166: try {
167: if (getId() == null) {
168: writer.write(msg);
169: } else {
170: stack.getContext().put(getId(), msg);
171: }
172: } catch (IOException e) {
173: LOG.error("Could not write out Text tag", e);
174: }
175: }
176:
177: return super .end(writer, "");
178: }
179:
180: public void addParameter(String key, Object value) {
181: addParameter(value);
182: }
183:
184: public void addParameter(Object value) {
185: if (values.isEmpty()) {
186: values = new ArrayList(4);
187: }
188:
189: values.add(value);
190: }
191: }
|