Add ItemOrder concept 53/93653/1
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 13 Nov 2020 12:30:50 +0000 (13:30 +0100)
committerRobert Varga <nite@hq.sk>
Fri, 13 Nov 2020 16:09:11 +0000 (16:09 +0000)
This is a generalized contract for container-like classes, expressing how contained
items contribute to equality contract of the container.

The defined values are ItemOrder.Ordered and ItemOrder.Unordered. For convenience,
these are also exposed as ItemOrder.itemOrder(), reporting the implemented class
of ItemOrder.

JIRA: YANGTOOLS-1170
Change-Id: Ic67926c2146696ecb4be6f664720e842f363c6b0
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit c0efc51f8eaec305de6524c8f98b30e20730feb7)

common/concepts/src/main/java/org/opendaylight/yangtools/concepts/ItemOrder.java [new file with mode: 0644]

diff --git a/common/concepts/src/main/java/org/opendaylight/yangtools/concepts/ItemOrder.java b/common/concepts/src/main/java/org/opendaylight/yangtools/concepts/ItemOrder.java
new file mode 100644 (file)
index 0000000..03d2b0d
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.concepts;
+
+import com.google.common.annotations.Beta;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Marker interface for specifying ordering of items. There are two orderings, {@link Ordered} and {@link Unordered},
+ * and they are mutually exclusive. Item ordering is considered semantically important, such as it impacts
+ * {@link Object#equals(Object)} contract. This can be thought of as the missing interface distinction between
+ * {@link Collection}, {@link List} and {@link Set}.
+ *
+ * @param <T> Item order type
+ */
+@Beta
+@NonNullByDefault
+public interface ItemOrder<T extends ItemOrder<T>> {
+    /**
+     * Items are ordered and their order is significant. A {@link List} is an example of a collection which conforms to
+     * this contract.
+     */
+    interface Ordered extends ItemOrder<Ordered> {
+        @Override
+        default Class<Ordered> itemOrder() {
+            return Ordered.class;
+        }
+
+        /**
+         * {@inheritDoc}
+         *
+         * <p>
+         * Hash code contract of {@link Ordered} objects <b>should</b> be sensitive to item order. In general similar to
+         * {@link List#hashCode()} (in the {@code must} reading of sensitivity. {@code need not} reading of sensitivity
+         * could also be implemented as {@code Map.hashCode()} in case of a map-like container.
+         */
+        // FIXME: 7.0.0: tighten 'should' to 'must'?
+        @Override
+        int hashCode();
+
+        /**
+         * {@inheritDoc}
+         *
+         * <p>
+         * Equality contract of {@link Ordered} objects <b>must</b> be sensitive to item order, similar to
+         * {@link List#equals(Object)}.
+         */
+        @Override
+        boolean equals(@Nullable Object obj);
+    }
+
+    /**
+     * Items are unordered and their order is insignificant. A {@link Set} is an example of a collection which conforms
+     * to this contract.
+     */
+    interface Unordered extends ItemOrder<Unordered> {
+        @Override
+        default Class<Unordered> itemOrder() {
+            return Unordered.class;
+        }
+
+        /**
+         * {@inheritDoc}
+         *
+         * <p>
+         * Hash code contract of {@link Unordered} objects <b>must</b> be insensitive to item order, similar to
+         * {@link Set#hashCode()}.
+         *
+         * <p>
+         * This contract is also exposed through {@link #itemOrder()}.
+         */
+        @Override
+        int hashCode();
+
+        /**
+         * {@inheritDoc}
+         *
+         * <p>
+         * Equality contract of {@link Unordered} objects <b>must</b> be insensitive to item order, similar to
+         * {@link Set#equals(Object)}.
+         *
+         * <p>
+         * This contract is also exposed through {@link #itemOrder()}.
+         */
+        @Override
+        boolean equals(@Nullable Object obj);
+    }
+
+    /**
+     * Return the item order class of this object. The class' equality contracts apply to this object's equality
+     * contract.
+     *
+     * @return Item order class.
+     */
+    Class<T> itemOrder();
+
+    /**
+     * {@link ItemOrder} has impact on {@link #hashCode()}.
+     */
+    @Override
+    int hashCode();
+
+    /**
+     * {@link ItemOrder} has impact on {@link #equals(Object)}.
+     */
+    @Override
+    boolean equals(@Nullable Object obj);
+}