if (getConfig().useJava50()) {
jMethod.addAnnotation(new JAnnotation(new JAnnotationType("Override")));
}
jclass.addMethod(jMethod);
JSourceCode jsc = jMethod.getSourceCode();
jsc.add("if ( this == obj )");
jsc.indent();
jsc.add("return true;");
jsc.unindent();
if (jclass.getSuperClassQualifiedName() != null) {
jsc.add("");
jsc.add("if (super.equals(obj)==false)");
jsc.indent();
jsc.add("return false;");
jsc.unindent();
}
jsc.add("");
jsc.add("if (obj instanceof ");
jsc.append(jclass.getLocalName());
jsc.append(") {");
jsc.add("");
if (fields.length > 0) {
jsc.indent();
jsc.add(jclass.getLocalName());
jsc.append(" temp = (");
jsc.append(jclass.getLocalName());
jsc.append(")obj;");
jsc.add("boolean thcycle;");
jsc.add("boolean tmcycle;");
}
for (int i = 0; i < fields.length; i++) {
JField temp = fields[i];
//Be careful to arrayList....
String name = temp.getName();
if (temp.getType().isPrimitive()) {
jsc.add("if (this.");
jsc.append(name);
jsc.append(" != temp.");
jsc.append(name);
jsc.append(")");
} else {
//-- Check first if the field is not null. This can occur while comparing
//-- two objects that contains non-mandatory fields. We only have to check
//-- one field since x.equals(null) should return false when equals() is
//-- correctly implemented.
jsc.add("if (this.");
jsc.append(name);
jsc.append(" != null) {");
jsc.indent();
jsc.add("if (temp.");
jsc.append(name);
jsc.append(" == null) ");
jsc.indent();
jsc.append("return false;");
jsc.unindent();
jsc.add("if (this.");
jsc.append(name);
jsc.append(" != temp.");
jsc.append(name);
jsc.append(") {");
// This prevents string constants and improper DOM subtree self comparisons
// (where Q(A(B)) and Q'(C(B)) are compared) screwing up cycle detection
jsc.indent();
jsc.add("thcycle=org.castor.core.util.CycleBreaker.startingToCycle(this." + name + ");");
jsc.add("tmcycle=org.castor.core.util.CycleBreaker.startingToCycle(temp." + name + ");");
// equivalent objects *will* cycle at the same time
jsc.add("if (thcycle!=tmcycle) {");
jsc.indent();
jsc.add("if (!thcycle) { org.castor.core.util.CycleBreaker.releaseCycleHandle(this."
+ name + "); };");
jsc.add("if (!tmcycle) { org.castor.core.util.CycleBreaker.releaseCycleHandle(temp."
+ name + "); };");
jsc.add("return false;");
jsc.unindent();
jsc.add("}"); // end of unequal cycle point test
jsc.add("if (!thcycle) {");
jsc.indent();
jsc.add("if (!");
// Special handling for comparing arrays
if (temp.getType().isArray()) {
jsc.append("java.util.Arrays.equals(this.");
jsc.append(name);
jsc.append(", temp.");
jsc.append(name);
jsc.append(")");
} else {
jsc.append("this.");
jsc.append(name);
jsc.append(".equals(temp.");
jsc.append(name);
jsc.append(")");
}
jsc.append(") {");
jsc.indent();
jsc.add("org.castor.core.util.CycleBreaker.releaseCycleHandle(this." + name + ");");
jsc.add("org.castor.core.util.CycleBreaker.releaseCycleHandle(temp." + name + ");");
jsc.add("return false;");
jsc.unindent();
jsc.add("}");
jsc.add("org.castor.core.util.CycleBreaker.releaseCycleHandle(this." + name + ");");
jsc.add("org.castor.core.util.CycleBreaker.releaseCycleHandle(temp." + name + ");");
jsc.unindent();
jsc.add("}"); // end of !thcycle
jsc.unindent();
jsc.add("}"); // end of this.name != that.name object constant check
jsc.unindent();
jsc.add("} else if (temp.");
jsc.append(name);
jsc.append(" != null)");
}
jsc.indent();
jsc.add("return false;");
jsc.unindent();
}
jsc.add("return true;");
jsc.unindent();
jsc.add("}");
jsc.add("return false;");
} //CreateEqualsMethod