|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package java.beans; |
|
|
|
import java.lang.ref.Reference; |
|
import java.lang.ref.WeakReference; |
|
import java.lang.reflect.Method; |
|
import java.util.List; |
|
import java.util.ArrayList; |
|
|
|
/** |
|
* A MethodDescriptor describes a particular method that a Java Bean |
|
* supports for external access from other components. |
|
*/ |
|
|
|
public class MethodDescriptor extends FeatureDescriptor { |
|
|
|
private final MethodRef methodRef = new MethodRef(); |
|
|
|
private String[] paramNames; |
|
|
|
private List<WeakReference<Class<?>>> params; |
|
|
|
private ParameterDescriptor parameterDescriptors[]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public MethodDescriptor(Method method) { |
|
this(method, null); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public MethodDescriptor(Method method, |
|
ParameterDescriptor parameterDescriptors[]) { |
|
setName(method.getName()); |
|
setMethod(method); |
|
this.parameterDescriptors = (parameterDescriptors != null) |
|
? parameterDescriptors.clone() |
|
: null; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public synchronized Method getMethod() { |
|
Method method = this.methodRef.get(); |
|
if (method == null) { |
|
Class<?> cls = getClass0(); |
|
String name = getName(); |
|
if ((cls != null) && (name != null)) { |
|
Class<?>[] params = getParams(); |
|
if (params == null) { |
|
for (int i = 0; i < 3; i++) { |
|
// Find methods for up to 2 params. We are guessing here. |
|
// This block should never execute unless the classloader |
|
|
|
method = Introspector.findMethod(cls, name, i, null); |
|
if (method != null) { |
|
break; |
|
} |
|
} |
|
} else { |
|
method = Introspector.findMethod(cls, name, params.length, params); |
|
} |
|
setMethod(method); |
|
} |
|
} |
|
return method; |
|
} |
|
|
|
private synchronized void setMethod(Method method) { |
|
if (method == null) { |
|
return; |
|
} |
|
if (getClass0() == null) { |
|
setClass0(method.getDeclaringClass()); |
|
} |
|
setParams(getParameterTypes(getClass0(), method)); |
|
this.methodRef.set(method); |
|
} |
|
|
|
private synchronized void setParams(Class<?>[] param) { |
|
if (param == null) { |
|
return; |
|
} |
|
paramNames = new String[param.length]; |
|
params = new ArrayList<>(param.length); |
|
for (int i = 0; i < param.length; i++) { |
|
paramNames[i] = param[i].getName(); |
|
params.add(new WeakReference<Class<?>>(param[i])); |
|
} |
|
} |
|
|
|
|
|
String[] getParamNames() { |
|
return paramNames; |
|
} |
|
|
|
private synchronized Class<?>[] getParams() { |
|
Class<?>[] clss = new Class<?>[params.size()]; |
|
|
|
for (int i = 0; i < params.size(); i++) { |
|
Reference<? extends Class<?>> ref = (Reference<? extends Class<?>>)params.get(i); |
|
Class<?> cls = ref.get(); |
|
if (cls == null) { |
|
return null; |
|
} else { |
|
clss[i] = cls; |
|
} |
|
} |
|
return clss; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public ParameterDescriptor[] getParameterDescriptors() { |
|
return (this.parameterDescriptors != null) |
|
? this.parameterDescriptors.clone() |
|
: null; |
|
} |
|
|
|
private static Method resolve(Method oldMethod, Method newMethod) { |
|
if (oldMethod == null) { |
|
return newMethod; |
|
} |
|
if (newMethod == null) { |
|
return oldMethod; |
|
} |
|
return !oldMethod.isSynthetic() && newMethod.isSynthetic() ? oldMethod : newMethod; |
|
} |
|
|
|
/* |
|
* Package-private constructor |
|
* Merge two method descriptors. Where they conflict, give the |
|
* second argument (y) priority over the first argument (x). |
|
* @param x The first (lower priority) MethodDescriptor |
|
* @param y The second (higher priority) MethodDescriptor |
|
*/ |
|
|
|
MethodDescriptor(MethodDescriptor x, MethodDescriptor y) { |
|
super(x, y); |
|
|
|
this.methodRef.set(resolve(x.methodRef.get(), y.methodRef.get())); |
|
params = x.params; |
|
if (y.params != null) { |
|
params = y.params; |
|
} |
|
paramNames = x.paramNames; |
|
if (y.paramNames != null) { |
|
paramNames = y.paramNames; |
|
} |
|
|
|
parameterDescriptors = x.parameterDescriptors; |
|
if (y.parameterDescriptors != null) { |
|
parameterDescriptors = y.parameterDescriptors; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
MethodDescriptor(MethodDescriptor old) { |
|
super(old); |
|
|
|
this.methodRef.set(old.getMethod()); |
|
params = old.params; |
|
paramNames = old.paramNames; |
|
|
|
if (old.parameterDescriptors != null) { |
|
int len = old.parameterDescriptors.length; |
|
parameterDescriptors = new ParameterDescriptor[len]; |
|
for (int i = 0; i < len ; i++) { |
|
parameterDescriptors[i] = new ParameterDescriptor(old.parameterDescriptors[i]); |
|
} |
|
} |
|
} |
|
|
|
void appendTo(StringBuilder sb) { |
|
appendTo(sb, "method", this.methodRef.get()); |
|
if (this.parameterDescriptors != null) { |
|
sb.append("; parameterDescriptors={"); |
|
for (ParameterDescriptor pd : this.parameterDescriptors) { |
|
sb.append(pd).append(", "); |
|
} |
|
sb.setLength(sb.length() - 2); |
|
sb.append("}"); |
|
} |
|
} |
|
} |