KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > admin > monitor > callflow > WebContainerListener


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * WebContainerListener.java
26  * $Id: WebContainerListener.java,v 1.12.2.1 2006/05/04 06:22:05 harpreet Exp $
27  * $Date: 2006/05/04 06:22:05 $
28  * $Revision: 1.12.2.1 $
29  */

30
31 package com.sun.enterprise.admin.monitor.callflow;
32
33 import org.apache.catalina.Wrapper;
34 import org.apache.catalina.InstanceEvent;
35 import org.apache.catalina.InstanceListener;
36 import org.apache.catalina.ContainerEvent;
37 import org.apache.catalina.ContainerListener;
38 import org.apache.catalina.core.StandardContext;
39 import org.apache.coyote.Adapter;
40 import org.apache.jasper.Constants;
41 import org.apache.jasper.servlet.JspServlet;
42
43 import javax.servlet.Filter JavaDoc;
44 import javax.servlet.Servlet JavaDoc;
45 import javax.servlet.ServletConfig JavaDoc;
46 import javax.servlet.http.HttpServletRequest JavaDoc;
47
48 import com.sun.enterprise.Switch;
49 /*
50  * WebContainerListener: Listens to web events and pushes to the callflow
51  * infrastructure.
52  * @author Harpreet Singh
53  * @author Ram Jeyaraman
54  */

