001/* 002 * Copyright 2002-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.servlet.tags; 018 019import javax.servlet.jsp.JspException; 020import javax.servlet.jsp.JspTagException; 021import javax.servlet.jsp.tagext.TagSupport; 022import javax.servlet.jsp.tagext.TryCatchFinally; 023 024import org.apache.commons.logging.Log; 025import org.apache.commons.logging.LogFactory; 026 027import org.springframework.web.servlet.support.JspAwareRequestContext; 028import org.springframework.web.servlet.support.RequestContext; 029 030/** 031 * Superclass for all tags that require a {@link RequestContext}. 032 * 033 * <p>The {@code RequestContext} instance provides easy access 034 * to current state like the 035 * {@link org.springframework.web.context.WebApplicationContext}, 036 * the {@link java.util.Locale}, the 037 * {@link org.springframework.ui.context.Theme}, etc. 038 * 039 * <p>Mainly intended for 040 * {@link org.springframework.web.servlet.DispatcherServlet} requests; 041 * will use fallbacks when used outside {@code DispatcherServlet}. 042 * 043 * @author Rod Johnson 044 * @author Juergen Hoeller 045 * @see org.springframework.web.servlet.support.RequestContext 046 * @see org.springframework.web.servlet.DispatcherServlet 047 */ 048@SuppressWarnings("serial") 049public abstract class RequestContextAwareTag extends TagSupport implements TryCatchFinally { 050 051 /** 052 * {@link javax.servlet.jsp.PageContext} attribute for the 053 * page-level {@link RequestContext} instance. 054 */ 055 public static final String REQUEST_CONTEXT_PAGE_ATTRIBUTE = 056 "org.springframework.web.servlet.tags.REQUEST_CONTEXT"; 057 058 059 /** Logger available to subclasses */ 060 protected final Log logger = LogFactory.getLog(getClass()); 061 062 063 private RequestContext requestContext; 064 065 066 /** 067 * Create and expose the current RequestContext. 068 * Delegates to {@link #doStartTagInternal()} for actual work. 069 * @see #REQUEST_CONTEXT_PAGE_ATTRIBUTE 070 * @see org.springframework.web.servlet.support.JspAwareRequestContext 071 */ 072 @Override 073 public final int doStartTag() throws JspException { 074 try { 075 this.requestContext = (RequestContext) this.pageContext.getAttribute(REQUEST_CONTEXT_PAGE_ATTRIBUTE); 076 if (this.requestContext == null) { 077 this.requestContext = new JspAwareRequestContext(this.pageContext); 078 this.pageContext.setAttribute(REQUEST_CONTEXT_PAGE_ATTRIBUTE, this.requestContext); 079 } 080 return doStartTagInternal(); 081 } 082 catch (JspException ex) { 083 logger.error(ex.getMessage(), ex); 084 throw ex; 085 } 086 catch (RuntimeException ex) { 087 logger.error(ex.getMessage(), ex); 088 throw ex; 089 } 090 catch (Exception ex) { 091 logger.error(ex.getMessage(), ex); 092 throw new JspTagException(ex.getMessage()); 093 } 094 } 095 096 /** 097 * Return the current RequestContext. 098 */ 099 protected final RequestContext getRequestContext() { 100 return this.requestContext; 101 } 102 103 /** 104 * Called by doStartTag to perform the actual work. 105 * @return same as TagSupport.doStartTag 106 * @throws Exception any exception, any checked one other than 107 * a JspException gets wrapped in a JspException by doStartTag 108 * @see javax.servlet.jsp.tagext.TagSupport#doStartTag 109 */ 110 protected abstract int doStartTagInternal() throws Exception; 111 112 113 @Override 114 public void doCatch(Throwable throwable) throws Throwable { 115 throw throwable; 116 } 117 118 @Override 119 public void doFinally() { 120 this.requestContext = null; 121 } 122 123}