import static org.opendaylight.mdsal.binding.model.util.Types.listTypeFor;
import static org.opendaylight.mdsal.binding.model.util.Types.listenableFutureTypeFor;
import static org.opendaylight.mdsal.binding.model.util.Types.mapTypeFor;
+import static org.opendaylight.mdsal.binding.model.util.Types.primitiveIntType;
import static org.opendaylight.mdsal.binding.model.util.Types.primitiveVoidType;
import static org.opendaylight.mdsal.binding.model.util.Types.wildcardTypeFor;
import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
private static void addConcreteInterfaceMethods(final GeneratedTypeBuilder typeBuilder) {
defaultImplementedInterace(typeBuilder);
+ typeBuilder.addMethod(BindingMapping.BINDING_HASHCODE_NAME)
+ .setAccessModifier(AccessModifier.PUBLIC)
+ .setStatic(true)
+ .setReturnType(primitiveIntType());
typeBuilder.addMethod(BindingMapping.BINDING_TO_STRING_NAME)
.setAccessModifier(AccessModifier.PUBLIC)
.setStatic(true)
assertNotNull("Generated Interface cannot contain NULL reference for Method Signature Definitions!", methods);
// FIXME: split this into getter/default/static asserts
- assertEquals(17, methods.size());
+ assertEquals(18, methods.size());
Enumeration ianaIfType = null;
for (final MethodSignature method : methods) {
if (method.getName().equals("getType")) {
assertNotNull("Generated Type Interface cannot contain NULL reference to Enumeration types!", methods);
// FIXME: split this into getter/default/static asserts
- assertEquals(7, methods.size());
+ assertEquals(8, methods.size());
for (final MethodSignature method : methods) {
if (method.getName().equals("getLinkUpDownTrapEnable")) {
linkUpDownTrapEnable = method.getReturnType();
assertNotNull(simpleContainer);
assertNotNull(nestedContainer);
// FIXME: split this into getter/default/static asserts
- assertEquals(5, simpleContainer.getMethodDefinitions().size());
+ assertEquals(6, simpleContainer.getMethodDefinitions().size());
// FIXME: split this into getter/default/static asserts
- assertEquals(4, nestedContainer.getMethodDefinitions().size());
+ assertEquals(5, nestedContainer.getMethodDefinitions().size());
int getFooMethodCounter = 0;
int getBarMethodCounter = 0;
assertNotNull(simpleContainer);
assertNotNull(nestedContainer);
// FIXME: split this into getter/default/static asserts
- assertEquals(5, simpleContainer.getMethodDefinitions().size());
+ assertEquals(6, simpleContainer.getMethodDefinitions().size());
// FIXME: split this into getter/default/static asserts
- assertEquals(4, nestedContainer.getMethodDefinitions().size());
+ assertEquals(5, nestedContainer.getMethodDefinitions().size());
int getFooMethodCounter = 0;
int getBarMethodCounter = 0;
}
// FIXME: split this into getter/default/static asserts
- assertEquals(4, listParentContainerMethodsCount);
+ assertEquals(5, listParentContainerMethodsCount);
// FIXME: split this into getter/default/static asserts
- assertEquals(3, listChildContainerMethodsCount);
+ assertEquals(4, listChildContainerMethodsCount);
assertEquals(1, getSimpleListKeyMethodCount);
assertEquals(1, listKeyClassCount);
assertEquals(1, getBarMethodCount);
// FIXME: split this into getter/default/static asserts
- assertEquals(8, simpleListMethodsCount);
+ assertEquals(9, simpleListMethodsCount);
}
@Test
assertTrue(getImplIface.isDefault());
assertTrue(it.hasNext());
+ final MethodSignature bindingHashCode = it.next();
+ assertEquals(BindingMapping.BINDING_HASHCODE_NAME, bindingHashCode.getName());
final MethodSignature bindingToString = it.next();
assertEquals(BindingMapping.BINDING_TO_STRING_NAME, bindingToString.getName());
containsInterface("GroupingCaseTest", caseC);
// FIXME: split this into getter/default/static asserts
- assertEquals(2, caseC.getMethodDefinitions().size());
+ assertEquals(3, caseC.getMethodDefinitions().size());
assertEquals("Number of method in GroupingCaseTest is incorrect", 2, groupingCaseTest.getMethodDefinitions()
.size());
assertEquals("Number of method in GroupingContainerTestis incorrect", 3, groupingContainerTest
.getMethodDefinitions().size());
// FIXME: split this into getter/default/static asserts
- assertEquals(3, containerTest.getMethodDefinitions().size());
+ assertEquals(4, containerTest.getMethodDefinitions().size());
containsMethods(groupingContainerTest.getMethodDefinitions(), new NameTypePattern(
"getLeafGroupingContainerTest1", "String"), new NameTypePattern("getLeafGroupingContainerTest2",
assertEquals("Number of method in GroupingListTest is incorrect", 6, groupingListTest.getMethodDefinitions()
.size());
// FIXME: split this into getter/default/static asserts
- assertEquals(3, listTest.getMethodDefinitions().size());
+ assertEquals(4, listTest.getMethodDefinitions().size());
// FIXME: split this into getter/default/static asserts
- assertEquals(3, containerGroupingListTest.getMethodDefinitions().size());
+ assertEquals(4, containerGroupingListTest.getMethodDefinitions().size());
// FIXME: split this into getter/default/static asserts
- assertEquals(3, listGroupingListTest.getMethodDefinitions().size());
+ assertEquals(4, listGroupingListTest.getMethodDefinitions().size());
containsMethods(groupingListTest.getMethodDefinitions(), new NameTypePattern("getContainerGroupingListTest",
"ContainerGroupingListTest"), new NameTypePattern("getLeafGroupingListTest", "String"),
containsInterface("GroupingRpcOutputTest", rpcTestOutput);
// FIXME: split this into getter/default/static asserts
- assertEquals(2, rpcTestInput.getMethodDefinitions().size());
+ assertEquals(3, rpcTestInput.getMethodDefinitions().size());
// FIXME: split this into getter/default/static asserts
- assertEquals(2, rpcTestOutput.getMethodDefinitions().size());
+ assertEquals(3, rpcTestOutput.getMethodDefinitions().size());
assertEquals("Number of method in GroupingRpcInputTest is incorrect", 3, groupingRpcInputTest
.getMethodDefinitions().size());
assertEquals("Number of method in GroupingRpcOutputTest is incorrect", 2, groupingRpcOutputTest
.getMethodDefinitions().size());
// FIXME: split this into getter/default/static asserts
- assertEquals(3, containerGroupingRpcInputTest.getMethodDefinitions().size());
+ assertEquals(4, containerGroupingRpcInputTest.getMethodDefinitions().size());
containsMethods(groupingRpcInputTest.getMethodDefinitions(), new NameTypePattern(
"getContainerGroupingRpcInputTest", "ContainerGroupingRpcInputTest"), new NameTypePattern(
containsInterface("GroupingAugmentTest", containerAugment1);
// FIXME: split this into getter/default/static asserts
- assertEquals(2, containerAugment1.getMethodDefinitions().size());
+ assertEquals(3, containerAugment1.getMethodDefinitions().size());
// FIXME: split this into getter/default/static asserts
- assertEquals(2, containerAugment1.getMethodDefinitions().size());
+ assertEquals(3, containerAugment1.getMethodDefinitions().size());
assertEquals("Number of method in GroupingCaseTest is incorrect", 2, groupingAugmentTest.getMethodDefinitions()
.size());
containsInterface("GroupingNotificationTest", notificationTest);
// FIXME: split this into getter/default/static asserts
- assertEquals(3, notificationTest.getMethodDefinitions().size());
+ assertEquals(4, notificationTest.getMethodDefinitions().size());
assertEquals("Number of method in GroupingNotificationTest is incorrect", 3, groupingNotificationTest
.getMethodDefinitions().size());
// FIXME: split this into getter/default/static asserts
- assertEquals(3, containerGroupingNotificationTest.getMethodDefinitions().size());
+ assertEquals(4, containerGroupingNotificationTest.getMethodDefinitions().size());
containsMethods(notificationTest.getMethodDefinitions(), new NameTypePattern("getLeafNotificationTest",
"String"));
private static final @NonNull ConcreteType LISTENABLE_FUTURE = typeForClass(ListenableFuture.class);
private static final @NonNull ConcreteType MAP_TYPE = typeForClass(Map.class);
private static final @NonNull ConcreteType OBJECT = typeForClass(Object.class);
+ private static final @NonNull ConcreteType PRIMITIVE_INT = typeForClass(int.class);
private static final @NonNull ConcreteType PRIMITIVE_VOID = typeForClass(void.class);
private static final @NonNull ConcreteType SERIALIZABLE = typeForClass(Serializable.class);
private static final @NonNull ConcreteType SET_TYPE = typeForClass(Set.class);
return OBJECT;
}
+ /**
+ * Returns an instance of {@link ConcreteType} which represents JAVA <code>int</code> type.
+ *
+ * @return <code>ConcreteType</code> instance which represents JAVA <code>int</code>
+ */
+ public static @NonNull ConcreteType primitiveIntType() {
+ return PRIMITIVE_INT;
+ }
+
/**
* Returns an instance of {@link ConcreteType} which represents JAVA <code>void</code> type.
*
import static org.opendaylight.mdsal.binding.model.util.Types.STRING;
import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.AUGMENTATION_FIELD
import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.AUGMENTABLE_AUGMENTATION_NAME
+import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.BINDING_HASHCODE_NAME
import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.BINDING_TO_STRING_NAME
import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.DATA_CONTAINER_IMPLEMENTED_INTERFACE_NAME
return hash;
}
- «hashCodeResult(properties)»
- «IF augmentType !== null»
- result = prime * result + «JU_OBJECTS.importedName».hashCode(augmentations());
- «ENDIF»
-
+ final int result = «targetType.importedName».«BINDING_HASHCODE_NAME»(this);
hash = result;
hashValid = true;
return result;
@«OVERRIDE.importedName»
public int hashCode() {
«IF size != 1»
- «hashCodeResult(genTO.hashCodeIdentifiers)»
+ final int prime = 31;
+ int result = 1;
+ «FOR property : genTO.hashCodeIdentifiers»
+ result = prime * result + «property.importedUtilClass».hashCode(«property.fieldName»);
+ «ENDFOR»
return result;
«ELSE»
return «CODEHELPERS.importedName».wrapperHashCode(«genTO.hashCodeIdentifiers.get(0).fieldName»);
import static extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.isGetterMethodName
import static extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.isNonnullMethodName
import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.AUGMENTATION_FIELD
+import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.BINDING_HASHCODE_NAME
import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.BINDING_TO_STRING_NAME
import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.DATA_CONTAINER_IMPLEMENTED_INTERFACE_NAME
def private generateStaticMethod(MethodSignature method) {
switch method.name {
+ case BINDING_HASHCODE_NAME : generateBindingHashCode
case BINDING_TO_STRING_NAME : generateBindingToString
}
}
}
'''
+ def private generateBindingHashCode() '''
+ «val augmentable = analyzeType»
+ /**
+ * Default implementation of {@link «Object.importedName»#hashCode()} contract for this interface.
+ * Implementations of this interface are encouraged to defer to this method to get consistent hashing
+ * results across all implementation.
+ *
+ «IF augmentable»
+ * <p>
+ * @param <T$$> implementation type, which has to also implement «AUGMENTATION_HOLDER.importedName» interface
+ * contract.
+ «ENDIF»
+ * @param obj Object for which to generate hashCode() result.
+ * @return Hash code value of data modeled by this interface.
+ * @throws «NPE.importedName» if {@code obj} is null
+ */
+ «IF augmentable»
+ static <T$$ extends «type.fullyQualifiedName» & «AUGMENTATION_HOLDER.importedName»<?>> int «BINDING_HASHCODE_NAME»(final @«NONNULL.importedName» T$$ obj) {
+ «ELSE»
+ static int «BINDING_HASHCODE_NAME»(final «type.fullyQualifiedName» obj) {
+ «ENDIF»
+ final int prime = 31;
+ int result = 1;
+ «FOR property : typeAnalysis.value»
+ result = prime * result + «property.importedUtilClass».hashCode(obj.«property.getterMethodName»());
+ «ENDFOR»
+ «IF augmentable»
+ result = prime * result + «CODEHELPERS.importedName».hashAugmentations(obj);
+ «ENDIF»
+ return result;
+ }
+ '''
+
def generateBindingToString() '''
«val augmentable = analyzeType»
/**
*/
public static final @NonNull String DATA_CONTAINER_IMPLEMENTED_INTERFACE_NAME = "implementedInterface";
+ /**
+ * Name of default {@link Object#hashCode()} implementation for instantiated DataObjects. Each such generated
+ * interface contains this static method.
+ */
+ public static final @NonNull String BINDING_HASHCODE_NAME = "bindingHashCode";
+
/**
* Name of default {@link Object#toString()} implementation for instantiated DataObjects. Each such generated
* interface contains this static method.
return value == null ? null : Uint64.valueOf(value);
}
+ /**
+ * Utility for extracting augmentations from an implementation of {@link AugmentationHolder} interface.
+ *
+ * @param obj Implementation object
+ * @return hash code of augmentations
+ * @throws NullPointerException if obj is null
+ */
+ public static int hashAugmentations(final @NonNull AugmentationHolder<?> obj) {
+ return Objects.hashCode(obj.augmentations());
+ }
+
/**
* The constant '31' is the result of folding this code:
* <pre>