scheu 02/04/19 12:14:57
Modified: java/src/org/apache/axis/wsdl/toJava JavaBeanWriter.java
Log:
The following changes are made.
The changes also fix http://nagoya.apache.org/bugzilla/show_bug.cgi?id=7743
1) Added hashCode generation to each bean generated by WSDL2Java.
2) The equals(Object) was not considering extended classes. Now
equals(Object) and hashCode() invoke their super conterparts.
3) It is possible that during the processing of equals or hashCode,
the object may be recursively invoked. I added code to synchronize
the methods and properly process these cases.
As an example, here is the code generated for the test.wsdl.multiref.Nodebase
class:
private Object __equalsCalc = null;
public synchronized boolean equals(Object obj) {
if (!(obj instanceof Nodebase)) return false;
Nodebase other = (Nodebase) obj;
if (obj == null) return false;
if (this == obj) return true;
if (__equalsCalc != null) {
return (__equalsCalc == obj);
}
__equalsCalc = obj;
boolean _equals;
_equals = true &&
((left==null && other.getLeft()==null) ||
(left!=null &&
left.equals(other.getLeft()))) &&
((right==null && other.getRight()==null) ||
(right!=null &&
right.equals(other.getRight())));
__equalsCalc = null;
return _equals;
}
private boolean __hashCodeCalc = false;
public synchronized int hashCode() {
if (__hashCodeCalc) {
return 0;
}
__hashCodeCalc = true;
int _hashCode = 1;
if (getLeft() != null) {
_hashCode += getLeft().hashCode();
}
if (getRight() != null) {
_hashCode += getRight().hashCode();
}
__hashCodeCalc = false;
return _hashCode;
}
Revision Changes Path
1.7 +100 -5
xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaBeanWriter.java
Index: JavaBeanWriter.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaBeanWriter.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- JavaBeanWriter.java 9 Apr 2002 18:50:13 -0000 1.6
+++ JavaBeanWriter.java 19 Apr 2002 19:14:57 -0000 1.7
@@ -242,6 +242,7 @@
}
writeEqualsMethod();
+ writeHashCodeMethod();
// Write the meta data into a Helper class or
// embed it in the bean class
@@ -254,18 +255,38 @@
pw.close();
} // writeFileBody
+ /**
+ * Generate an equals method.
+ **/
protected void writeEqualsMethod() {
- pw.println(" public boolean equals(Object obj) {");
- pw.println(" // compare elements");
+
+ // The __equalsCalc field and synchronized method are necessary
+ // in case the object has direct or indirect references to itself.
+ pw.println(" private Object __equalsCalc = null;");
+ pw.println(" public synchronized boolean equals(Object obj) {");
+
+ // First do the general comparison checks
pw.println(" if (!(obj instanceof " + className + ")) return
false;");
pw.println(" " + className + " other = (" + className + ") obj;");
pw.println(" if (obj == null) return false;");
pw.println(" if (this == obj) return true;");
- pw.println(" if (! (obj instanceof " + className + ")) return
false;");
+
+ // Have we been here before ? return true if yes otherwise false
+ pw.println(" if (__equalsCalc != null) {");
+ pw.println(" return (__equalsCalc == obj);");
+ pw.println(" }");
+ pw.println(" __equalsCalc = obj;");
+
+ // Before checking the elements, check equality of the super class
+ String truth = "true";
+ if (extendType != null && !type.isSimpleType()) {
+ truth = "super.equals(obj)";
+ }
+ pw.println(" boolean _equals;");
if (names.size() == 0) {
- pw.println(" return true;");
+ pw.println(" _equals = " + truth + ";");
} else {
- pw.println(" return");
+ pw.println(" _equals = " + truth + " && ");
for (int i = 0; i < names.size(); i += 2) {
String variableType = (String) names.get(i);
String variable = (String) names.get(i + 1);
@@ -308,6 +329,80 @@
pw.println(" &&");
}
}
+ pw.println(" __equalsCalc = null;");
+ pw.println(" return _equals;");
+ pw.println(" }");
+ }
+
+ protected void writeHashCodeMethod() {
+ // The __hashCodeCalc field and synchronized method are necessary
+ // in case the object has direct or indirect references to itself.
+ pw.println(" private boolean __hashCodeCalc = false;");
+ pw.println(" public synchronized int hashCode() {");
+ pw.println(" if (__hashCodeCalc) {");
+ pw.println(" return 0;");
+ pw.println(" }");
+ pw.println(" __hashCodeCalc = true;");
+
+ // Get the hashCode of the super class
+ String start = "1";
+ if (extendType != null && !type.isSimpleType()) {
+ start = "super.hashCode()";
+ }
+ pw.println(" int _hashCode = " + start + ";");
+ for (int i = 0; i < names.size(); i += 2) {
+ String variableType = (String) names.get(i);
+ String variable = (String) names.get(i + 1);
+ String get = "get";
+
+ if (variableType.equals("boolean"))
+ get = "is";
+
+ if (variableType.equals("int") ||
+ variableType.equals("short") ||
+ variableType.equals("boolean") ||
+ variableType.equals("byte")) {
+ pw.println(" _hashCode += " + get +
+ Utils.capitalizeFirstChar(variable) + "();");
+ } else if (variableType.equals("long")) {
+ pw.println(" _hashCode += new Long(" + get +
+ Utils.capitalizeFirstChar(variable) + "()).hashCode();");
+ } else if (variableType.equals("float")) {
+ pw.println(" _hashCode += new Float(" + get +
+ Utils.capitalizeFirstChar(variable) + "()).hashCode();");
+ } else if (variableType.equals("double")) {
+ pw.println(" _hashCode += new Double(" + get +
+ Utils.capitalizeFirstChar(variable) + "()).hashCode();");
+ } else if (variableType.indexOf("[") >=0) {
+ // The hashCode calculation for arrays is complicated.
+ // Wish there was a hashCode method in java.utils.Arrays !
+ // Get the hashCode for each element of the array which is not an
array.
+ pw.println(" if (" + get +
+ Utils.capitalizeFirstChar(variable) + "() != null) {");
+ pw.println(" for (int i=0;");
+ pw.println(" i<java.lang.reflect.Array.getLength("
+ get +
+ Utils.capitalizeFirstChar(variable) + "());");
+ pw.println(" i++) {");
+ pw.println(" Object obj =
java.lang.reflect.Array.get(" +
+ get +
+ Utils.capitalizeFirstChar(variable) + "(), i);");
+ pw.println(" if (obj != null &&");
+ pw.println(" !obj.getClass().isArray()) {");
+ pw.println(" _hashCode += obj.hashCode();");
+ pw.println(" }");
+ pw.println(" }");
+ pw.println(" }");
+ } else {
+ pw.println(" if (" + get +
+ Utils.capitalizeFirstChar(variable) + "() != null) {");
+ pw.println(" _hashCode += " + get +
+ Utils.capitalizeFirstChar(variable) + "().hashCode();");
+ pw.println(" }");
+ }
+ }
+ // Reset the __hashCodeCalc variable and return
+ pw.println(" __hashCodeCalc = false;");
+ pw.println(" return _hashCode;");
pw.println(" }");
}
} // class JavaBeanWriter