View Javadoc

1   /*
2    * $Id$
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  
22  package org.apache.struts2.util;
23  
24  import com.opensymphony.xwork2.util.ValueStack;
25  import com.opensymphony.xwork2.util.logging.Logger;
26  import com.opensymphony.xwork2.util.logging.LoggerFactory;
27  import com.opensymphony.xwork2.TextProvider;
28  
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.LinkedList;
32  import java.util.Collections;
33  
34  /***
35   * Helper methods to access text from TextProviders
36   */
37  public class TextProviderHelper {
38  
39      private static final Logger LOG = LoggerFactory.getLogger(TextProviderHelper.class);
40  
41       /***
42       * <p>Get a message from the first TextProvider encountered in the stack.
43       * If the first TextProvider doesn't provide the message the default message is returned.</p>
44       * The stack is searched if if no TextProvider is found, or the message is not found.
45       * @param key             the message key in the resource bundle
46       * @param defaultMessage  the message to return if not found (evaluated for OGNL)
47       * @param args            an array args to be used in a {@link java.text.MessageFormat} message
48       * @param stack           the value stack to use for finding the text
49       *
50       * @return the message if found, otherwise the defaultMessage
51       */
52      public static String getText(String key, String defaultMessage, List<Object> args, ValueStack stack) {
53          return getText(key, defaultMessage, args, stack, true);
54      }
55  
56      /***
57       * <p>Get a message from the first TextProvider encountered in the stack.
58       * If the first TextProvider doesn't provide the message the default message is returned.</p>
59       * <p>The search for a TextProvider is iterative from the root of the stack.</p>
60       * <p>This method was refactored from  {@link org.apache.struts2.components.Text} to use a
61       * consistent implementation across UIBean components.</p>
62       * @param key             the message key in the resource bundle
63       * @param defaultMessage  the message to return if not found (evaluated for OGNL)
64       * @param args            an array args to be used in a {@link java.text.MessageFormat} message
65       * @param stack           the value stack to use for finding the text
66       * @param searchStack     search stack for the key
67       *
68       * @return the message if found, otherwise the defaultMessage
69       */
70      public static String getText(String key, String defaultMessage, List<Object> args, ValueStack stack, boolean searchStack) {
71          String msg = null;
72          TextProvider tp = null;
73  
74          for (Iterator iterator = stack.getRoot().iterator(); iterator.hasNext();) {
75              Object o = iterator.next();
76  
77              if (o instanceof TextProvider) {
78                  tp = (TextProvider) o;
79                  msg = tp.getText(key, null, args, stack);
80  
81                  break;
82              }
83          }
84  
85          if (msg == null) {
86              // evaluate the defaultMesage as an OGNL expression
87              if (searchStack)
88                  msg = stack.findString(defaultMessage);
89              
90              if (msg == null) {
91                  // use the defaultMessage literal value
92                  msg = defaultMessage;
93              }
94  
95              if (LOG.isWarnEnabled()) {
96                  if (tp != null) {
97                      LOG.warn("The first TextProvider in the ValueStack ("+tp.getClass().getName()+") could not locate the message resource with key '"+key+"'");
98                  } else {
99                      LOG.warn("Could not locate the message resource '"+key+"' as there is no TextProvider in the ValueStack.");
100                 }
101                 if (msg.equals(defaultMessage)) {
102                     LOG.warn("The default value expression '"+defaultMessage+"' was evaluated and did not match a property.  The literal value '"+defaultMessage+"' will be used.");
103                 } else {
104                     LOG.warn("The default value expression '"+defaultMessage+"' evaluated to '"+msg+"'");
105                 }
106             }
107         }
108         return msg;
109     }
110 
111     /***
112      * <p>Get a message from the first TextProvider encountered in the stack.
113      * If the first TextProvider doesn't provide the message the default message is returned.</p>
114      * <p>The search for a TextProvider is iterative from the root of the stack.</p>
115      * <p>This method was refactored from  {@link org.apache.struts2.components.Text} to use a
116      * consistent implementation across UIBean components.</p>
117      * @param key             the message key in the resource bundle
118      * @param defaultMessage  the message to return if not found
119      * @param stack           the value stack to use for finding the text
120        *
121      * @return the message if found, otherwise the defaultMessage
122      */
123     public static String getText(String key, String defaultMessage, ValueStack stack) {
124         return getText(key, defaultMessage, Collections.emptyList(), stack);
125     }
126 }