1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.geronimo.tomcat.listener; 18 19 import java.util.Stack; 20 21 import javax.security.jacc.PolicyContext; 22 import javax.servlet.ServletRequest; 23 import javax.servlet.ServletResponse; 24 25 import org.apache.catalina.Container; 26 import org.apache.catalina.Globals; 27 import org.apache.catalina.InstanceEvent; 28 import org.apache.catalina.InstanceListener; 29 import org.apache.catalina.core.StandardWrapper; 30 import org.apache.geronimo.tomcat.GeronimoStandardContext; 31 import org.apache.geronimo.tomcat.interceptor.BeforeAfter; 32 import org.apache.geronimo.tomcat.security.jacc.JACCRealm; 33 import org.apache.tomcat.util.buf.MessageBytes; 34 import org.apache.tomcat.util.http.mapper.Mapper; 35 import org.apache.tomcat.util.http.mapper.MappingData; 36 import org.slf4j.Logger; 37 import org.slf4j.LoggerFactory; 38 39 public class DispatchListener implements InstanceListener { 40 41 private static final Logger log = LoggerFactory.getLogger(DispatchListener.class); 42 43 private static ThreadLocal<Stack<Object[]>> currentContext = new ThreadLocal<Stack<Object[]>>() { 44 protected Stack<Object[]> initialValue() { 45 return new Stack<Object[]>(); 46 } 47 }; 48 49 50 public void instanceEvent(InstanceEvent event) { 51 52 if (event.getType().equals(InstanceEvent.BEFORE_DISPATCH_EVENT)) { 53 Container parent = event.getWrapper().getParent(); 54 if (parent instanceof GeronimoStandardContext) { 55 beforeDispatch((GeronimoStandardContext) parent, event.getRequest(), event.getResponse()); 56 } 57 } 58 59 if (event.getType().equals(InstanceEvent.AFTER_DISPATCH_EVENT)) { 60 Container parent = event.getWrapper().getParent(); 61 if (parent instanceof GeronimoStandardContext) { 62 afterDispatch((GeronimoStandardContext) parent, event.getRequest(), event.getResponse()); 63 } 64 } 65 } 66 67 private void beforeDispatch(GeronimoStandardContext webContext, ServletRequest request, ServletResponse response) { 68 69 BeforeAfter beforeAfter = webContext.getBeforeAfter(); 70 if (beforeAfter != null) { 71 Stack<Object[]> stack = currentContext.get(); 72 Object context[] = new Object[webContext.getContextCount() + 2]; 73 String wrapperName = getWrapperName(request, webContext); 74 context[webContext.getContextCount()] = JACCRealm.setRequestWrapperName(wrapperName); 75 76 context[webContext.getContextCount() + 1] = PolicyContext.getContextID(); 77 PolicyContext.setContextID(webContext.getPolicyContextId()); 78 79 beforeAfter.before(context, request, response, BeforeAfter.DISPATCHED); 80 81 stack.push(context); 82 } 83 } 84 85 private void afterDispatch(GeronimoStandardContext webContext, ServletRequest request, ServletResponse response) { 86 87 BeforeAfter beforeAfter = webContext.getBeforeAfter(); 88 if (beforeAfter != null) { 89 Stack<Object[]> stack = currentContext.get(); 90 Object context[] = stack.pop(); 91 92 beforeAfter.after(context, request, response, BeforeAfter.DISPATCHED); 93 94 JACCRealm.setRequestWrapperName((String) context[webContext.getContextCount()]); 95 PolicyContext.setContextID((String) context[webContext.getContextCount() + 1]); 96 } 97 } 98 99 private String getWrapperName(ServletRequest request, GeronimoStandardContext webContext) { 100 101 MappingData mappingData = new MappingData(); 102 Mapper mapper = webContext.getMapper(); 103 MessageBytes mb = MessageBytes.newInstance(); 104 105 String dispatchPath = (String) request.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR); 106 mb.setString(webContext.getName() + dispatchPath); 107 108 try { 109 mapper.map(mb, mappingData); 110 StandardWrapper wrapper = (StandardWrapper) mappingData.wrapper; 111 return wrapper.getName(); 112 } catch (Exception e) { 113 log.error(e.getMessage(), e); 114 } 115 116 return null; 117 } 118 119 }