diff --git a/.gitignore b/.gitignore index 53fd8f506..16c601975 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,10 @@ /err /std + +plugins/.settings/org.eclipse.core.resources.prefs + +plugins/.settings/org.eclipse.jdt.core.prefs + +tests/simple-hashCode-equals-01/.project + +tests/simple-hashCode-equals-01/.classpath diff --git a/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/BasicHashCodeCodeGenerator.java b/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/BasicHashCodeCodeGenerator.java index f302d71d0..8a4d50166 100644 --- a/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/BasicHashCodeCodeGenerator.java +++ b/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/BasicHashCodeCodeGenerator.java @@ -8,6 +8,7 @@ import com.sun.codemodel.JExpression; import com.sun.codemodel.JOp; import com.sun.codemodel.JType; +import com.sun.codemodel.JVar; public abstract class BasicHashCodeCodeGenerator implements HashCodeCodeGenerator { @@ -19,8 +20,8 @@ public BasicHashCodeCodeGenerator(JCodeModel codeModel) { } @Override - public void generate(JBlock block, JType type, JExpression left, - JExpression right) { + public void generate(JBlock block, JType type, JVar left, + JVar right) { // if (!(left ==null ? right == null : )) // { return false; } final JExpression comparison = comparison(left, right); diff --git a/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/HashCodeCodeGenerator.java b/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/HashCodeCodeGenerator.java index 4d1f0339f..dc6833b01 100644 --- a/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/HashCodeCodeGenerator.java +++ b/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/HashCodeCodeGenerator.java @@ -5,9 +5,10 @@ import com.sun.codemodel.JBlock; import com.sun.codemodel.JExpression; import com.sun.codemodel.JType; +import com.sun.codemodel.JVar; public interface HashCodeCodeGenerator extends CodeGenerator { - public void generate(JBlock block, JType type, JExpression left, - JExpression right); + public void generate(JBlock block, JType type, JVar left, + JVar right); } diff --git a/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/HashCodeCodeGeneratorFactory.java b/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/HashCodeCodeGeneratorFactory.java index 462dd1b15..cf9496e41 100644 --- a/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/HashCodeCodeGeneratorFactory.java +++ b/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/HashCodeCodeGeneratorFactory.java @@ -4,10 +4,13 @@ import java.util.Map; import java.util.Map.Entry; +import javax.xml.bind.JAXBElement; + import org.apache.commons.lang3.Validate; import org.jvnet.jaxb2_commons.codemodel.JCMType; import org.jvnet.jaxb2_commons.codemodel.JCMTypeFactory; import org.jvnet.jaxb2_commons.codemodel.generator.TypedCodeGeneratorFactory; +import org.jvnet.jaxb2_commons.plugin.simpleequals.generator.JAXBElementEqualsCodeGenerator; import com.sun.codemodel.JCodeModel; import com.sun.codemodel.JType; @@ -19,6 +22,7 @@ public class HashCodeCodeGeneratorFactory implements private final JCMTypeFactory typeFactory = new JCMTypeFactory(); // Known code generators private final Map, HashCodeCodeGenerator> codeGenerators = new LinkedHashMap, HashCodeCodeGenerator>(); + private final HashCodeCodeGenerator defaultCodeGenerator; public HashCodeCodeGeneratorFactory(JCodeModel codeModel) { @@ -39,11 +43,14 @@ public HashCodeCodeGeneratorFactory(JCodeModel codeModel) { this.codeModel)); addCodeGenerator(this.codeModel.DOUBLE, new FloatHashCodeCodeGenerator( this.codeModel)); + addCodeGenerator(this.codeModel.ref(JAXBElement.class), + new JAXBElementHashCodeCodeGenerator(codeModel, this)); // TODO primitive arrays // TODO Collections/Lists // TODO JAXBElement addCodeGenerator(this.codeModel.ref(Object.class), new ObjectHashCodeCodeGenerator(this.codeModel)); + defaultCodeGenerator = new ObjectHashCodeCodeGenerator(this.codeModel); } private void addCodeGenerator(final JType type, @@ -61,8 +68,7 @@ public HashCodeCodeGenerator getCodeGenerator(JType type) { return entry.getValue(); } } - throw new IllegalArgumentException( - "Could not find a code generator for [" + type + "]."); + return defaultCodeGenerator; } } diff --git a/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/JAXBElementHashCodeCodeGenerator.java b/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/JAXBElementHashCodeCodeGenerator.java new file mode 100644 index 000000000..d7500d061 --- /dev/null +++ b/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/JAXBElementHashCodeCodeGenerator.java @@ -0,0 +1,82 @@ +package org.jvnet.jaxb2_commons.plugin.simplehashcode.generator; + +import javax.xml.namespace.QName; + +import org.apache.commons.lang3.Validate; +import org.jvnet.jaxb2_commons.codemodel.generator.TypedCodeGeneratorFactory; + +import com.sun.codemodel.JBlock; +import com.sun.codemodel.JClass; +import com.sun.codemodel.JCodeModel; +import com.sun.codemodel.JConditional; +import com.sun.codemodel.JExpr; +import com.sun.codemodel.JMod; +import com.sun.codemodel.JOp; +import com.sun.codemodel.JType; +import com.sun.codemodel.JVar; + +public class JAXBElementHashCodeCodeGenerator implements HashCodeCodeGenerator { + + private final JCodeModel codeModel; + private final TypedCodeGeneratorFactory codeGeneratorFactory; + + public JAXBElementHashCodeCodeGenerator(JCodeModel codeModel, + TypedCodeGeneratorFactory codeGeneratorFactory) { + this.codeModel = Validate.notNull(codeModel); + this.codeGeneratorFactory = Validate.notNull(codeGeneratorFactory); + } + + @Override + public void generate(JBlock block, JType type, JVar left, JVar right) { + + JBlock leftNeRight = block._if(left.ne(right))._then(); + + JConditional ifLeftOrRightIsNull = leftNeRight._if(JOp.cor( + left.eq(JExpr._null()), right.eq(JExpr._null()))); + + final JBlock leftOrRightAreNull = ifLeftOrRightIsNull._then(); + final JBlock leftAndRightAreNotNull = ifLeftOrRightIsNull._else(); + + leftOrRightAreNull._return(JExpr.FALSE); + + generateNonNull(leftAndRightAreNotNull, type, left, right); + + } + + public void generateNonNull(JBlock block, JType type, JVar left, JVar right) { + + // TODO extract type wildcard + generate(block, type, left, right, "Name", "getName", QName.class); + generate(block, type, left, right, "Value", "getValue", Object.class); + final JClass classWildcard = codeModel.ref(Class.class).narrow( + codeModel.ref(Object.class).wildcard()); + generate(block, type, left, right, "DeclaredType", "getDeclaredType", + classWildcard); + generate(block, type, left, right, "Scope", "getScope", classWildcard); + generate(block, type, left, right, "Nil", "isNil", codeModel.BOOLEAN); + + } + + private void generate(JBlock block, JType type, JVar left, JVar right, + String propertyName, String method, Class propertyType) { + generate(block, type, left, right, propertyName, method, + codeModel.ref(propertyType)); + } + + private void generate(JBlock block, JType type, JVar left, JVar right, + String propertyName, String method, JType propertyType) { + + final JBlock propertyBlock = block.block(); + + JVar leftPropertyValue = propertyBlock.decl(JMod.FINAL, propertyType, + left.name() + propertyName, left.invoke(method)); + JVar rightPropertyValue = propertyBlock.decl(JMod.FINAL, propertyType, + right.name() + propertyName, right.invoke(method)); + + final HashCodeCodeGenerator codeGenerator = codeGeneratorFactory + .getCodeGenerator(propertyType); + codeGenerator.generate(propertyBlock, propertyType, leftPropertyValue, + rightPropertyValue); + } + +} diff --git a/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/PrimitiveHashCodeCodeGenerator.java b/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/PrimitiveHashCodeCodeGenerator.java index fdf47c674..e8098a2fa 100644 --- a/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/PrimitiveHashCodeCodeGenerator.java +++ b/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/simplehashcode/generator/PrimitiveHashCodeCodeGenerator.java @@ -5,6 +5,7 @@ import com.sun.codemodel.JExpr; import com.sun.codemodel.JExpression; import com.sun.codemodel.JType; +import com.sun.codemodel.JVar; public class PrimitiveHashCodeCodeGenerator extends BaseHashCodeCodeGenerator { @@ -14,8 +15,8 @@ public PrimitiveHashCodeCodeGenerator(JCodeModel codeModel) { } @Override - public void generate(JBlock block, JType type, JExpression left, - JExpression right) { + public void generate(JBlock block, JType type, JVar left, + JVar right) { // if (!(left ==null ? right == null : )) // { return false; } final JExpression comparison = comparison(left, right);