Java tutorial
/** * Copyright (C) 2013 Seajas, the Netherlands. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.seajas.search.utilities.tags; import java.io.IOException; import java.util.List; import java.util.Vector; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspTagException; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceResolvable; import org.springframework.context.NoSuchMessageException; import org.springframework.web.servlet.tags.HtmlEscapingAwareTag; import org.springframework.web.util.ExpressionEvaluationUtils; import org.springframework.web.util.HtmlUtils; import org.springframework.web.util.JavaScriptUtils; import org.springframework.web.util.TagUtils; /** * Overridden MessageTag (which has very unfortunate final methods) which takes its arguments from its child tags. * * @author Rod Johnson * @author Juergen Hoeller * @author Jasper van Veghel <jasper@seajas.com> * @see org.springframework.web.servlet.tags.MessageTag */ public class MessageTag extends HtmlEscapingAwareTag { /** * Serial version UID. */ private static final long serialVersionUID = 0L; /** * Default separator for splitting an arguments String: a comma (",") */ public static final String DEFAULT_ARGUMENT_SEPARATOR = ","; private Object message; private String code; private List<Object> arguments; private String text; private String var; private String scope = TagUtils.SCOPE_PAGE; private boolean javaScriptEscape = false; /** * Set the MessageSourceResolvable for this tag. Accepts a direct MessageSourceResolvable instance as well as a JSP expression language String that points to a MessageSourceResolvable. * <p> * If a MessageSourceResolvable is specified, it effectively overrides any code, arguments or text specified on this tag. * * @param message */ public void setMessage(final Object message) { this.message = message; } /** * Set the message code for this tag. * * @param code */ public void setCode(final String code) { this.code = code; } /** * Get optional message arguments for this tag. * * @return List<Object> */ public List<Object> getArguments() { return arguments; } /** * Set the message text for this tag. * * @param text */ public void setText(final String text) { this.text = text; } /** * Set PageContext attribute name under which to expose a variable that contains the resolved message. * * @param var * @see #setScope * @see javax.servlet.jsp.PageContext#setAttribute */ public void setVar(final String var) { this.var = var; } /** * Set the scope to export the variable to. Default is SCOPE_PAGE ("page"). * * @param scope * @see #setVar * @see org.springframework.web.util.TagUtils#SCOPE_PAGE * @see javax.servlet.jsp.PageContext#setAttribute */ public void setScope(final String scope) { this.scope = scope; } /** * Set JavaScript escaping for this tag, as boolean value. Default is "false". * * @param javaScriptEscape * @throws JspException */ public void setJavaScriptEscape(final String javaScriptEscape) throws JspException { this.javaScriptEscape = ExpressionEvaluationUtils.evaluateBoolean("javaScriptEscape", javaScriptEscape, pageContext); } /** * Resolves the message, escapes it if demanded, and writes it to the page (or exposes it as variable). * * @see #resolveMessage() * @see org.springframework.web.util.HtmlUtils#htmlEscape(String) * @see org.springframework.web.util.JavaScriptUtils#javaScriptEscape(String) * @see #writeMessage(String) */ @Override protected final int doStartTagInternal() throws JspException, IOException { arguments = new Vector<Object>(); return EVAL_BODY_INCLUDE; } /** * Put the actual internal processing in here. * * @return * @throws JspException */ @Override public int doEndTag() throws JspException { try { // Resolve the unescaped message. String msg = resolveMessage(); // HTML and/or JavaScript escape, if demanded. msg = isHtmlEscape() ? HtmlUtils.htmlEscape(msg) : msg; msg = this.javaScriptEscape ? JavaScriptUtils.javaScriptEscape(msg) : msg; // Expose as variable, if demanded, else write to the page. String resolvedVar = ExpressionEvaluationUtils.evaluateString("var", this.var, pageContext); if (resolvedVar != null) { String resolvedScope = ExpressionEvaluationUtils.evaluateString("scope", this.scope, pageContext); pageContext.setAttribute(resolvedVar, msg, TagUtils.getScope(resolvedScope)); } else { try { writeMessage(msg); } catch (IOException e) { throw new JspException(e); } } return super.doAfterBody(); } catch (NoSuchMessageException ex) { throw new JspTagException(getNoSuchMessageExceptionDescription(ex)); } } /** * Resolve the specified message into a concrete message String. The returned message String should be unescaped. * * @throws JspException * @throws NoSuchMessageException */ protected String resolveMessage() throws JspException, NoSuchMessageException { MessageSource messageSource = getMessageSource(); if (messageSource == null) { throw new JspTagException("No corresponding MessageSource found"); } // Evaluate the specified MessageSourceResolvable, if any. MessageSourceResolvable resolvedMessage = null; if (this.message instanceof MessageSourceResolvable) { resolvedMessage = (MessageSourceResolvable) this.message; } else if (this.message != null) { String expr = this.message.toString(); resolvedMessage = (MessageSourceResolvable) ExpressionEvaluationUtils.evaluate("message", expr, MessageSourceResolvable.class, pageContext); } if (resolvedMessage != null) { // We have a given MessageSourceResolvable. return messageSource.getMessage(resolvedMessage, getRequestContext().getLocale()); } String resolvedCode = ExpressionEvaluationUtils.evaluateString("code", this.code, pageContext); String resolvedText = ExpressionEvaluationUtils.evaluateString("text", this.text, pageContext); if (resolvedCode != null || resolvedText != null) { // We have a code or default text that we need to resolve. Object[] argumentsArray = arguments.toArray(new Object[arguments.size()]); if (resolvedText != null) { // We have a fallback text to consider. return messageSource.getMessage(resolvedCode, argumentsArray, resolvedText, getRequestContext().getLocale()); } else { // We have no fallback text to consider. return messageSource.getMessage(resolvedCode, argumentsArray, getRequestContext().getLocale()); } } // All we have is a specified literal text. return resolvedText; } /** * Write the message to the page. * <p> * Can be overridden in subclasses, e.g. for testing purposes. * * @param msg * the message to write * @throws IOException * if writing failed */ protected void writeMessage(final String msg) throws IOException { pageContext.getOut().write(String.valueOf(msg)); } /** * Use the current RequestContext's application context as MessageSource. * * @return MessageSource */ protected MessageSource getMessageSource() { return getRequestContext().getMessageSource(); } /** * Return default exception message. * * @param ex * @return String */ protected String getNoSuchMessageExceptionDescription(final NoSuchMessageException ex) { return ex.getMessage(); } }