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    import javax.servlet.http.HttpServletRequest;
033    import javax.servlet.http.HttpServletResponse;
034    
035    import org.apache.activemq.web.BrokerFacade;
036    import org.slf4j.Logger;
037    import org.slf4j.LoggerFactory;
038    import org.springframework.web.bind.ServletRequestDataBinder;
039    import org.springframework.web.context.WebApplicationContext;
040    import 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 &lt;c.set var="myfoo"
053     * value="${applicationContext.foo}"/&gt; <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     */
062    public 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    }