View Javadoc

1   
2   /*
3    * Copyright (C) 2005 by Arno Schumacher
4    *
5    * This file is part of net.sourceforge.servletspy
6    *
7    * net.sourceforge.servletspy is free software; you can redistribute
8    * it and/or modify it under the terms of the GNU General Public 
9    * License as published by the Free Software Foundation; either 
10   * version 2, or (at your option) any later version.
11   *
12   * net.sourceforge.servletspy is distributed in the hope that it will
13   * be useful, but WITHOUT ANY WARRANTY; without even the implied 
14   * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
15   * See the GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, write to the Free Software
19   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA 
20   */
21  
22  package net.sourceforge.servletspy.handler.container;
23  
24  import java.beans.BeanInfo;
25  import java.beans.Introspector;
26  import java.beans.PropertyDescriptor;
27  import java.lang.reflect.Method;
28  import java.lang.reflect.Modifier;
29  import java.lang.reflect.Proxy;
30  import java.util.Collection;
31  
32  import net.sourceforge.servletspy.IContext;
33  import net.sourceforge.servletspy.handler.base.AbstractHandler;
34  import net.sourceforge.servletspy.util.ClassUtil;
35  import net.sourceforge.servletspy.config.Param;
36  
37  
38  /***
39   * @author arno schumacher
40   */
41  public final class DynamicProxyTransformer extends AbstractHandler {
42  
43      public static final String SKIP_COLLECTIONS = "SKIP_COLLECTIONS";
44      private boolean skipCollections = true;
45  
46      /***
47       * Constructor.
48       */
49      public DynamicProxyTransformer() {
50      }
51  
52      /* (non-Javadoc)
53       * @see net.sourceforge.servletspy.IContextHandler#handle(net.sourceforge.servletspy.IContext)
54       */
55      public final void handle(final IContext context) throws Exception {
56  
57          // TODO similar code in AbstractInterfacesHandler, find a common soulution.
58  
59          final Class clazz = context.getSubject().getClass();
60          if (Proxy.isProxyClass(clazz)) {
61              context.setValue(ClassUtil.getClassName(clazz));
62              final BeanInfo beanInfo = Introspector.getBeanInfo(clazz, clazz
63                      .isInterface() ? null : Object.class);
64              final PropertyDescriptor[] apd = beanInfo.getPropertyDescriptors();
65              for (int i = 0; i < apd.length; i++) {
66                  final PropertyDescriptor pd = apd[i];
67                  final Method m = pd.getReadMethod();
68                  final Class clazzType = pd.getPropertyType();
69                  if (m == null) {
70                      continue;
71                  }
72                  // Readers with parameter, i.e. indexed properties.
73                  if (m.getParameterTypes().length > 0) {
74                      continue;
75                  }
76                  // Exclude null types, just in case there exists an
77                  // 'invalid' user defined property descriptor.
78                  if (clazzType == null) {
79                      continue;
80                  }
81                  if (!Modifier.isPublic(m.getModifiers())
82                          || Modifier.isStatic(m.getModifiers())) {
83                      continue;
84                  }
85                  
86                  if ( Collection.class.isAssignableFrom( clazzType ) && skipCollections ) {
87                      continue;
88                  }
89  
90                  // Guess the name of the property ...
91                  final String mName = m.getName();
92                  String key = null;
93                  if (mName.startsWith("get") && mName.length() > 3) {
94                      key = Introspector.decapitalize(mName.substring(3));
95                  }
96                  if (mName.startsWith("is") && mName.length() > 2) {
97                      key = Introspector.decapitalize(mName.substring(2));
98                  }
99                  final Object prop = m.invoke(context.getSubject(),
100                         new Object[0]);
101                 context.add(key, prop);
102             }
103         }
104         else {
105             context.proceed();
106         }
107     }
108 
109     /*
110      * (non-Javadoc)
111      *
112      * @see net.sourceforge.servletspy.ILifecycle#init(net.sourceforge.servletspy.config.Param[])
113      */
114     public void init(final Param[] params) {
115         
116         // TODO Refactor initialization 
117         
118         for (int i = 0; i < params.length; i++) {
119             if (SKIP_COLLECTIONS.equals(params[i].getName())) {
120                 try {
121                     skipCollections = ! "FALSE".equalsIgnoreCase( params[i].getValue() );
122                     return;
123                 } catch (Exception e) {
124                     skipCollections = true;
125                 }
126             }
127         }
128     }
129 }