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.geronimo.tomcat.listener;
018    
019    import java.util.Stack;
020    import javax.servlet.ServletRequest;
021    import javax.servlet.ServletResponse;
022    
023    import org.apache.catalina.Container;
024    import org.apache.catalina.Globals;
025    import org.apache.catalina.InstanceEvent;
026    import org.apache.catalina.InstanceListener;
027    import org.apache.catalina.core.StandardWrapper;
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    import org.apache.geronimo.tomcat.GeronimoStandardContext;
031    import org.apache.geronimo.tomcat.interceptor.BeforeAfter;
032    import org.apache.geronimo.tomcat.realm.TomcatGeronimoRealm;
033    import org.apache.tomcat.util.buf.MessageBytes;
034    import org.apache.tomcat.util.http.mapper.Mapper;
035    import org.apache.tomcat.util.http.mapper.MappingData;
036    
037    public class DispatchListener implements InstanceListener {
038    
039        private static final Log log = LogFactory.getLog(DispatchListener.class);
040    
041        private static ThreadLocal currentContext = new ThreadLocal() {
042            protected Object initialValue() {
043                return new Stack<Object[]>();
044            }
045        };
046    
047        public void instanceEvent(InstanceEvent event) {
048    
049            if (event.getType().equals(InstanceEvent.BEFORE_DISPATCH_EVENT)) {
050                Container parent = event.getWrapper().getParent();
051                if (parent instanceof GeronimoStandardContext) {
052                    beforeDispatch((GeronimoStandardContext) parent, event.getRequest(), event.getResponse());
053                }
054            }
055    
056            if (event.getType().equals(InstanceEvent.AFTER_DISPATCH_EVENT)) {
057                Container parent = event.getWrapper().getParent();
058                if (parent instanceof GeronimoStandardContext) {
059                    afterDispatch((GeronimoStandardContext) parent, event.getRequest(), event.getResponse());
060                }
061            }
062        }
063    
064        private void beforeDispatch(GeronimoStandardContext webContext, ServletRequest request, ServletResponse response) {
065    
066            BeforeAfter beforeAfter = webContext.getBeforeAfter();
067            if (beforeAfter != null) {
068                Stack<Object[]> stack = (Stack<Object[]>) currentContext.get();
069                Object context[] = new Object[webContext.getContextCount() + 1];
070                String wrapperName = getWrapperName(request, webContext);
071                context[webContext.getContextCount()] = TomcatGeronimoRealm.setRequestWrapperName(wrapperName);
072    
073                beforeAfter.before(context, request, response, BeforeAfter.DISPATCHED);
074    
075                stack.push(context);
076            }
077        }
078    
079        private void afterDispatch(GeronimoStandardContext webContext, ServletRequest request, ServletResponse response) {
080    
081            BeforeAfter beforeAfter = webContext.getBeforeAfter();
082            if (beforeAfter != null) {
083                Stack stack = (Stack) currentContext.get();
084                Object context[] = (Object[]) stack.pop();
085    
086                beforeAfter.after(context, request, response, BeforeAfter.DISPATCHED);
087    
088                TomcatGeronimoRealm.setRequestWrapperName((String) context[webContext.getContextCount()]);
089            }
090        }
091    
092        private String getWrapperName(ServletRequest request, GeronimoStandardContext webContext) {
093    
094            MappingData mappingData = new MappingData();
095            Mapper mapper = webContext.getMapper();
096            MessageBytes mb = MessageBytes.newInstance();
097    
098            String dispatchPath = (String) request.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR);
099            mb.setString(webContext.getName() + dispatchPath);
100    
101            try {
102                mapper.map(mb, mappingData);
103                StandardWrapper wrapper = (StandardWrapper) mappingData.wrapper;
104                return wrapper.getName();
105            } catch (Exception e) {
106                log.error(e.getMessage(), e);
107            }
108    
109            return null;
110        }
111    
112    }