1 /*
2 * ====================
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 *
5 * Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved.
6 *
7 * The contents of this file are subject to the terms of the Common Development
8 * and Distribution License("CDDL") (the "License"). You may not use this file
9 * except in compliance with the License.
10 *
11 * You can obtain a copy of the License at
12 * http://IdentityConnectors.dev.java.net/legal/license.txt
13 * See the License for the specific language governing permissions and limitations
14 * under the License.
15 *
16 * When distributing the Covered Code, include this CDDL Header Notice in each file
17 * and include the License file at identityconnectors/legal/license.txt.
18 * If applicable, add the following below this CDDL Header, with the fields
19 * enclosed by brackets [] replaced by your own identifying information:
20 * "Portions Copyrighted [year] [name of copyright owner]"
21 * ====================
22 */
23 package org.identityconnectors.common;
24
25 import java.lang.reflect.Method;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Set;
31
32 public class ReflectionUtil {
33
34 /**
35 * Never allow this to be instantiated.
36 */
37 private ReflectionUtil() {
38 throw new AssertionError();
39 }
40
41 /**
42 * Builds a {@link Set} of interfaces from the target class.
43 */
44 public static Set<Class<?>> getAllInterfaces(final Class<?> target) {
45 assert target != null;
46 Set<Class<?>> ret = new HashSet<Class<?>>();
47 getAllInteralInterfaces(target, ret);
48 return ret;
49 }
50
51 private static void getAllInteralInterfaces(final Class<?> target,
52 final Set<Class<?>> result) {
53 // quick exit if target is null..
54 if (target != null) {
55 // get all the interfaces of the target class..
56 for (Class<?> inter : target.getInterfaces()) {
57 result.add(inter);
58 }
59 // get all the interfaces of the super class..
60 getAllInteralInterfaces(target.getSuperclass(), result);
61 }
62 }
63
64 /**
65 * Determine if the target class implements the provided interface.
66 *
67 * @param target
68 * class to look through for a matching interface.
69 * @param clazz
70 * interface class to look for.
71 * @return true if a matching interface is found otherwise false.
72 */
73 public static boolean containsInterface(final Class<?> target,
74 final Class<?> clazz) {
75 return clazz.isAssignableFrom(target);
76 }
77
78 /**
79 * Get all interfaces the extends the type provided.
80 */
81 public static <T> List<Class<? extends T>> getInterfaces(
82 final Class<?> target, final Class<T> type) {
83 List<Class<? extends T>> ret = new ArrayList<Class<? extends T>>();
84 Collection<Class<?>> interfs = getAllInterfaces(target);
85 for (Class<?> clazz : interfs) {
86 if (containsInterface(clazz, type)) {
87 @SuppressWarnings("unchecked")
88 Class<? extends T> o = (Class<? extends T>) clazz;
89 ret.add(o);
90 }
91 }
92 return ret;
93 }
94
95 /**
96 * Returns true iff the given class overrides equals and hashCode
97 * @param clazz The class to check.
98 * @return True iff the given class overrides equals and hashCode
99 */
100 public static boolean overridesEqualsAndHashcode(Class<?> clazz) {
101 try {
102 Method equals = clazz.getMethod("equals", Object.class);
103 if (equals.getDeclaringClass() == Object.class) {
104 return false;
105 }
106 Method hashCode = clazz.getMethod("hashCode");
107 if (hashCode.getDeclaringClass() == Object.class) {
108 return false;
109 }
110 return true;
111 }
112 catch (RuntimeException e) {
113 throw e;
114 }
115 catch (Exception e) {
116 //this should never happen
117 throw new RuntimeException(e);
118 }
119 }
120
121 /**
122 * Returns the package the class is associated with.
123 *
124 * @param clazz
125 * class to inspect for the package.
126 * @return package for the class provided.
127 * @throws NullPointerException
128 * iff clazz is <code>null</code>.
129 */
130 public static String getPackage(Class<?> clazz) {
131 String name = clazz.getName();
132 return name.substring(0, name.lastIndexOf('.'));
133 }
134
135 /**
136 * Determine the method name for the calling class.
137 */
138 public static String getMethodName(int depth) {
139 // Hack (?) to get the stack trace.
140 Throwable dummyException = new Throwable();
141 StackTraceElement locations[] = dummyException.getStackTrace();
142 // caller will be the depth element
143 String method = "unknown";
144 if (locations != null && locations.length > depth) {
145 StackTraceElement caller = locations[depth];
146 method = caller.getMethodName();
147 }
148 return method;
149 }
150 }