Project Report: fawkez

Packagesummary org.jcoderz.commons.util

org.jcoderz.commons.util.LoggingProxy

LineHitsNoteSource
1  /*
2   * $Id: LoggingProxy.java 1559 2009-10-08 19:39:07Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.commons.util;
34  
35  import java.lang.reflect.InvocationHandler;
36  import java.lang.reflect.InvocationTargetException;
37  import java.lang.reflect.Method;
38  import java.lang.reflect.Proxy;
39  import java.util.Arrays;
40  import java.util.HashSet;
41  import java.util.Set;
42  import java.util.logging.Level;
43  import java.util.logging.Logger;
44  
45  /**
46   * <p>
47   * This class can be used to proxy any object, providing entering and
48   * exiting logging for all <i>interfaces</i> of the object.
49   * </p>
50   * <p>
51   * <b>Note:</b> Java Dynamic Proxies only work on <i>interfaces</i>.
52   * The object returned by the {@link #getProxy(Object)} can be cast to
53   * any interface implemented by the argument or one of its ancestors. It
54   * can't, however, be cast to an implementation class.
55   * </p>
56   *
57   * @author Albrecht Messner
58   * @author Andreas Mandel
59   */
60  public final class LoggingProxy
61        implements InvocationHandler
62  {
63     private final Object mRealObject;
64     private final String mRealObjectClassName;
65     private final Logger mObjectLogger;
66  
67     /**
68      * Create a proxy that directs all calls to the real object and logs all
69      * method calls with entering/exiting/throwing, using the given logger.
70      *
71      * @param realObject the object for which a proxy is created
72      * @param logger the logger to which calls are logged
73      */
74     private LoggingProxy (Object realObject, Logger logger)
750    {
760       mRealObject = realObject;
770       mRealObjectClassName = mRealObject.getClass().getName();
780       mObjectLogger = logger;
790    }
80  
81     /**
82      * Static factory that wraps an object into a proxy depending on the
83      * log level for that object.
84      *
85      * @param obj an object for which a proxy should be created
86      * @return a logging proxy for the obj, if the log level for that
87      *       object is FINER or finest, the object itself otherwise
88      */
89     public static Object getProxy (Object obj)
90     {
910       final String classname = obj.getClass().getName();
920       final Logger logger = Logger.getLogger(classname);
93  
94        final Object proxy;
950       if (logger.isLoggable(Level.FINER))
96        {
97           // collect all interfaces implemented by this objects class and
98           // its super classes
99           // Note: Ne do not add super-interfaces here....
1000          final Set interfaces = new HashSet();
1010          Class currentClass = obj.getClass();
1020          while (currentClass != null)
103           {
1040             interfaces.addAll(Arrays.asList(currentClass.getInterfaces()));
1050             currentClass = currentClass.getSuperclass();
106           }
107  
1080          proxy = Proxy.newProxyInstance(
109                 obj.getClass().getClassLoader(),
110                 (Class[]) interfaces.toArray(new Class[interfaces.size()]),
111                 new LoggingProxy(obj, logger));
1120       }
113        else
114        {
1150          proxy = obj;
116        }
1170       return proxy;
118     }
119  
120     /**
121      * Log the entering, exiting and throwing events of the proxied object.
122      *
123      * @see java.lang.reflect.InvocationHandler#invoke(
124      *       java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
125      */
126 (1)(2)(3)(4)   public Object invoke (Object proxy, Method method, Object[] args)
127 (5)         throws Throwable
128     {
1290       final boolean isLoggable = mObjectLogger.isLoggable(Level.FINER);
130  
1310       if (isLoggable)
132        {
1330          if (args == null)
134           {
1350             mObjectLogger.entering(mRealObjectClassName, method.getName());
136           }
137           else
138           {
1390             final Object[] args2 = new Object[args.length];
1400             for (int i = 0; i < args.length; i++)
141              {
1420                 if (args[i] != null && args[i].getClass().isArray())
143                  {
1440                     args2[i] = ArraysUtil.toString(args[i]);
145                  }
146                  else
147                  {
1480(6)                    args2[i] = args[i];
149                  }
150              }
1510             mObjectLogger.entering(
152                    mRealObjectClassName, method.getName(), args2);
153           }
154        }
155  
1560       final Object result = invokeMethod(method, args, isLoggable);
157  
1580       if (isLoggable)
159        {
1600          if (result != null || method.getReturnType() != Void.TYPE)
161           {
1620            mObjectLogger.exiting(
163                   mRealObjectClassName, method.getName(),
164                   ArraysUtil.toString(result));
165           }
166           else
167           {
1680            mObjectLogger.exiting(mRealObjectClassName, method.getName());
169           }
170        }
171  
1720       return result;
173     }
174  
175     private Object invokeMethod (Method method, Object[] args,
176           boolean isLoggable)
177           throws Throwable
178     {
179        final Object result;
180        try
181        {
1820          result = method.invoke(mRealObject, args);
183        }
1840       catch (InvocationTargetException x)
185        {
1860          if (isLoggable)
187           {
1880             mObjectLogger.throwing(
189                    mRealObjectClassName, method.getName(), x.getCause());
190           }
1910(7)         throw x.getCause();
192        }
1930       catch (Exception x)
194        {
1950          if (isLoggable)
196           {
1970             mObjectLogger.throwing(mRealObjectClassName, method.getName(), x);
198           }
1990          throw x;
2000       }
2010       return result;
202     }
203  }

Findings in this File

f (8) Class contains more than one logger. Ok.
f (9) The Logger variable declaration does not contain the static and final modifiers Ok.
c (1) 126 : 0 Expected an @return tag.
c (2) 126 : 33 Expected @param tag for 'proxy'.
c (3) 126 : 47 Expected @param tag for 'method'.
c (4) 126 : 64 Expected @param tag for 'args'.
c (5) 127 : 17 Expected @throws tag for 'Throwable'.
w (6) 148 : 0 method org.jcoderz.commons.util.LoggingProxy.invoke(Object, Method, Object[]) copies arrays manually
w (7) 191 : 0 Method org.jcoderz.commons.util.LoggingProxy.invokeMethod(Method, Object[], boolean) throws alternative exception from catch block without history