static EntityBeanDeserializer.BeanPropertyDescriptor[] processPropertyDescriptors(PropertyDescriptor[] rawPd,
Class cls) {
BeanPropertyDescriptor[] myPd = new BeanPropertyDescriptor[rawPd.length];
for (int i = 0; i < rawPd.length; i++) {
myPd[i] =
new BeanPropertyDescriptor(
rawPd[i].getName(),
rawPd[i].getReadMethod(),
rawPd[i].getWriteMethod());
}
try {
// Create a new pd array and index into the array
int index = 0;
// Build a new pd array
// defined by the order of the get methods.
BeanPropertyDescriptor[] newPd = new BeanPropertyDescriptor[rawPd.length];
Method[] methods = cls.getMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (method.getName().startsWith("set")) {
boolean found = false;
for (int j = 0; j < myPd.length && !found; j++) {
if (myPd[j].getWriteMethod() != null
&& myPd[j].getWriteMethod().equals(method)) {
found = true;
newPd[index] = myPd[j];
index++;
}
}
}
}
// Now if there are any additional property descriptors, add them to the end.
if (index < myPd.length) {
for (int m = 0; m < myPd.length && index < myPd.length; m++) {
boolean found = false;
for (int n = 0; n < index && !found; n++) {
found = (myPd[m] == newPd[n]);
}
if (!found) {
newPd[index] = myPd[m];
index++;
}
}
}
// If newPd has same number of elements as myPd, use newPd.
if (index == myPd.length) {
myPd = newPd;
}
// Get the methods of the class and look for the special set and
// get methods for property "collections"
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().startsWith("set")
&& methods[i].getParameterTypes().length == 2) {
for (int j = 0; j < methods.length; j++) {
if ((methods[j].getName().startsWith("get")
|| methods[j].getName().startsWith("is"))
&& methods[j].getParameterTypes().length == 1
&& methods[j].getReturnType() == methods[i].getParameterTypes()[1]
&& methods[j].getParameterTypes()[0] == int.class
&& methods[i].getParameterTypes()[0] == int.class) {
for (int k = 0; k < myPd.length; k++) {
if (myPd[k].getReadMethod() != null
&& myPd[k].getWriteMethod() != null
&& myPd[k].getReadMethod().getName().equals(methods[j].getName())
&& myPd[k].getWriteMethod().getName().equals(methods[i].getName())) {
myPd[k] = new BeanPropertyDescriptor(myPd[k].getName(), methods[j], methods[i]);
}
}
}
}
}
}
} catch (Exception e) {
// Don't process Property Descriptors if problems occur
return myPd;
}
return myPd;
}
This method attempts to sort the property descriptors to match the
order defined in the class. This is necessary to support
xsd:sequence processing, which means that the serialized order of
properties must match the xml element order. (This method assumes that the
order of the set methods matches the xml element order...the emitter
will always order the set methods according to the xml order.)
This routine also looks for set(i, type) and get(i) methods and adjusts the
property to use these methods instead. These methods are generated by the
emitter for "collection" of properties (i.e. maxOccurs="unbounded" on an element).
JAX-RPC is silent on this issue, but web services depend on this kind of behaviour.
The method signatures were chosen to match bean indexed properties. |