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.discovery.tools;
18  
19  import java.lang.reflect.Constructor;
20  import java.lang.reflect.InvocationTargetException;
21  import java.lang.reflect.Method;
22  import java.lang.reflect.Modifier;
23  
24  import org.apache.commons.discovery.DiscoveryException;
25  
26  import org.apache.commons.discovery.log.DiscoveryLogFactory;
27  import org.apache.commons.logging.Log;
28  
29  
30  /***
31   * @author Richard A. Sitze
32   */
33  public class ClassUtils {
34      private static Log log = DiscoveryLogFactory.newLog(ClassUtils.class);
35      public static void setLog(Log _log) {
36          log = _log;
37      }
38  
39      /***
40       * Get package name.
41       * Not all class loaders 'keep' package information,
42       * in which case Class.getPackage() returns null.
43       * This means that calling Class.getPackage().getName()
44       * is unreliable at best.
45       */
46      public static String getPackageName(Class clazz) {
47          Package clazzPackage = clazz.getPackage();
48          String packageName;
49          if (clazzPackage != null) {
50              packageName = clazzPackage.getName();
51          } else {
52              String clazzName = clazz.getName();
53              packageName = clazzName.substring(0, clazzName.lastIndexOf('.'));
54          }
55          return</strong> packageName;
56      }
57      
58      /***
59       * @return Method 'public static returnType methodName(paramTypes)',
60       *         if found to be <strong>directly</strong> implemented by clazz.
61       */
62      public static Method findPublicStaticMethod(Class clazz,
63                                                  Class returnType,
64                                                  String methodName,
65                                                  Class[] paramTypes) {
66          boolean problem = false;
67          Method method = null;
68  
69          // verify '<methodName>(<paramTypes>)' is directly in class.
70          try {
71              method = clazz.getDeclaredMethod(methodName, paramTypes);
72          } catch(NoSuchMethodException e) {
73              problem = true;
74              log.debug("Class " + clazz.getName() + ": missing method '" + methodName + "(...)", e);
75          }
76          
77          // verify 'public static <returnType>'
78          if (!problem  &&
79              !(Modifier.isPublic(method.getModifiers()) &&
80                Modifier.isStatic(method.getModifiers()) &&
81                method.getReturnType() == returnType)) {
82              if (log.isDebugEnabled()) {
83                  if (!Modifier.isPublic(method.getModifiers())) {
84                      log.debug(methodName + "() is not public");
85                  }
86                  if (!Modifier.isStatic(method.getModifiers())) {
87                      log.debug(methodName + "() is not static");
88                  }
89                  if (method.getReturnType() != returnType) {
90                      log.debug("Method returns: " + method.getReturnType().getName() + "@@" + method.getReturnType().getClassLoader());
91                      log.debug("Should return:  " + returnType.getName() + "@@" + returnType.getClassLoader());
92                  }
93              }
94              problem = true;
95              method = null;
96          }
97          
98          return method;
99      }
100 
101     /***
102      * Instantiate a new 
103      */    
104     public static Object newInstance(Class impl, Class paramClasses[], Object params[])
105         throws DiscoveryException,
106                InstantiationException,
107                IllegalAccessException,
108                NoSuchMethodException,
109                InvocationTargetException
110     {
111         if (paramClasses == null || params == null) {
112             return impl.newInstance();
113         } else {
114             Constructor constructor = impl.getConstructor(paramClasses);
115             return constructor.newInstance(params);
116         }
117     }
118     
119     /***
120      * Throws exception if <code>impl</code> does not
121      * implement or extend the SPI.
122      */
123     public static void verifyAncestory(Class spi, Class impl)
124         throws DiscoveryException
125     {
126         if (spi == null) {
127             throw new DiscoveryException("No interface defined!");
128         }
129 
130         if (impl == null) {
131             throw new DiscoveryException("No implementation defined for " + spi.getName());
132         }
133 
134         if (!spi.isAssignableFrom(impl)) {
135             throw new DiscoveryException("Class " + impl.getName() +
136                                          " does not implement " + spi.getName());
137         }
138     }
139 }