提交 f71d93e2 编写于 作者: O ohair

Merge

...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
package com.sun.jmx.mbeanserver; package com.sun.jmx.mbeanserver;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.ref.SoftReference;
import java.lang.reflect.AnnotatedElement; import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
...@@ -33,8 +34,13 @@ import java.lang.reflect.Modifier; ...@@ -33,8 +34,13 @@ import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException; import java.lang.reflect.UndeclaredThrowableException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap;
import javax.management.Descriptor; import javax.management.Descriptor;
import javax.management.DescriptorKey; import javax.management.DescriptorKey;
...@@ -506,11 +512,25 @@ public class Introspector { ...@@ -506,11 +512,25 @@ public class Introspector {
} else { } else {
// Java Beans introspection // Java Beans introspection
// //
BeanInfo bi = java.beans.Introspector.getBeanInfo(complex.getClass()); Class<?> clazz = complex.getClass();
PropertyDescriptor[] pds = bi.getPropertyDescriptors(); Method readMethod = null;
for (PropertyDescriptor pd : pds) if (BeansHelper.isAvailable()) {
if (pd.getName().equals(element)) Object bi = BeansHelper.getBeanInfo(clazz);
return pd.getReadMethod().invoke(complex); Object[] pds = BeansHelper.getPropertyDescriptors(bi);
for (Object pd: pds) {
if (BeansHelper.getPropertyName(pd).equals(element)) {
readMethod = BeansHelper.getReadMethod(pd);
break;
}
}
} else {
// Java Beans not available so use simple introspection
// to locate method
readMethod = SimpleIntrospector.getReadMethod(clazz, element);
}
if (readMethod != null)
return readMethod.invoke(complex);
throw new AttributeNotFoundException( throw new AttributeNotFoundException(
"Could not find the getter method for the property " + "Could not find the getter method for the property " +
element + " using the Java Beans introspector"); element + " using the Java Beans introspector");
...@@ -524,4 +544,235 @@ public class Introspector { ...@@ -524,4 +544,235 @@ public class Introspector {
new AttributeNotFoundException(e.getMessage()), e); new AttributeNotFoundException(e.getMessage()), e);
} }
} }
/**
* A simple introspector that uses reflection to analyze a class and
* identify its "getter" methods. This class is intended for use only when
* Java Beans is not present (which implies that there isn't explicit
* information about the bean available).
*/
private static class SimpleIntrospector {
private SimpleIntrospector() { }
private static final String GET_METHOD_PREFIX = "get";
private static final String IS_METHOD_PREFIX = "is";
// cache to avoid repeated lookups
private static final Map<Class<?>,SoftReference<List<Method>>> cache =
Collections.synchronizedMap(
new WeakHashMap<Class<?>,SoftReference<List<Method>>> ());
/**
* Returns the list of methods cached for the given class, or {@code null}
* if not cached.
*/
private static List<Method> getCachedMethods(Class<?> clazz) {
// return cached methods if possible
SoftReference<List<Method>> ref = cache.get(clazz);
if (ref != null) {
List<Method> cached = ref.get();
if (cached != null)
return cached;
}
return null;
}
/**
* Returns {@code true} if the given method is a "getter" method (where
* "getter" method is a public method of the form getXXX or "boolean
* isXXX")
*/
static boolean isReadMethod(Method method) {
// ignore static methods
int modifiers = method.getModifiers();
if (Modifier.isStatic(modifiers))
return false;
String name = method.getName();
Class<?>[] paramTypes = method.getParameterTypes();
int paramCount = paramTypes.length;
if (paramCount == 0 && name.length() > 2) {
// boolean isXXX()
if (name.startsWith(IS_METHOD_PREFIX))
return (method.getReturnType() == boolean.class);
// getXXX()
if (name.length() > 3 && name.startsWith(GET_METHOD_PREFIX))
return (method.getReturnType() != void.class);
}
return false;
}
/**
* Returns the list of "getter" methods for the given class. The list
* is ordered so that isXXX methods appear before getXXX methods - this
* is for compatability with the JavaBeans Introspector.
*/
static List<Method> getReadMethods(Class<?> clazz) {
// return cached result if available
List<Method> cachedResult = getCachedMethods(clazz);
if (cachedResult != null)
return cachedResult;
// get list of public methods, filtering out methods that have
// been overridden to return a more specific type.
List<Method> methods =
StandardMBeanIntrospector.getInstance().getMethods(clazz);
methods = MBeanAnalyzer.eliminateCovariantMethods(methods);
// filter out the non-getter methods
List<Method> result = new LinkedList<Method>();
for (Method m: methods) {
if (isReadMethod(m)) {
// favor isXXX over getXXX
if (m.getName().startsWith(IS_METHOD_PREFIX)) {
result.add(0, m);
} else {
result.add(m);
}
}
}
// add result to cache
cache.put(clazz, new SoftReference<List<Method>>(result));
return result;
}
/**
* Returns the "getter" to read the given property from the given class or
* {@code null} if no method is found.
*/
static Method getReadMethod(Class<?> clazz, String property) {
// first character in uppercase (compatability with JavaBeans)
property = property.substring(0, 1).toUpperCase(Locale.ENGLISH) +
property.substring(1);
String getMethod = GET_METHOD_PREFIX + property;
String isMethod = IS_METHOD_PREFIX + property;
for (Method m: getReadMethods(clazz)) {
String name = m.getName();
if (name.equals(isMethod) || name.equals(getMethod)) {
return m;
}
}
return null;
}
}
/**
* A class that provides access to the JavaBeans Introspector and
* PropertyDescriptors without creating a static dependency on java.beans.
*/
private static class BeansHelper {
private static final Class<?> introspectorClass =
getClass("java.beans.Introspector");
private static final Class<?> beanInfoClass =
(introspectorClass == null) ? null : getClass("java.beans.BeanInfo");
private static final Class<?> getPropertyDescriptorClass =
(beanInfoClass == null) ? null : getClass("java.beans.PropertyDescriptor");
private static final Method getBeanInfo =
getMethod(introspectorClass, "getBeanInfo", Class.class);
private static final Method getPropertyDescriptors =
getMethod(beanInfoClass, "getPropertyDescriptors");
private static final Method getPropertyName =
getMethod(getPropertyDescriptorClass, "getName");
private static final Method getReadMethod =
getMethod(getPropertyDescriptorClass, "getReadMethod");
private static Class<?> getClass(String name) {
try {
return Class.forName(name, true, null);
} catch (ClassNotFoundException e) {
return null;
}
}
private static Method getMethod(Class<?> clazz,
String name,
Class<?>... paramTypes)
{
if (clazz != null) {
try {
return clazz.getMethod(name, paramTypes);
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
} else {
return null;
}
}
private BeansHelper() { }
/**
* Returns {@code true} if java.beans is available.
*/
static boolean isAvailable() {
return introspectorClass != null;
}
/**
* Invokes java.beans.Introspector.getBeanInfo(Class)
*/
static Object getBeanInfo(Class<?> clazz) throws Exception {
try {
return getBeanInfo.invoke(null, clazz);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof Exception)
throw (Exception)cause;
throw new AssertionError(e);
} catch (IllegalAccessException iae) {
throw new AssertionError(iae);
}
}
/**
* Invokes java.beans.BeanInfo.getPropertyDescriptors()
*/
static Object[] getPropertyDescriptors(Object bi) {
try {
return (Object[])getPropertyDescriptors.invoke(bi);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException)
throw (RuntimeException)cause;
throw new AssertionError(e);
} catch (IllegalAccessException iae) {
throw new AssertionError(iae);
}
}
/**
* Invokes java.beans.PropertyDescriptor.getName()
*/
static String getPropertyName(Object pd) {
try {
return (String)getPropertyName.invoke(pd);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException)
throw (RuntimeException)cause;
throw new AssertionError(e);
} catch (IllegalAccessException iae) {
throw new AssertionError(iae);
}
}
/**
* Invokes java.beans.PropertyDescriptor.getReadMethod()
*/
static Method getReadMethod(Object pd) {
try {
return (Method)getReadMethod.invoke(pd);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException)
throw (RuntimeException)cause;
throw new AssertionError(e);
} catch (IllegalAccessException iae) {
throw new AssertionError(iae);
}
}
}
} }
...@@ -175,7 +175,7 @@ abstract class MBeanIntrospector<M> { ...@@ -175,7 +175,7 @@ abstract class MBeanIntrospector<M> {
/** /**
* Get the methods to be analyzed to build the MBean interface. * Get the methods to be analyzed to build the MBean interface.
*/ */
List<Method> getMethods(final Class<?> mbeanType) throws Exception { List<Method> getMethods(final Class<?> mbeanType) {
return Arrays.asList(mbeanType.getMethods()); return Arrays.asList(mbeanType.getMethods());
} }
......
...@@ -150,9 +150,17 @@ public final class PKIXValidator extends Validator { ...@@ -150,9 +150,17 @@ public final class PKIXValidator extends Validator {
("null or zero-length certificate chain"); ("null or zero-length certificate chain");
} }
if (TRY_VALIDATOR) { if (TRY_VALIDATOR) {
// check if chain contains trust anchor // check that chain is in correct order and check if chain contains
// trust anchor
X500Principal prevIssuer = null;
for (int i = 0; i < chain.length; i++) { for (int i = 0; i < chain.length; i++) {
if (trustedCerts.contains(chain[i])) { X509Certificate cert = chain[i];
if (i != 0 &&
!cert.getSubjectX500Principal().equals(prevIssuer)) {
// chain is not ordered correctly, call builder instead
return doBuild(chain, otherCerts);
}
if (trustedCerts.contains(cert)) {
if (i == 0) { if (i == 0) {
return new X509Certificate[] {chain[0]}; return new X509Certificate[] {chain[0]};
} }
...@@ -161,6 +169,7 @@ public final class PKIXValidator extends Validator { ...@@ -161,6 +169,7 @@ public final class PKIXValidator extends Validator {
System.arraycopy(chain, 0, newChain, 0, i); System.arraycopy(chain, 0, newChain, 0, i);
return doValidate(newChain); return doValidate(newChain);
} }
prevIssuer = cert.getIssuerX500Principal();
} }
// apparently issued by trust anchor? // apparently issued by trust anchor?
...@@ -303,5 +312,4 @@ public final class PKIXValidator extends Validator { ...@@ -303,5 +312,4 @@ public final class PKIXValidator extends Validator {
("PKIX path building failed: " + e.toString(), e); ("PKIX path building failed: " + e.toString(), e);
} }
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册