55 public class WebContainerListener
56         implements InstanceListener, ContainerListener {
57     
58     private static final String JavaDoc JSP_SERVLET = JspServlet.class.getName();
59     /**
60      * Thread local object.
61      *
62      * This motivation for this object is to ensure that the natural call flow
63      * sequence is maintained. Refer to the javadoc description of Agent class.
64      * The natural call flow sequence expects startTime() to be called after
65      * all the addRequestInfo() calls are completed.
66      *
67      * In the case of the web container, we need to explicitly issue the first
68      * startTime() call, just before the beforeFilter or beforeService
69      * operation. However, for nested local servlet calls, called by the first
70      * Servlet, there is no need to explicitly issue the startTime() call,
71      * since the web container provides the beforeDispatch() event.
72      * Unfortunately, the beforeDispatch() event is not available for the
73      * first Servlet call, it is only available for nested local servlet
74      * invocations; so we use this thread local object as a work around.
75      *
76      * So, this thread local object exists, primarily to support the explicit
77      * issuance of the first startTime() call and its corollary endTime() call,
78      * during the invocation of the first Servlet or filter in the invocation
79      * path.
80      */

81     private static final ThreadLocal JavaDoc<AgentImpl.FlowStack<Boolean JavaDoc>> threadLocal =
82         new ThreadLocal JavaDoc() {
83             protected AgentImpl.FlowStack<Boolean JavaDoc> initialValue() {
84                 return new AgentImpl.FlowStack<Boolean JavaDoc>();
85             }
86         };
87     
88        
89         private static final ThreadLocal JavaDoc<Boolean JavaDoc> requestStartTls =
90           new ThreadLocal JavaDoc() {
91             protected Boolean JavaDoc initialValue(){
92                 return Boolean.FALSE;
93             }
94         };
95         
96     private Agent callFlowAgent;
97     
98     public WebContainerListener() {
99         this.callFlowAgent = Switch.getSwitch().getCallFlowAgent();
100     }
101     
102     public void instanceEvent(InstanceEvent event) {
103
104         if (!callFlowAgent.isEnabled()) {
105             return;
106         }
107         
108         if (!requestStartTls.get ())
109             return;
110
111         if (event.getType().equals(InstanceEvent.BEFORE_SERVICE_EVENT)) {
112             AgentImpl.FlowStack<Boolean JavaDoc> flowStack = threadLocal.get();
113             if (flowStack.size() == 0) {
114                 // Explicitly issue first startTime() only for the first
115
// Servlet or filter call, in the invocation path.
116
processBeforeDispatchEvent(event);
117             }
118             flowStack.push(Boolean.TRUE);
119             processBeforeServiceEvent(event);
120         } else if (event.getType().equals(InstanceEvent.AFTER_SERVICE_EVENT)) {
121             processAfterServiceEvent(event);
122             AgentImpl.FlowStack<Boolean JavaDoc> flowStack = threadLocal.get();
123             flowStack.pop();
124             if (flowStack.size() == 0) {
125                 // Explicitly issue the matching endTime() for the first
126
// Servlet or filter call, in the invocation path.
127
processAfterDispatchEvent(event);
128             }
129         } else if (event.getType().equals(InstanceEvent.BEFORE_FILTER_EVENT)) {
130             AgentImpl.FlowStack<Boolean JavaDoc> flowStack = threadLocal.get();
131             if (flowStack.size() == 0) {
132                 // Explicitly issue first startTime() only for the first
133
// Servlet or filter call, in the invocation path.
134
processBeforeDispatchEvent(event);
135             }
136             flowStack.push(Boolean.TRUE);
137             processBeforeFilterEvent(event);
138         } else if (event.getType().equals(InstanceEvent.AFTER_FILTER_EVENT)) {
139             processAfterFilterEvent(event);
140             AgentImpl.FlowStack<Boolean JavaDoc> flowStack = threadLocal.get();
141             flowStack.pop();
142             if (flowStack.size() == 0) {
143                 // Explicitly issue the matching endTime() for the first
144
// Servlet or filter call, in the invocation path.
145
processAfterDispatchEvent(event);
146             }
147         } else if (event.getType().
148                 equals(InstanceEvent.BEFORE_DISPATCH_EVENT)) {
149             processBeforeDispatchEvent(event);
150         } else if (event.getType().equals(InstanceEvent.AFTER_DISPATCH_EVENT)) {
151             processAfterDispatchEvent(event);
152         }
153     }
154     
155     private void processBeforeServiceEvent(InstanceEvent event) {
156
157         Servlet servlet = event.getServlet();
158         ServletConfig JavaDoc servletConfig = servlet.getServletConfig();
159         String JavaDoc servletName = "UNKNOWN";
160         if (servletConfig != null) {
161             servletName = servletConfig.getServletName();
162         }
163         
164         HttpServletRequest JavaDoc req = (HttpServletRequest JavaDoc) event.getRequest();
165         String JavaDoc methodName = req.getRequestURI() + ":";
166         if (!servlet.getClass().getName().equalsIgnoreCase(JSP_SERVLET)){
167                methodName += servlet.getClass().getName() + ".service";
168         } else {
169             // JSP
170
methodName += extractJSPName(req) +":" + JSP_SERVLET + ".service";
171         }
172         String JavaDoc callerPrincipal = req.getRemoteUser();
173         if (callerPrincipal == null) {
174             if (req.getUserPrincipal() != null) {
175                 callerPrincipal = req.getUserPrincipal().getName();
176             } else {
177                 callerPrincipal = "anonymous";
178             }
179         }
180
181         Wrapper wrapper = event.getWrapper();
182         String JavaDoc applicationName =
183                 ((StandardContext)wrapper.getParent()).getJ2EEApplication();
184         if ((applicationName == null) || (applicationName.equals("null"))) {
185             applicationName = "URI:" + req.getRequestURI();
186         }
187         String JavaDoc moduleName = wrapper.getParent().getName();
188          
189         callFlowAgent.webMethodStart(
190                 methodName, applicationName, moduleName,
191                 servletName, ComponentType.SERVLET,
192                 callerPrincipal);
193     }
194     
195     private void processAfterServiceEvent(InstanceEvent event) {
196         Throwable JavaDoc exception = event.getException();
197         callFlowAgent.webMethodEnd(exception);
198     }
199     
200     private void processBeforeFilterEvent(InstanceEvent event) {
201
202         Filter JavaDoc filter = event.getFilter();
203         
204         HttpServletRequest JavaDoc req = (HttpServletRequest JavaDoc) event.getRequest();
205         String JavaDoc methodName = req.getRequestURI() + ":" +
206                             filter.getClass().getName() + ".doFilter";
207         String JavaDoc callerPrincipal = req.getRemoteUser();
208         if (callerPrincipal == null) {
209             if (req.getUserPrincipal() != null) {
210                 callerPrincipal = req.getUserPrincipal().getName();
211             } else {
212                 callerPrincipal = "anonymous";
213             }
214         }
215         
216         Wrapper wrapper = event.getWrapper();
217         String JavaDoc applicationName =
218                 ((StandardContext)wrapper.getParent()).getJ2EEApplication();
219         if ((applicationName == null) || (applicationName.equals("null"))) {
220             applicationName = "URI:" + req.getRequestURI();
221         }
222         String JavaDoc moduleName = wrapper.getParent().getName();
223                 
224         callFlowAgent.webMethodStart(
225                 methodName, applicationName, moduleName,
226                 filter.getClass().getName(),
227                 ComponentType.SERVLET_FILTER, callerPrincipal);
228     }
229     
230     private void processAfterFilterEvent(InstanceEvent event) {
231         Throwable JavaDoc exception = event.getException();
232         callFlowAgent.webMethodEnd(exception);
233     }
234         
235     private void processBeforeDispatchEvent(InstanceEvent event) {
236         callFlowAgent.startTime(ContainerTypeOrApplicationType.WEB_CONTAINER);
237     }
238     
239     private void processAfterDispatchEvent(InstanceEvent event) {
240         callFlowAgent.endTime();
241     }
242     
243     /**
244      * Receive event from the Grizzly HTTP Connector.
245      * The ContainerEvent.getData() will return the current
246      * <code>RequestInfo</code>, which contains request information.
247      * @param event An instance of ContainerEvent.
248      */

249     public void containerEvent(ContainerEvent event) {
250
251         if (!callFlowAgent.isEnabled()) {
252             return;
253         }
254
255         Object JavaDoc obj = event.getData();
256         if (!(obj instanceof org.apache.coyote.RequestInfo)) {
257             return;
258         }
259         org.apache.coyote.RequestInfo
260                 requestInfo = (org.apache.coyote.RequestInfo) obj;
261         if (Adapter.CONNECTION_PROCESSING_STARTED.equals(event.getType())) {
262            requestStartTls.set (Boolean.TRUE);
263            callFlowAgent.requestStart(RequestType.REMOTE_WEB);
264            callFlowAgent.addRequestInfo(
265                             RequestInfo.CALLER_IP_ADDRESS,
266                             requestInfo.getRemoteAddr());
267         } else if (Adapter.REQUEST_PROCESSING_COMPLETED.
268                     equals(event.getType())) {
269            callFlowAgent.requestEnd();
270         }
271     }
272     
273     private String JavaDoc extractJSPName (HttpServletRequest JavaDoc request){
274   
275        String JavaDoc jspUri = null;
276
277        String JavaDoc jspFile = (String JavaDoc) request.getAttribute(Constants.JSP_FILE);
278        if (jspFile != null) {
279            // JSP is specified via <jsp-file> in <servlet> declaration
280
jspUri = jspFile;
281        } else {
282            /*
283             * Check to see if the requested JSP has been the target of a
284             * RequestDispatcher.include()
285             */

286            jspUri = (String JavaDoc) request.getAttribute(Constants.INC_SERVLET_PATH);
287            if (jspUri != null) {
288                /*
289                 * Requested JSP has been target of
290                 * RequestDispatcher.include(). Its path is assembled from the
291                 * relevant javax.servlet.include.* request attributes
292                 */

293                String JavaDoc pathInfo = (String JavaDoc) request.getAttribute(
294                                    "javax.servlet.include.path_info");
295                if (pathInfo != null) {
296                    jspUri += pathInfo;
297                }
298            } else {
299                /*
300                 * Requested JSP has not been the target of a
301                 * RequestDispatcher.include(). Reconstruct its path from the
302                 * request's getServletPath() and getPathInfo()
303                 */

304                jspUri = request.getServletPath();
305                String JavaDoc pathInfo = request.getPathInfo();
306                if (pathInfo != null) {
307                    jspUri += pathInfo;
308                }
309            }
310        }
311      return jspUri;
312     }
313 }
314
Popular Tags