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 */ 017package org.apache.activemq.web.filter; 018 019import java.io.IOException; 020import java.util.AbstractMap; 021import java.util.Collections; 022import java.util.Map; 023import java.util.Set; 024 025import javax.servlet.Filter; 026import javax.servlet.FilterChain; 027import javax.servlet.FilterConfig; 028import javax.servlet.ServletContext; 029import javax.servlet.ServletException; 030import javax.servlet.ServletRequest; 031import javax.servlet.ServletResponse; 032import javax.servlet.http.HttpServletRequest; 033import javax.servlet.http.HttpServletResponse; 034 035import org.apache.activemq.web.BrokerFacade; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038import org.springframework.web.bind.ServletRequestDataBinder; 039import org.springframework.web.context.WebApplicationContext; 040import org.springframework.web.context.support.WebApplicationContextUtils; 041 042/** 043 * Exposes Spring ApplicationContexts to JSP EL and other view technologies. 044 * Currently a variable is placed in application scope (by default called 045 * 'applicationContext') so that POJOs can be pulled out of Spring in a JSP page 046 * to render things using EL expressions. <br/> 047 * 048 * e.g. ${applicationContext.cheese} would access the cheese POJO. Or 049 * ${applicationContext.cheese.name} would access the name property of the 050 * cheese POJO. <br/> 051 * 052 * You can then use JSTL to work with these POJOs such as <c.set var="myfoo" 053 * value="${applicationContext.foo}"/> <br/> 054 * 055 * In addition to applicationContext a 'requestContext' variable is created 056 * which will automatically bind any request parameters to the POJOs extracted 057 * from the applicationContext - which is ideal for POJOs which implement 058 * queries in view technologies. 059 * 060 * 061 */ 062public class ApplicationContextFilter implements Filter { 063 private static final transient Logger LOG = LoggerFactory.getLogger(ApplicationContextFilter.class); 064 065 private ServletContext servletContext; 066 private String applicationContextName = "applicationContext"; 067 private String requestContextName = "requestContext"; 068 private String requestName = "request"; 069 070 public void init(FilterConfig config) throws ServletException { 071 this.servletContext = config.getServletContext(); 072 this.applicationContextName = getInitParameter(config, "applicationContextName", applicationContextName); 073 this.requestContextName = getInitParameter(config, "requestContextName", requestContextName); 074 this.requestName = getInitParameter(config, "requestName", requestName); 075 076 // register the application context in the applicationScope 077 WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext); 078 Map wrapper = createApplicationContextWrapper(context); 079 servletContext.setAttribute(applicationContextName, wrapper); 080 } 081 082 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 083 // lets register a requestContext in the requestScope 084 Map requestContextWrapper = createRequestContextWrapper(request); 085 String path = ((HttpServletRequest)request).getRequestURI(); 086 // handle slave brokers 087// try { 088// if ( !(path.endsWith("css") || path.endsWith("png") || path.endsWith("ico") || path.endsWith(slavePage)) 089// && ((BrokerFacade)requestContextWrapper.get("brokerQuery")).isSlave()) { 090// ((HttpServletResponse)response).sendRedirect(slavePage); 091// return; 092// } 093// } catch (Exception e) { 094// LOG.warn(path + ", failed to access BrokerFacade: reason: " + e.getLocalizedMessage()); 095// if (LOG.isDebugEnabled()) { 096// LOG.debug(request.toString(), e); 097// } 098// throw new IOException(e); 099// } 100 request.setAttribute(requestContextName, requestContextWrapper); 101 request.setAttribute(requestName, request); 102 chain.doFilter(request, response); 103 } 104 105 public void destroy() { 106 } 107 108 public ServletContext getServletContext() { 109 return servletContext; 110 } 111 112 public String getApplicationContextName() { 113 return applicationContextName; 114 } 115 116 public void setApplicationContextName(String variableName) { 117 this.applicationContextName = variableName; 118 } 119 120 public String getRequestContextName() { 121 return requestContextName; 122 } 123 124 public void setRequestContextName(String requestContextName) { 125 this.requestContextName = requestContextName; 126 } 127 128 protected String getInitParameter(FilterConfig config, String key, String defaultValue) { 129 String parameter = config.getInitParameter(key); 130 return (parameter != null) ? parameter : defaultValue; 131 } 132 133 /** 134 * Creates a wrapper around the web application context so that it can be 135 * accessed easily from inside JSP EL (or other expression languages in 136 * other view technologies). 137 */ 138 protected Map createApplicationContextWrapper(final WebApplicationContext context) { 139 Map wrapper = new AbstractMap() { 140 141 public WebApplicationContext getContext() { 142 return context; 143 } 144 145 public Object get(Object key) { 146 if (key == null) { 147 return null; 148 } 149 return context.getBean(key.toString()); 150 } 151 152 public Set entrySet() { 153 return Collections.EMPTY_SET; 154 } 155 156 }; 157 return wrapper; 158 } 159 160 /** 161 * Creates a wrapper around the request context (e.g. to allow POJOs to be 162 * auto-injected from request parameter values etc) so that it can be 163 * accessed easily from inside JSP EL (or other expression languages in 164 * other view technologies). 165 */ 166 protected Map createRequestContextWrapper(final ServletRequest request) { 167 final WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext); 168 Map wrapper = new AbstractMap() { 169 170 public WebApplicationContext getContext() { 171 return context; 172 } 173 174 public Object get(Object key) { 175 if (key == null) { 176 return null; 177 } 178 return bindRequestBean(context.getBean(key.toString()), request); 179 } 180 181 public Set entrySet() { 182 return Collections.EMPTY_SET; 183 } 184 185 }; 186 return wrapper; 187 188 } 189 190 /** 191 * Binds properties from the request parameters to the given POJO which is 192 * useful for POJOs which are configurable via request parameters such as 193 * for query/view POJOs 194 */ 195 protected Object bindRequestBean(Object bean, ServletRequest request) { 196 ServletRequestDataBinder binder = new ServletRequestDataBinder(bean, null); 197 binder.bind(request); 198 return bean; 199 } 200 201}