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