/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.anodyneos.xp.tag.fmt;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import javax.servlet.jsp.el.ELException;
import org.anodyneos.xp.XpContext;
import org.anodyneos.xp.XpException;
import org.anodyneos.xp.XpOutput;
import org.anodyneos.xp.tagext.XpTag;
import org.anodyneos.xp.tagext.XpTagSupport;
import org.xml.sax.SAXException;
/**
* Support for tag handlers for <message>, the message formatting tag in
* JSTL 1.0.
*
* @author Jan Luehe
*/
public class MessageTag extends XpTagSupport {
// *********************************************************************
// Public constants
public static final String UNDEFINED_KEY = "???";
// *********************************************************************
// Protected state
protected String keyAttrValue; // 'key' attribute value
protected boolean keySpecified; // 'key' attribute specified
protected LocalizationContext bundleAttrValue; // 'bundle' attribute value
protected boolean bundleSpecified; // 'bundle' attribute specified?
// *********************************************************************
// Private state
private String var; // 'var' attribute
private int scope; // 'scope' attribute
private List params;
// *********************************************************************
// Constructor and initialization
public MessageTag() {
params = new ArrayList();
var = null;
scope = XpContext.PAGE_SCOPE;
keyAttrValue = null;
keySpecified = false;
bundleAttrValue = null;
bundleSpecified = false;
}
// for tag attribute
public void setKey(String key) {
this.keyAttrValue = key;
this.keySpecified = true;
}
// for tag attribute
public void setBundle(LocalizationContext locCtxt) {
this.bundleAttrValue = locCtxt;
this.bundleSpecified = true;
}
// *********************************************************************
// Tag attributes known at translation time
public void setVar(String var) {
this.var = var;
}
public void setScope(String scope) {
this.scope = getXpContext().resolveScope(scope);
}
// *********************************************************************
// Collaboration with subtags
/**
* Adds an argument (for parametric replacement) to this tag's message.
*
* @see ParamSupport
*/
public void addParam(Object arg) {
params.add(arg);
}
// *********************************************************************
// Tag logic
public void doTag(XpOutput out) throws XpException, SAXException,
ELException {
String key = null;
LocalizationContext locCtxt = null;
// determine the message key by...
if (keySpecified) {
// ... reading 'key' attribute
key = keyAttrValue;
// this check is required as getXpBody returns null if the tag looks like: <fmt:message key="x" />
if (getXpBody() != null) {
getXpBody().invokeToString(); // use this to avoid output - body should only be param tags.
}
} else {
// ... retrieving and trimming our body
if (getXpBody() != null) {
key = getXpBody().invokeToString().trim();
}
}
if ((key == null) || key.equals("")) {
out.write("??????");
}
String prefix = null;
if (!bundleSpecified) {
XpTag t = findAncestorWithClass(this, BundleTag.class);
if (t != null) {
// use resource bundle from parent <bundle> tag
BundleTag parent = (BundleTag) t;
locCtxt = parent.getLocalizationContext();
prefix = parent.getPrefix();
} else {
locCtxt = BundleTag
.getLocalizationContext(getXpContext());
}
} else {
// localization context taken from 'bundle' attribute
locCtxt = bundleAttrValue;
//if (locCtxt.getLocale() != null) {
// SetLocaleSupport.setResponseLocale(pageContext, locCtxt
// .getLocale());
//}
}
String message = UNDEFINED_KEY + key + UNDEFINED_KEY;
if (locCtxt != null) {
ResourceBundle bundle = locCtxt.getResourceBundle();
if (bundle != null) {
try {
// prepend 'prefix' attribute from parent bundle
if (prefix != null)
key = prefix + key;
message = bundle.getString(key);
// Perform parametric replacement if required
if (!params.isEmpty()) {
Object[] messageArgs = params.toArray();
MessageFormat formatter = new MessageFormat(""); // empty
// pattern,
// default
// Locale
if (locCtxt.getLocale() != null) {
formatter.setLocale(locCtxt.getLocale());
} else {
// For consistency with the <fmt:formatXXX> actions,
// we try to get a locale that matches the user's
// preferences
// as well as the locales supported by 'date' and
// 'number'.
// System.out.println("LOCALE-LESS LOCCTXT: GETTING
// FORMATTING LOCALE");
Locale locale = SetLocaleTag
.getFormattingLocale(getXpContext());
// System.out.println("LOCALE: " + locale);
if (locale != null) {
formatter.setLocale(locale);
}
}
formatter.applyPattern(message);
message = formatter.format(messageArgs);
}
} catch (MissingResourceException mre) {
message = UNDEFINED_KEY + key + UNDEFINED_KEY;
}
}
}
if (var != null) {
getXpContext().setAttribute(var, message, scope);
} else {
out.write(message);
}
}
}