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 }