introspector.java
来自「《移动Agent技术》一书的所有章节源代码。」· Java 代码 · 共 937 行 · 第 1/3 页
JAVA
937 行
decapitalize(name.substring(3)),
null, null,
method, null);
} else if (resultType == void.class && name.startsWith("set")) {
// Simple setter
pd = new PropertyDescriptor(decapitalize(name.substring(3)),
null, method);
if (throwsException(method, PropertyVetoException.class)) {
pd.setConstrained(true);
}
}
} else if (argCount == 2) {
if (argTypes[0] == int.class && name.startsWith("set")) {
pd = new IndexedPropertyDescriptor(
decapitalize(name.substring(3)),
null, null,
null, method);
if (throwsException(method, PropertyVetoException.class)) {
pd.setConstrained(true);
}
}
}
} catch (IntrospectionException ex) {
// This happens if a PropertyDescriptor or IndexedPropertyDescriptor
// constructor fins that the method violates details of the deisgn
// pattern, e.g. by having an empty name, or a getter returning
// void , or whatever.
pd = null;
}
if (pd != null) {
// If this class or one of its base classes is a PropertyChange
// source, then we assume that any properties we discover are "bound".
if (propertyChangeSource) {
pd.setBound(true);
}
addProperty(pd);
}
}
}
// Allocate and populate the result array.
PropertyDescriptor result[] = new PropertyDescriptor[properties.size()];
java.util.Enumeration elements = properties.elements();
for (int i = 0; i < result.length; i++) {
result[i] = (PropertyDescriptor)elements.nextElement();
if (defaultPropertyName != null
&& defaultPropertyName.equals(result[i].getName())) {
defaultPropertyIndex = i;
}
}
return result;
}
void addProperty(PropertyDescriptor pd) {
String name = pd.getName();
PropertyDescriptor old = (PropertyDescriptor)properties.get(name);
if (old == null) {
properties.put(name, pd);
return;
}
// If the property type has changed, use the new descriptor.
Class opd = old.getPropertyType();
Class npd = pd.getPropertyType();
if (opd != null && npd != null && opd != npd) {
properties.put(name, pd);
return;
}
PropertyDescriptor composite;
if (old instanceof IndexedPropertyDescriptor ||
pd instanceof IndexedPropertyDescriptor) {
composite = new IndexedPropertyDescriptor(old, pd);
} else {
composite = new PropertyDescriptor(old, pd);
}
properties.put(name, composite);
}
/**
* @return An array of EventSetDescriptors describing the kinds of
* events fired by the target bean.
*/
private EventSetDescriptor[] getTargetEventInfo() throws IntrospectionException {
// Check if the bean has its own BeanInfo that will provide
// explicit information.
EventSetDescriptor[] explicit = null;
if (informant != null) {
explicit = informant.getEventSetDescriptors();
int ix = informant.getDefaultEventIndex();
if (ix >= 0 && ix < explicit.length) {
defaultEventName = explicit[ix].getName();
}
}
if (explicit == null && superBeanInfo != null) {
// We have no explicit BeanInfo events. Check with our parent.
EventSetDescriptor supers[] = superBeanInfo.getEventSetDescriptors();
for (int i = 0 ; i < supers.length; i++) {
addEvent(supers[i]);
}
int ix = superBeanInfo.getDefaultEventIndex();
if (ix >= 0 && ix < supers.length) {
defaultEventName = supers[ix].getName();
}
}
for (int i = 0; i < additionalBeanInfo.length; i++) {
EventSetDescriptor additional[] = additionalBeanInfo[i].getEventSetDescriptors();
if (additional != null) {
for (int j = 0 ; j < additional.length; j++) {
addEvent(additional[j]);
}
}
}
if (explicit != null) {
// Add the explicit informant data to our results.
for (int i = 0 ; i < explicit.length; i++) {
addEvent(explicit[i]);
}
} else {
// Apply some reflection to the current class.
// Get an array of all the beans methods at this level
Method methodList[] = getDeclaredMethods(beanClass);
// Find all suitable "add" and "remove" methods.
java.util.Hashtable adds = new java.util.Hashtable();
java.util.Hashtable removes = new java.util.Hashtable();
for (int i = 0; i < methodList.length; i++) {
Method method = methodList[i];
// skip static and non-public methods.
int mods = method.getModifiers();
if (Modifier.isStatic(mods) || !Modifier.isPublic(mods)) {
continue;
}
String name = method.getName();
Class argTypes[] = method.getParameterTypes();
Class resultType = method.getReturnType();
if (name.startsWith("add") && argTypes.length == 1 &&
resultType == Void.TYPE) {
String compound = name.substring(3) + ":" + argTypes[0];
adds.put(compound, method);
} else if (name.startsWith("remove") && argTypes.length == 1 &&
resultType == Void.TYPE) {
String compound = name.substring(6) + ":" + argTypes[0];
removes.put(compound, method);
}
}
// Now look for matching addFooListener+removeFooListener pairs.
java.util.Enumeration keys = adds.keys();
String beanClassName = beanClass.getName();
while (keys.hasMoreElements()) {
String compound = (String) keys.nextElement();
// Skip any "add" which doesn't have a matching "remove".
if (removes.get(compound) == null) {
continue;
}
// Method name has to end in "Listener"
if (compound.indexOf("Listener:") <= 0) {
continue;
}
String listenerName = compound.substring(0, compound.indexOf(':'));
String eventName = decapitalize(listenerName.substring(0, listenerName.length()-8));
Method addMethod = (Method)adds.get(compound);
Method removeMethod = (Method)removes.get(compound);
Class argType = addMethod.getParameterTypes()[0];
// Check if the argument type is a subtype of EventListener
if (!Introspector.isSubclass(argType, eventListenerType)) {
continue;
}
// generate a list of Method objects for each of the target methods:
Method allMethods[] = argType.getMethods();
int count = 0;
for (int i = 0; i < allMethods.length; i++) {
if (isEventHandler(allMethods[i])) {
count++;
} else {
allMethods[i] = null;
}
}
Method methods[] = new Method[count];
int j = 0;
for (int i = 0; i < allMethods.length; i++) {
if (allMethods[i] != null) {
methods[j++] = allMethods[i];
}
}
EventSetDescriptor esd = new EventSetDescriptor(eventName, argType,
methods, addMethod, removeMethod);
// If the adder method throws the TooManyListenersException then it
// is a Unicast event source.
if (throwsException(addMethod,
java.util.TooManyListenersException.class)) {
esd.setUnicast(true);
}
addEvent(esd);
}
}
// Allocate and populate the result array.
EventSetDescriptor result[] = new EventSetDescriptor[events.size()];
java.util.Enumeration elements = events.elements();
for (int i = 0; i < result.length; i++) {
result[i] = (EventSetDescriptor)elements.nextElement();
if (defaultEventName != null
&& defaultEventName.equals(result[i].getName())) {
defaultEventIndex = i;
}
}
return result;
}
void addEvent(EventSetDescriptor esd) {
String key = esd.getName();
if (key.equals("propertyChange")) {
propertyChangeSource = true;
}
EventSetDescriptor old = (EventSetDescriptor)events.get(key);
if (old == null) {
events.put(key, esd);
return;
}
EventSetDescriptor composite = new EventSetDescriptor(old, esd);
events.put(key, composite);
}
/**
* @return An array of MethodDescriptors describing the private
* methods supported by the target bean.
*/
private MethodDescriptor[] getTargetMethodInfo() throws IntrospectionException {
// Check if the bean has its own BeanInfo that will provide
// explicit information.
MethodDescriptor[] explicit = null;
if (informant != null) {
explicit = informant.getMethodDescriptors();
}
if (explicit == null && superBeanInfo != null) {
// We have no explicit BeanInfo methods. Check with our parent.
MethodDescriptor supers[] = superBeanInfo.getMethodDescriptors();
for (int i = 0 ; i < supers.length; i++) {
addMethod(supers[i]);
}
}
for (int i = 0; i < additionalBeanInfo.length; i++) {
MethodDescriptor additional[] = additionalBeanInfo[i].getMethodDescriptors();
if (additional != null) {
for (int j = 0 ; j < additional.length; j++) {
addMethod(additional[j]);
}
}
}
if (explicit != null) {
// Add the explicit informant data to our results.
for (int i = 0 ; i < explicit.length; i++) {
addMethod(explicit[i]);
}
} else {
// Apply some reflection to the current class.
// First get an array of all the beans methods at this level
Method methodList[] = getDeclaredMethods(beanClass);
// Now analyze each method.
for (int i = 0; i < methodList.length; i++) {
Method method = methodList[i];
// skip non-public methods.
if (!Modifier.isPublic(method.getModifiers())) {
continue;
}
MethodDescriptor md = new MethodDescriptor(method);
addMethod(md);
}
}
// Allocate and populate the result array.
MethodDescriptor result[] = new MethodDescriptor[methods.size()];
java.util.Enumeration elements = methods.elements();
for (int i = 0; i < result.length; i++) {
result[i] = (MethodDescriptor)elements.nextElement();
}
return result;
}
private void addMethod(MethodDescriptor md) {
// We have to be careful here to distinguish method by both name
// and argument lists.
// This method gets called a *lot, so we try to be efficient.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?