001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.tags.html;
020:
021: import org.apache.beehive.netui.pageflow.config.PageFlowActionMapping;
022: import org.apache.beehive.netui.pageflow.config.PageFlowControllerConfig;
023: import org.apache.beehive.netui.pageflow.internal.InternalConstants;
024: import org.apache.beehive.netui.pageflow.internal.InternalExpressionUtils;
025: import org.apache.beehive.netui.pageflow.internal.InternalUtils;
026: import org.apache.beehive.netui.pageflow.PageFlowUtils;
027: import org.apache.beehive.netui.tags.AbstractSimpleTag;
028: import org.apache.beehive.netui.util.Bundle;
029: import org.apache.beehive.netui.util.logging.Logger;
030: import org.apache.struts.Globals;
031: import org.apache.struts.action.ActionMapping;
032: import org.apache.struts.action.ActionMessage;
033: import org.apache.struts.action.ActionForm;
034: import org.apache.struts.config.ControllerConfig;
035: import org.apache.struts.config.ModuleConfig;
036: import org.apache.struts.taglib.html.Constants;
037: import org.apache.struts.util.MessageResources;
038: import org.apache.struts.util.RequestUtils;
039:
040: import javax.servlet.ServletContext;
041: import javax.servlet.http.HttpServletRequest;
042: import javax.servlet.jsp.JspException;
043: import javax.servlet.jsp.PageContext;
044: import javax.servlet.jsp.el.ELException;
045: import java.text.MessageFormat;
046: import java.util.Locale;
047:
048: abstract public class ErrorBaseTag extends AbstractSimpleTag {
049: private static final Logger LOGGER = Logger
050: .getInstance(ErrorBaseTag.class);
051:
052: /**
053: * The default locale on our server.
054: */
055: protected static Locale defaultLocale = Locale.getDefault();
056:
057: /**
058: * The name of the message bundle, as defined in the page flow's
059: * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.MessageBundle} annotation,
060: * where the error messages can be found. This defaults to org.apache.struts.action.Action.MESSAGES_KEY.
061: */
062: protected String _bundleName = null;
063:
064: /**
065: * The session attribute key for the locale.
066: * This defaults to org.apache.struts.action.Action.LOCALE_KEY.
067: */
068: protected String _locale = Globals.LOCALE_KEY;
069:
070: /**
071: * The isResource method on ActionMessage isn't present in Struts 1.1.
072: */
073: private static boolean _isStruts11 = false;
074:
075: static {
076: try {
077: ActionMessage.class.getMethod("isResource", null);
078: } catch (NoSuchMethodException e) {
079: _isStruts11 = true;
080: }
081: }
082:
083: /**
084: * Set the name of the message bundle, as defined in the page flow's
085: * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.MessageBundle} annotation, where the error messages
086: * can be found. If this attribute is not set, the page flow's default message bundle is used.
087: * @param bundleName the bundle name
088: * @jsptagref.attributedescription The name of the message bundle, as defined in the page flow's
089: * Jpf.MessageBundle annotation. This defaults to org.apache.struts.action.Action.MESSAGES_KEY.
090: * @jsptagref.databindable false
091: * @jsptagref.attributesyntaxvalue <i>string_bundleName</i>
092: * @netui:attribute required="false" rtexprvalue="true"
093: * description="The name of the message bundle, as defined in the page flow's Jpf.MessageBundle annotation."
094: */
095: public final void setBundleName(String bundleName)
096: throws JspException {
097: _bundleName = setRequiredValueAttribute(bundleName,
098: "bundleName");
099: }
100:
101: /**
102: * Set the name of the locale attribute.
103: * @param locale the locale attribute name
104: * @jsptagref.attributedescription The name of the session attribute key for the user's locale.
105: * This defaults to org.apache.struts.action.Action.LOCALE_KEY.
106: * @jsptagref.databindable false
107: * @jsptagref.attributesyntaxvalue <i>string_locale</i>
108: * @netui:attribute required="false" rtexprvalue="true"
109: * description="The name of the session attribute key for the user's locale"
110: */
111: public final void setLocale(String locale) {
112: _locale = setNonEmptyValueAttribute(locale);
113: }
114:
115: /**
116: * @param report
117: * @param bundleName
118: * @return message
119: * @throws JspException
120: */
121: protected String getErrorMessage(ActionMessage report,
122: String bundleName) throws JspException {
123: String key = report.getKey();
124: Object[] messageArgs = report.getValues();
125: PageContext pageContext = getPageContext();
126:
127: String message = null;
128: HttpServletRequest request = (HttpServletRequest) pageContext
129: .getRequest();
130: if (key.length() == 0) {
131: return "";
132: } else if (!_isStruts11 && !report.isResource()) {
133: //
134: // This covers the case where the validator has already used MessageResources
135: // with an alternate resource bundle to format the message before
136: // creating the ActionMessage. Just return the already formatted message.
137: //
138: message = report.getKey();
139: } else {
140: ModuleConfig curModuleConfig = RequestUtils
141: .getModuleConfig(pageContext);
142: ServletContext servletContext = pageContext
143: .getServletContext();
144:
145: // First, look in the message bundle for a shared flow that was involved in this request.
146: String sharedFlowModulePath = InternalUtils
147: .getForwardingModule(pageContext.getRequest());
148: if (sharedFlowModulePath != null
149: && (curModuleConfig == null || !sharedFlowModulePath
150: .equals(curModuleConfig.getPrefix()))) {
151: ModuleConfig sfModule = InternalUtils.getModuleConfig(
152: sharedFlowModulePath, servletContext);
153: if (bundleName != null
154: || !isMissingUserDefaultMessages(sfModule)) {
155: String msgAttr = (bundleName != null ? bundleName
156: : Globals.MESSAGES_KEY)
157: + sfModule.getPrefix();
158: MessageResources resources = (MessageResources) servletContext
159: .getAttribute(msgAttr);
160: message = getMessage(resources, key, messageArgs,
161: pageContext);
162: }
163: }
164:
165: // Next look in the default message bundle for the page flow.
166: boolean missingUserDefaultMessages = isMissingUserDefaultMessages(pageContext);
167: if (message == null
168: && (bundleName != null || !missingUserDefaultMessages)) {
169: MessageResources resources = InternalUtils
170: .getMessageResources(
171: bundleName != null ? bundleName
172: : Globals.MESSAGES_KEY,
173: request, servletContext);
174: message = getMessage(resources, key, messageArgs,
175: pageContext);
176: }
177:
178: // If we still didn't find it, try the default validation message bundle (in beehive-netui-pageflow.jar).
179: if (message == null && bundleName == null) {
180: MessageResources resources = InternalUtils
181: .getMessageResources("_defaultMsgs", request,
182: servletContext);
183: message = getMessage(resources, key, messageArgs,
184: pageContext);
185: }
186:
187: //
188: // We've run out of options -- the message simply doesn't exist. If the user didn't specify a default
189: // message bundle in the page flow, that's the problem; otherwise, it's simply a missing message.
190: // Register a tag error for either case.
191: //
192: if (message == null) {
193: if (bundleName == null && missingUserDefaultMessages) {
194: String s = Bundle.getString(
195: "Tags_ErrorsBundleMissing", key);
196: registerTagError(s, null);
197: return null;
198: } else {
199: String s = Bundle.getString(
200: "Tags_ErrorsMessageMissing", key);
201: registerTagError(s, null);
202: return null;
203: }
204: }
205: }
206:
207: return message;
208: }
209:
210: private String getMessage(MessageResources resources, String key,
211: Object[] messageArgs, PageContext pageContext) {
212: if (resources != null) {
213: Locale userLocale = RequestUtils.retrieveUserLocale(
214: pageContext, _locale);
215: if (messageArgs == null) {
216: return resources.getMessage(userLocale, key);
217: } else {
218: return resources.getMessage(userLocale, key,
219: messageArgs);
220: }
221: }
222:
223: return null;
224: }
225:
226: /**
227: * Tell whether the given Struts module has no default message bundle defined.
228: * @return <code>true</code> if the given Struts module has no user-specified default message bundle.
229: */
230: protected static boolean isMissingUserDefaultMessages(
231: PageContext pageContext) {
232: return isMissingUserDefaultMessages(RequestUtils
233: .getModuleConfig(pageContext))
234: && pageContext.getRequest().getAttribute(
235: Globals.MESSAGES_KEY) == null;
236: }
237:
238: /**
239: * Tell whether the given Struts module has no default message bundle defined.
240: * @return <code>true</code> if the given Struts module has no user-specified default message bundle.
241: */
242: protected static boolean isMissingUserDefaultMessages(
243: ModuleConfig mc) {
244: if (mc != null) {
245: ControllerConfig cc = mc.getControllerConfig();
246:
247: if (cc instanceof PageFlowControllerConfig) {
248: return ((PageFlowControllerConfig) cc)
249: .isMissingDefaultMessages();
250: }
251: }
252:
253: return false;
254: }
255: }
|