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
  
  
  


Reply via email to