Skip to content

Commit

Permalink
Issue highsource#11. Handle T in JAXBElement<T>, especially when type is
Browse files Browse the repository at this point in the history
heterogeneous.
  • Loading branch information
highsource committed Dec 2, 2014
1 parent 352affb commit 4b2c65f
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,17 @@ public HashCodeCodeGeneratorFactory(JCodeModel codeModel) {
addCodeGenerator(this.codeModel.ref(Object.class).array(),
new ArrayHashCodeGenerator(this, this.codeModel));

addCodeGenerator(this.codeModel.ref(JAXBElement.class),
new JAXBElementHashCodeCodeGenerator(this, this.codeModel));
addCodeGenerator(
this.codeModel.ref(JAXBElement.class).narrow(Object.class),
new JAXBElementHashCodeCodeGenerator(this, this.codeModel,
this.typeFactory));

addCodeGenerator(this.codeModel.ref(List.class).narrow(Object.class),
new ListHashCodeCodeGenerator(this, this.codeModel));

// TODO Collections/Lists

// TODO Object with multiple possible types
addCodeGenerator(this.codeModel.ref(Object.class),
new ObjectHashCodeCodeGenerator(this, this.codeModel));
defaultCodeGenerator = new ObjectHashCodeCodeGenerator(this,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.namespace.QName;

import org.apache.commons.lang3.Validate;
import org.jvnet.jaxb2_commons.codemodel.JCMTypeFactory;

import com.sun.codemodel.JBlock;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JCodeModel;
Expand All @@ -17,24 +23,59 @@
public class JAXBElementHashCodeCodeGenerator extends
BlockHashCodeCodeGenerator {

private JCMTypeFactory typeFactory;

public JAXBElementHashCodeCodeGenerator(
TypedHashCodeCodeGeneratorFactory factory, JCodeModel codeModel) {
TypedHashCodeCodeGeneratorFactory factory, JCodeModel codeModel,
JCMTypeFactory typeFactory) {
super(factory, codeModel);
this.typeFactory = Validate.notNull(typeFactory);
}

private JCMTypeFactory getTypeFactory() {
return typeFactory;
}

@Override
protected void generate(JBlock block, JVar currentHashCode,
JType exposedType, Collection<JType> possibleTypes, JVar value) {

// TODO multiple possible types
Validate.isInstanceOf(JClass.class, exposedType);

final JClass exposedClass = (JClass) exposedType;

// Get the T from JAXBElement<T>
final JClass exposedTypeParameter;
final List<JClass> typeParameters = exposedClass.getTypeParameters();
if (typeParameters.size() == 1) {
exposedTypeParameter = typeParameters.get(0);
} else {
exposedTypeParameter = getCodeModel().ref(Object.class).wildcard();
}

// Gather possible values types
final Set<JType> possibleValueTypes = new HashSet<JType>();

for (JType possibleType : possibleTypes) {
Validate.isInstanceOf(JClass.class, possibleType);
final JClass possibleClass = (JClass) possibleType;
if (possibleClass.getTypeParameters().size() == 1) {
possibleValueTypes
.add(possibleClass.getTypeParameters().get(0));
} else {
possibleValueTypes.add(getCodeModel().ref(Object.class));
}
}

valueHashCode(block, currentHashCode, exposedType, value, "Name",
"getName", QName.class);
valueHashCode(block, currentHashCode, exposedType, value, "Value",
"getValue", Object.class);
"getValue", exposedTypeParameter, possibleValueTypes);
final JClass classWildcard = getCodeModel().ref(Class.class).narrow(
getCodeModel().ref(Object.class).wildcard());
final JClass exposedClassWildcard = getCodeModel().ref(Class.class)
.narrow(exposedTypeParameter);
valueHashCode(block, currentHashCode, exposedType, value,
"DeclaredType", "getDeclaredType", classWildcard,
"DeclaredType", "getDeclaredType", exposedClassWildcard,
Collections.<JType> singleton(classWildcard));
valueHashCode(block, currentHashCode, exposedType, value, "Scope",
"getScope", classWildcard,
Expand All @@ -58,14 +99,18 @@ private void valueHashCode(JBlock block, JVar currentHashCode, JType type,
Collection<JType> possiblePropertyTypes) {
final HashCodeCodeGenerator codeGenerator = getFactory()
.getCodeGenerator(propertyType);
final JVar propertyValue = block.decl(JMod.FINAL, propertyType,
value.name() + propertyName, value.invoke(method));

JType declarablePropertyType = getTypeFactory().create(
propertyType).getDeclarableType();

final JVar propertyValue = block.decl(JMod.FINAL,
declarablePropertyType, value.name() + propertyName,
value.invoke(method));
// We assume that primitive properties are always set
boolean isAlwaysSet = propertyType.isPrimitive();
final JExpression hasSetValue = isAlwaysSet ? JExpr.TRUE
: propertyValue.ne(JExpr._null());
codeGenerator.generate(block, currentHashCode, propertyType,
possiblePropertyTypes, propertyValue, hasSetValue, isAlwaysSet);
}

}

0 comments on commit 4b2c65f

Please # to comment.