KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > LogInterceptor


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb.plugins;
23
24 import java.io.PrintWriter JavaDoc;
25 import java.io.StringWriter JavaDoc;
26 import java.rmi.*;
27 import java.security.GeneralSecurityException JavaDoc;
28
29 import javax.ejb.EJBException JavaDoc;
30 import javax.ejb.NoSuchEntityException JavaDoc;
31 import javax.ejb.NoSuchObjectLocalException JavaDoc;
32 import javax.ejb.TransactionRolledbackLocalException JavaDoc;
33 import javax.ejb.AccessLocalException JavaDoc;
34 import javax.transaction.TransactionRolledbackException JavaDoc;
35
36
37 import org.jboss.invocation.Invocation;
38 import org.jboss.invocation.InvocationType;
39 import org.jboss.invocation.JBossLazyUnmarshallingException;
40 import org.jboss.metadata.BeanMetaData;
41
42 import org.jboss.tm.JBossTransactionRolledbackException;
43 import org.jboss.tm.JBossTransactionRolledbackLocalException;
44
45 /**
46  * An interceptor used to log all invocations. It also handles any
47  * unexpected exceptions.
48  *
49  * @author <a HREF="mailto:rickard.oberg@telkel.com">Rickard ´┐Żberg</a>
50  * @author <a HREF="mailto:Scott.Stark@jboss.org">Scott Stark</a>
51  * @author <a HREF="mailto:dain@daingroup.com">Dain Sundstrom</a>
52  * @author <a HREF="mailto:osh@sparre.dk">Ole Husgaard</a>
53  * @version $Revision: 43739 $
54  */

