View Javadoc

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.commons.javaflow.utils;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.ByteArrayOutputStream;
21  import java.io.IOException;
22  import java.io.ObjectInputStream;
23  import java.io.ObjectOutputStream;
24  import java.lang.reflect.Field;
25  import java.lang.reflect.Method;
26  import java.util.HashMap;
27  import java.util.Map;
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  
31  /**
32   * @author tcurdt
33   *
34   */
35  public final class ReflectionUtils {
36      
37      private final static Log log = LogFactory.getLog(ReflectionUtils.class);
38      
39  	public interface Matcher {
40          boolean matches(final String pName);
41      }
42  	    
43      public interface Indexer {
44          void put(final Map pMap, final String pKey, final Object pObject);
45      }
46  	    
47      private static Indexer defaultIndexer = new DefaultIndexer();
48      private static Matcher defaultMatcher = new DefaultMatcher();
49  	    
50      public static class DefaultMatcher implements Matcher {
51          public boolean matches(final String pName) {
52              return true;
53          }
54      }
55  
56      public static class DefaultIndexer implements Indexer {
57          public void put(final Map pMap, final String pKey, final Object pObject) {
58              pMap.put(pKey, pObject);
59          }
60      }
61  	    
62      public static Map discoverFields(
63              final Class pClazz,
64              final Matcher pMatcher
65              ) {
66          
67          return discoverFields(pClazz, pMatcher, defaultIndexer);
68      }
69  
70      public static Map discoverFields(
71              final Class pClazz
72              ) {
73          
74          return discoverFields(pClazz, defaultMatcher, defaultIndexer);
75      }
76      
77      public static Map discoverFields(
78              final Class pClazz,
79              final Matcher pMatcher,
80              final Indexer pIndexer
81              ) {
82          
83          log.debug("discovering fields on " + pClazz.getName());
84          
85          final Map result = new HashMap();
86  
87          Class current = pClazz;
88          do {
89              final Field[] fields = current.getDeclaredFields();
90              for (int i = 0; i < fields.length; i++) {
91                  final String fname = fields[i].getName();
92                  if (pMatcher.matches(fname)) {
93                      pIndexer.put(result, fname, fields[i]);
94                      
95                      log.debug("discovered field " + fname + " -> " + fields[i]);
96                  }
97              }
98              current = current.getSuperclass();
99          } while(current != null);
100      
101         return result;
102     }    
103 
104     
105     public static Map discoverMethods(
106             final Class pClazz,
107             final Matcher pMatcher
108             ) {
109         
110         return discoverMethods(pClazz, pMatcher, defaultIndexer);
111     }
112 
113     public static Map discoverMethods(
114             final Class pClazz
115             ) {
116         
117         return discoverMethods(pClazz, defaultMatcher, defaultIndexer);
118     }
119     
120     public static Map discoverMethods(
121             final Class pClazz,
122             final Matcher pMatcher,
123             final Indexer pIndexer
124             ) {
125         
126         log.debug("discovering methods on " + pClazz.getName());
127         
128         final Map result = new HashMap();
129 
130         Class current = pClazz;
131         do {
132             final Method[] methods = current.getDeclaredMethods();
133             for (int i = 0; i < methods.length; i++) {
134                 final String mname = methods[i].getName();
135                 if (pMatcher.matches(mname)) {
136                     pIndexer.put(result, mname, methods[i]);
137 
138                     log.debug("discovered method " + mname + " -> " + methods[i]);
139                 }
140             }
141             current = current.getSuperclass();
142         } while(current != null);
143      
144         return result;
145     }    
146 
147     public static Object cast(Object o) throws IOException, ClassNotFoundException {
148         final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
149         final ObjectOutputStream oos = new ObjectOutputStream(buffer);
150         oos.writeObject(o);
151         oos.flush();
152         final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));
153         return ois.readObject();
154       }
155     
156     public static String getClassName(final Object o) {
157         if (o == null) {
158             return "unknown";
159         }
160         
161         return o.getClass().getName() + "@" + o.hashCode();
162     }
163 
164     public static String getClassLoaderName(final Object o) {
165         if (o == null) {
166             return "unknown";
167         }
168         
169         return getClassName(o.getClass().getClassLoader());
170     }
171 }