001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.discovery.tools;
018:
019: import java.lang.reflect.Constructor;
020: import java.lang.reflect.InvocationTargetException;
021: import java.lang.reflect.Method;
022: import java.lang.reflect.Modifier;
023:
024: import org.apache.commons.discovery.DiscoveryException;
025:
026: import org.apache.commons.discovery.log.DiscoveryLogFactory;
027: import org.apache.commons.logging.Log;
028:
029: /**
030: * @author Richard A. Sitze
031: */
032: public class ClassUtils {
033: private static Log log = DiscoveryLogFactory
034: .newLog(ClassUtils.class);
035:
036: public static void setLog(Log _log) {
037: log = _log;
038: }
039:
040: /**
041: * Get package name.
042: * Not all class loaders 'keep' package information,
043: * in which case Class.getPackage() returns null.
044: * This means that calling Class.getPackage().getName()
045: * is unreliable at best.
046: */
047: public static String getPackageName(Class clazz) {
048: Package clazzPackage = clazz.getPackage();
049: String packageName;
050: if (clazzPackage != null) {
051: packageName = clazzPackage.getName();
052: } else {
053: String clazzName = clazz.getName();
054: packageName = clazzName.substring(0, clazzName
055: .lastIndexOf('.'));
056: }
057: return packageName;
058: }
059:
060: /**
061: * @return Method 'public static returnType methodName(paramTypes)',
062: * if found to be <strong>directly</strong> implemented by clazz.
063: */
064: public static Method findPublicStaticMethod(Class clazz,
065: Class returnType, String methodName, Class[] paramTypes) {
066: boolean problem = false;
067: Method method = null;
068:
069: // verify '<methodName>(<paramTypes>)' is directly in class.
070: try {
071: method = clazz.getDeclaredMethod(methodName, paramTypes);
072: } catch (NoSuchMethodException e) {
073: problem = true;
074: log.debug("Class " + clazz.getName() + ": missing method '"
075: + methodName + "(...)", e);
076: }
077:
078: // verify 'public static <returnType>'
079: if (!problem
080: && !(Modifier.isPublic(method.getModifiers())
081: && Modifier.isStatic(method.getModifiers()) && method
082: .getReturnType() == returnType)) {
083: if (log.isDebugEnabled()) {
084: if (!Modifier.isPublic(method.getModifiers())) {
085: log.debug(methodName + "() is not public");
086: }
087: if (!Modifier.isStatic(method.getModifiers())) {
088: log.debug(methodName + "() is not static");
089: }
090: if (method.getReturnType() != returnType) {
091: log.debug("Method returns: "
092: + method.getReturnType().getName() + "@@"
093: + method.getReturnType().getClassLoader());
094: log.debug("Should return: " + returnType.getName()
095: + "@@" + returnType.getClassLoader());
096: }
097: }
098: problem = true;
099: method = null;
100: }
101:
102: return method;
103: }
104:
105: /**
106: * Instantiate a new
107: */
108: public static Object newInstance(Class impl, Class paramClasses[],
109: Object params[]) throws DiscoveryException,
110: InstantiationException, IllegalAccessException,
111: NoSuchMethodException, InvocationTargetException {
112: if (paramClasses == null || params == null) {
113: return impl.newInstance();
114: } else {
115: Constructor constructor = impl.getConstructor(paramClasses);
116: return constructor.newInstance(params);
117: }
118: }
119:
120: /**
121: * Throws exception if <code>impl</code> does not
122: * implement or extend the SPI.
123: */
124: public static void verifyAncestory(Class spi, Class impl)
125: throws DiscoveryException {
126: if (spi == null) {
127: throw new DiscoveryException("No interface defined!");
128: }
129:
130: if (impl == null) {
131: throw new DiscoveryException(
132: "No implementation defined for " + spi.getName());
133: }
134:
135: if (!spi.isAssignableFrom(impl)) {
136: throw new DiscoveryException("Class " + impl.getName()
137: + " does not implement " + spi.getName());
138: }
139: }
140: }
|