55 public class LogInterceptor extends AbstractInterceptor
56 {
57    // Static --------------------------------------------------------
58

59    // Attributes ----------------------------------------------------
60
protected String JavaDoc ejbName;
61    protected boolean callLogging;
62
63    // Constructors --------------------------------------------------
64

65    // Public --------------------------------------------------------
66

67    // Container implementation --------------------------------------
68
public void create()
69       throws Exception JavaDoc
70    {
71       super.start();
72
73       BeanMetaData md = getContainer().getBeanMetaData();
74       ejbName = md.getEjbName();
75
76       // Should we log call details
77
callLogging = md.getContainerConfiguration().getCallLogging();
78    }
79
80    /**
81     * This method logs the method, calls the next invoker, and handles
82     * any exception.
83     *
84     * @param invocation contain all infomation necessary to carry out the
85     * invocation
86     * @return the return value of the invocation
87     * @exception Exception if an exception during the invocation
88     */

89    public Object JavaDoc invokeHome(Invocation invocation)
90       throws Exception JavaDoc
91    {
92       String JavaDoc methodName;
93       if (invocation.getMethod() != null)
94       {
95          methodName = invocation.getMethod().getName();
96       }
97       else
98       {
99          methodName = "<no method>";
100       }
101
102       boolean trace = log.isTraceEnabled();
103       if (trace)
104       {
105          log.trace("Start method=" + methodName);
106       }
107
108       // Log call details
109
if (callLogging)
110       {
111          StringBuffer JavaDoc str = new StringBuffer JavaDoc("InvokeHome: ");
112          str.append(methodName);
113          str.append("(");
114          Object JavaDoc[] args = invocation.getArguments();
115          if (args != null)
116          {
117             for (int i = 0; i < args.length; i++)
118             {
119                if (i > 0)
120                {
121                   str.append(",");
122                }
123                str.append(args[i]);
124             }
125          }
126          str.append(")");
127          log.debug(str.toString());
128       }
129
130       try
131       {
132          return getNext().invokeHome(invocation);
133       }
134       catch(Throwable JavaDoc e)
135       {
136          throw handleException(e, invocation);
137       }
138       finally
139       {
140          if (trace)
141          {
142             log.trace("End method=" + methodName);
143          }
144       }
145    }
146
147    /**
148     * This method logs the method, calls the next invoker, and handles
149     * any exception.
150     *
151     * @param invocation contain all infomation necessary to carry out the
152     * invocation
153     * @return the return value of the invocation
154     * @exception Exception if an exception during the invocation
155     */

156    public Object JavaDoc invoke(Invocation invocation)
157       throws Exception JavaDoc
158    {
159       String JavaDoc methodName;
160       if (invocation.getMethod() != null)
161       {
162          methodName = invocation.getMethod().getName();
163       }
164       else
165       {
166          methodName = "<no method>";
167       }
168
169       boolean trace = log.isTraceEnabled();
170       if (trace)
171       {
172          log.trace("Start method=" + methodName);
173       }
174
175       // Log call details
176
if (callLogging)
177       {
178          StringBuffer JavaDoc str = new StringBuffer JavaDoc("Invoke: ");
179          if (invocation.getId() != null)
180          {
181             str.append("[");
182             str.append(invocation.getId().toString());
183             str.append("] ");
184          }
185          str.append(methodName);
186          str.append("(");
187          Object JavaDoc[] args = invocation.getArguments();
188          if (args != null)
189          {
190             for (int i = 0; i < args.length; i++)
191             {
192                if (i > 0)
193                {
194                   str.append(",");
195                }
196                str.append(args[i]);
197             }
198          }
199          str.append(")");
200          log.debug(str.toString());
201       }
202
203       try
204       {
205          return getNext().invoke(invocation);
206       }
207       catch(Throwable JavaDoc e)
208       {
209          throw handleException(e, invocation);
210       }
211       finally
212       {
213          if (trace)
214          {
215             log.trace("End method=" + methodName);
216          }
217       }
218    }
219
220    // Private -------------------------------------------------------
221

222    /**
223     PLEASE DO NOT CHANGE THIS CODE WITHOUT LOOKING AT __ALL__ OF IT TO MAKE ___SURE___
224     YOUR CHANGES ARE NECESSARY AND DO NOT BREAK LARGE AMOUNTS OF CORRECT BEHAVIOR!
225     PLEASE ADD A TEST TO DEMONSTRATE YOUR CHANGES FIX SOMETHING.
226     The rollback exceptions are tested by org.jboss.test.jca.test.XAExceptionUnitTestCase
227     * @param e - the exception thrown by the invocation
228     * @param invocation
229     * @return the correct exception to throw
230     */

231    private Exception JavaDoc handleException(Throwable JavaDoc e, Invocation invocation)
232    {
233
234       InvocationType type = invocation.getType();
235       boolean isLocal =
236             type == InvocationType.LOCAL ||
237             type == InvocationType.LOCALHOME;
238
239       if (e instanceof TransactionRolledbackLocalException JavaDoc ||
240             e instanceof TransactionRolledbackException JavaDoc)
241       {
242          // If we got a remote TransactionRolledbackException for a local
243
// invocation convert it into a TransactionRolledbackLocalException
244
if (isLocal && e instanceof TransactionRolledbackException JavaDoc)
245          {
246             TransactionRolledbackException JavaDoc remoteTxRollback =
247                   (TransactionRolledbackException JavaDoc)e;
248
249             Exception JavaDoc cause;
250             if (remoteTxRollback.detail instanceof Exception JavaDoc)
251             {
252                cause = (Exception JavaDoc)remoteTxRollback.detail;
253             }
254             else if (remoteTxRollback.detail instanceof Error JavaDoc)
255             {
256                String JavaDoc msg = formatException(
257                      "Unexpected Error",
258                      remoteTxRollback.detail);
259                cause = new EJBException JavaDoc(msg);
260             }
261             else
262             {
263                String JavaDoc msg = formatException(
264                      "Unexpected Throwable",
265                      remoteTxRollback.detail);
266                cause = new EJBException JavaDoc(msg);
267             }
268
269             e = new JBossTransactionRolledbackLocalException(
270                   remoteTxRollback.getMessage(),
271                   cause);
272          }
273
274          // If we got a local TransactionRolledbackLocalException for a remote
275
// invocation convert it into a TransactionRolledbackException
276
if (!isLocal && e instanceof TransactionRolledbackLocalException JavaDoc)
277          {
278             TransactionRolledbackLocalException JavaDoc localTxRollback =
279                   (TransactionRolledbackLocalException JavaDoc)e;
280             e = new JBossTransactionRolledbackException(
281                   localTxRollback.getMessage(), localTxRollback.getCausedByException());
282          }
283
284          // get the data we need for logging
285
Throwable JavaDoc cause = null;
286          String JavaDoc exceptionType = null;
287          if (e instanceof TransactionRolledbackException JavaDoc)
288          {
289             cause = ((TransactionRolledbackException JavaDoc)e).detail;
290             exceptionType = "TransactionRolledbackException";
291          }
292          else
293          {
294             cause =
295                ((TransactionRolledbackLocalException JavaDoc)e).getCausedByException();
296             exceptionType = "TransactionRolledbackLocalException";
297          }
298
299          // log the exception
300
if (cause != null)
301          {
302             // if the cause is an EJBException unwrap it for logging
303
if ((cause instanceof EJBException JavaDoc) &&
304                   (((EJBException JavaDoc) cause).getCausedByException() != null))
305             {
306                cause = ((EJBException JavaDoc) cause).getCausedByException();
307             }
308             log.error(exceptionType + " in method: " + invocation.getMethod()
309                + ", causedBy:", cause);
310          }
311          else
312          {
313             log.error(exceptionType + " in method: " + invocation.getMethod(), e);
314          }
315          return (Exception JavaDoc)e;
316       }
317       if (e instanceof NoSuchEntityException JavaDoc)
318       {
319          NoSuchEntityException JavaDoc noSuchEntityException =
320                (NoSuchEntityException JavaDoc) e;
321          if (noSuchEntityException.getCausedByException() != null)
322          {
323             log.error("NoSuchEntityException in method: " + invocation.getMethod() + ", causedBy:",
324                   noSuchEntityException.getCausedByException());
325          }
326          else
327          {
328             log.error("NoSuchEntityException in method: " + invocation.getMethod() + ":", noSuchEntityException);
329          }
330
331          if (isLocal)
332          {
333             return new NoSuchObjectLocalException JavaDoc(
334                   noSuchEntityException.getMessage(),
335                   noSuchEntityException.getCausedByException());
336          }
337          else
338          {
339             NoSuchObjectException noSuchObjectException =
340                   new NoSuchObjectException(noSuchEntityException.getMessage());
341             noSuchObjectException.detail = noSuchEntityException;
342             return noSuchObjectException;
343          }
344       }
345       if (e instanceof EJBException JavaDoc)
346       {
347          EJBException JavaDoc ejbException = (EJBException JavaDoc) e;
348          if (ejbException.getCausedByException() != null)
349          {
350             log.error("EJBException in method: " + invocation.getMethod() + ", causedBy:",
351                   ejbException.getCausedByException());
352          }
353          else
354          {
355             log.error("EJBException in method: " + invocation.getMethod() + ":", ejbException);
356          }
357
358          if (isLocal)
359          {
360             return ejbException;
361          }
362          else
363          {
364             // Remote invocation need a remote exception
365
return new ServerException("EJBException:", ejbException);
366          }
367       }
368
369       /* Handle SecurityExceptions specially to tranform into one of the
370          security related ejb or rmi exceptions to allow users to identitify
371          them more easily.
372       */

373       if (e instanceof SecurityException JavaDoc || e instanceof GeneralSecurityException JavaDoc)
374       {
375          Exception JavaDoc runtimeException = (Exception JavaDoc)e;
376          if( log.isTraceEnabled() )
377             log.trace("SecurityException in method: " + invocation.getMethod() + ":", runtimeException);
378          if( isAppException(invocation, e) )
379          {
380             return runtimeException;
381          }
382          else if (isLocal)
383          {
384             return new AccessLocalException JavaDoc("SecurityException", runtimeException);
385          }
386          else
387          {
388             return new AccessException("SecurityException", runtimeException);
389          }
390       }
391
392       // handle unmarshalling exception which should only come if problem unmarshalling
393
// invocation payload, arguments, or value on remote end.
394
if(e instanceof JBossLazyUnmarshallingException)
395       {
396          RuntimeException JavaDoc runtimeException = (RuntimeException JavaDoc)e;
397          log.error("UnmarshalException:", e);
398
399          if(isLocal)
400          {
401             return new EJBException JavaDoc("UnmarshalException", runtimeException);
402          }
403          else
404          {
405             return new MarshalException("MarshalException", runtimeException);
406          }
407       }
408
409       // All other RuntimeException
410
if (e instanceof RuntimeException JavaDoc)
411       {
412          RuntimeException JavaDoc runtimeException = (RuntimeException JavaDoc)e;
413          log.error("RuntimeException in method: " + invocation.getMethod() + ":", runtimeException);
414
415          if (isLocal)
416          {
417             return new EJBException JavaDoc("RuntimeException", runtimeException);
418          }
419          else
420          {
421             return new ServerException("RuntimeException", runtimeException);
422          }
423       }
424       if (e instanceof Error JavaDoc)
425       {
426          log.error("Unexpected Error in method: " + invocation.getMethod(), e);
427          if (isLocal)
428          {
429             String JavaDoc msg = formatException("Unexpected Error", e);
430             return new EJBException JavaDoc(msg);
431          }
432          else
433          {
434             return new ServerError("Unexpected Error", (Error JavaDoc)e);
435          }
436       }
437
438       // If we got a RemoteException for a local invocation wrap it
439
// in an EJBException.
440
if(isLocal && e instanceof RemoteException)
441       {
442          if (callLogging)
443          {
444             log.info("Remote Exception in method: " + invocation.getMethod(), e);
445          }
446          return new EJBException JavaDoc((RemoteException)e);
447       }
448
449       if (e instanceof Exception JavaDoc)
450       {
451          if (callLogging)
452          {
453             log.info("Application Exception in method: " + invocation.getMethod(), e);
454          }
455          return (Exception JavaDoc)e;
456       }
457       else
458       {
459          // The should not happen
460
String JavaDoc msg = formatException("Unexpected Throwable", e);
461          log.warn("Unexpected Throwable in method: " + invocation.getMethod(), e);
462          if (isLocal)
463          {
464             return new EJBException JavaDoc(msg);
465          }
466          else
467          {
468             return new ServerException(msg);
469          }
470       }
471    }
472
473    private String JavaDoc formatException(String JavaDoc msg, Throwable JavaDoc t)
474    {
475       StringWriter JavaDoc sw = new StringWriter JavaDoc();
476       PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
477       if (msg != null)
478          pw.println(msg);
479       if (t != null)
480       {
481          t.printStackTrace(pw);
482       } // end of if ()
483
return sw.toString();
484    }
485
486 }
487
Popular Tags