2 * Copyright (c) 2024 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.binding.lib;
10 import java.io.Serializable;
11 import org.eclipse.jdt.annotation.NonNull;
12 import org.eclipse.jdt.annotation.Nullable;
15 * A reference to a {@link DataObject} type forming a single step in a path similar to {@code instance-identifier}.
17 * @param <T> DataObject type
20 * FIXME: this interface forms a partial model of the following RFC7950 construct:
22 * ;; Instance Identifiers
24 * instance-identifier = 1*("/" (node-identifier [1*key-predicate / leaf-list-predicate / pos]))
26 * We handle the 'node-identifier for DataObjects' and 'key-predicate' cases. What is missing are interfaces for:
27 * - 'leaf-list-predicate' (exact value match)
28 * - 'pos' interfaces (index into a list or a leaf-list}
29 * - 'node-identifier for non-DataObjects' (i.e. leaf, anydata, anyxml)
31 public sealed interface DataObjectStep<T extends DataObject> extends Comparable<DataObjectStep<?>>, Serializable
32 permits ExactDataObjectStep, KeylessStep {
34 * Return the data object type backing this PathArgument.
36 * @return Data object type
38 @NonNull Class<T> type();
41 * Return an optional enclosing case type. This is used only when {@link #type()} references a node defined
42 * in a {@code grouping} which is reference inside a {@code case} statement in order to safely reference the node.
44 * @return case class, or {@code null}
46 @Nullable Class<? extends DataObject> caseType();
49 default int compareTo(final DataObjectStep<?> other) {
50 final var typeCmp = compareClasses(type(), other.type());
54 final var caseType = caseType();
55 final var otherCaseType = other.caseType();
56 if (caseType == null) {
57 return otherCaseType == null ? 0 : -1;
59 final var caseCmp = otherCaseType == null ? 1 : compareClasses(caseType, otherCaseType);
60 return caseCmp != 0 ? caseCmp : compareHierarchy(this, other);
63 private static int compareHierarchy(final DataObjectStep<?> recv, final DataObjectStep<?> other) {
64 if (recv instanceof NodeStep) {
65 if (other instanceof NodeStep) {
67 } else if (other instanceof KeylessStep || other instanceof KeyStep) {
70 } else if (recv instanceof KeyStep thisAware) {
71 if (other instanceof KeyStep otherAware) {
72 @SuppressWarnings("unchecked")
73 final var thisKey = (Comparable<Object>) thisAware.key();
74 return thisKey.compareTo(otherAware.key());
75 } else if (other instanceof NodeStep || other instanceof KeylessStep) {
78 } else if (recv instanceof KeylessStep) {
79 if (other instanceof KeylessStep) {
81 } else if (other instanceof NodeStep || other instanceof KeyStep) {
85 throw new IllegalStateException("Unhandled " + recv + ".compareTo(" + other + ")");
88 private static int compareClasses(final Class<?> first, final Class<?> second) {
89 return first.getCanonicalName().compareTo(second.getCanonicalName());