From fc4826510d4c7ee455c48992e57bef1104871d33 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 10 Jan 2024 04:06:53 +0100 Subject: [PATCH] Simplify SchemaNodeIdentifier class hierarchy Use instanceof checks to eliminate the need for dedicated subclasses of Absolute/Descendant. Change-Id: I9ac512037c0930e5bc81d4ebbaa13f8b151dd8ad Signed-off-by: Robert Varga --- .../model/api/stmt/SchemaNodeIdentifier.java | 195 ++++++------------ 1 file changed, 59 insertions(+), 136 deletions(-) diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaNodeIdentifier.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaNodeIdentifier.java index 7439f4c50a..c69d85054a 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaNodeIdentifier.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaNodeIdentifier.java @@ -7,7 +7,6 @@ */ package org.opendaylight.yangtools.yang.model.api.stmt; -import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; import com.google.common.base.MoreObjects; @@ -15,7 +14,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Interner; import com.google.common.collect.Interners; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; import org.eclipse.jdt.annotation.NonNull; @@ -31,9 +29,17 @@ public abstract sealed class SchemaNodeIdentifier implements Immutable { /** * An absolute schema node identifier. */ - public abstract static sealed class Absolute extends SchemaNodeIdentifier { + public static final class Absolute extends SchemaNodeIdentifier { private static final Interner<@NonNull Absolute> INTERNER = Interners.newWeakInterner(); + private Absolute(final ImmutableList qnames) { + super(qnames); + } + + private Absolute(final QName qname) { + super(qname); + } + /** * Create an absolute schema node identifier composed of a single node identifier. * @@ -42,7 +48,7 @@ public abstract sealed class SchemaNodeIdentifier implements Immutable { * @throws NullPointerException if {@code nodeIdentifier} is null */ public static @NonNull Absolute of(final QName nodeIdentifier) { - return new AbsoluteSingle(nodeIdentifier); + return new Absolute(nodeIdentifier); } /** @@ -54,7 +60,7 @@ public abstract sealed class SchemaNodeIdentifier implements Immutable { * @throws IllegalArgumentException if {@code nodeIdentifiers} is empty */ public static @NonNull Absolute of(final QName... nodeIdentifiers) { - return of(Arrays.asList(nodeIdentifiers)); + return of(ImmutableList.copyOf(nodeIdentifiers)); } /** @@ -66,8 +72,8 @@ public abstract sealed class SchemaNodeIdentifier implements Immutable { * @throws IllegalArgumentException if {@code nodeIdentifiers} is empty */ public static @NonNull Absolute of(final Collection nodeIdentifiers) { - final var qnames = checkQNames(nodeIdentifiers); - return qnames.size() == 1 ? of(qnames.get(0)) : new AbsoluteMultiple(qnames); + final var qnames = ImmutableList.copyOf(nodeIdentifiers); + return qnames.size() == 1 ? of(qnames.get(0)) : new Absolute(qnames); } /** @@ -75,20 +81,23 @@ public abstract sealed class SchemaNodeIdentifier implements Immutable { * * @return An interned reference, or this object if it was previously interned. */ - public final @NonNull Absolute intern() { + public @NonNull Absolute intern() { return INTERNER.intern(this); } - - @Override - final String className() { - return "Absolute"; - } } /** * A descendant schema node identifier. */ - public abstract static sealed class Descendant extends SchemaNodeIdentifier { + public static final class Descendant extends SchemaNodeIdentifier { + private Descendant(final ImmutableList qnames) { + super(qnames); + } + + private Descendant(final QName qname) { + super(qname); + } + /** * Create a descendant schema node identifier composed of a single node identifier. * @@ -97,7 +106,7 @@ public abstract sealed class SchemaNodeIdentifier implements Immutable { * @throws NullPointerException if {@code nodeIdentifier} is null */ public static @NonNull Descendant of(final QName nodeIdentifier) { - return new DescendantSingle(nodeIdentifier); + return new Descendant(nodeIdentifier); } /** @@ -109,7 +118,7 @@ public abstract sealed class SchemaNodeIdentifier implements Immutable { * @throws IllegalArgumentException if {@code nodeIdentifiers} is empty */ public static @NonNull Descendant of(final QName... nodeIdentifiers) { - return of(Arrays.asList(nodeIdentifiers)); + return of(ImmutableList.copyOf(nodeIdentifiers)); } /** @@ -121,117 +130,35 @@ public abstract sealed class SchemaNodeIdentifier implements Immutable { * @throws IllegalArgumentException if {@code nodeIdentifiers} is empty */ public static @NonNull Descendant of(final Collection nodeIdentifiers) { - final var qnames = checkQNames(nodeIdentifiers); - return qnames.size() == 1 ? of(qnames.get(0)) : new DescandantMultiple(qnames); - } - - @Override - final String className() { - return "Descendant"; - } - } - - private static final class AbsoluteSingle extends Absolute { - private final @NonNull QName qname; - - AbsoluteSingle(final QName qname) { - this.qname = requireNonNull(qname); - } - - @Override - public ImmutableList getNodeIdentifiers() { - return ImmutableList.of(qname); - } - - @Override - public QName firstNodeIdentifier() { - return qname; - } - - @Override - public QName lastNodeIdentifier() { - return qname; - } - - @Override - Object pathObject() { - return qname; - } - } - - private static final class AbsoluteMultiple extends Absolute { - private final @NonNull ImmutableList qnames; - - AbsoluteMultiple(final ImmutableList qnames) { - this.qnames = requireNonNull(qnames); - } - - @Override - public ImmutableList getNodeIdentifiers() { - return qnames; - } - - @Override - Object pathObject() { - return qnames; + final var qnames = ImmutableList.copyOf(nodeIdentifiers); + return qnames.size() == 1 ? of(qnames.get(0)) : new Descendant(qnames); } } - private static final class DescendantSingle extends Descendant { - private final @NonNull QName qname; - - DescendantSingle(final QName qname) { - this.qname = requireNonNull(qname); - } - - @Override - public ImmutableList getNodeIdentifiers() { - return ImmutableList.of(qname); - } + private final @NonNull Object pathObj; - @Override - public QName firstNodeIdentifier() { - return qname; - } - - @Override - public QName lastNodeIdentifier() { - return qname; - } + // Cached hashCode + private volatile int hash; - @Override - Object pathObject() { - return qname; - } + private SchemaNodeIdentifier(final QName qname) { + pathObj = requireNonNull(qname); } - private static final class DescandantMultiple extends Descendant { - private final @NonNull ImmutableList qnames; - - DescandantMultiple(final ImmutableList qnames) { - this.qnames = requireNonNull(qnames); - } - - @Override - public ImmutableList getNodeIdentifiers() { - return qnames; - } - - @Override - Object pathObject() { - return qnames; + private SchemaNodeIdentifier(final ImmutableList qnames) { + if (qnames.isEmpty()) { + throw new IllegalArgumentException("SchemaNodeIdentifier has to have at least one node identifier"); } + pathObj = qnames; } - // Cached hashCode - private volatile int hash; - /** * Return the non-empty sequence of node identifiers which constitute this schema node identifier. * * @return Non-empty sequence of node identifiers */ - public abstract @NonNull List getNodeIdentifiers(); + public final @NonNull List getNodeIdentifiers() { + return pathObj instanceof QName qname ? ImmutableList.of(qname) : coerceList(); + } /** * Return the first node identifier. This method is equivalent to {@code getNodeIdentifiers().get(0)}, but is @@ -239,8 +166,8 @@ public abstract sealed class SchemaNodeIdentifier implements Immutable { * * @return The first node identifier */ - public @NonNull QName firstNodeIdentifier() { - return getNodeIdentifiers().get(0); + public final @NonNull QName firstNodeIdentifier() { + return pathObj instanceof QName qname ? qname : coerceList().get(0); } /** @@ -249,44 +176,35 @@ public abstract sealed class SchemaNodeIdentifier implements Immutable { * * @return The last node identifier */ - public @NonNull QName lastNodeIdentifier() { - final var local = getNodeIdentifiers(); - return local.get(local.size() - 1); + public final @NonNull QName lastNodeIdentifier() { + if (pathObj instanceof QName qname) { + return qname; + } + final var list = coerceList(); + return list.get(list.size() - 1); } @Override public final int hashCode() { final int local; - return (local = hash) != 0 ? local : (hash = pathObject().hashCode()); + return (local = hash) != 0 ? local : (hash = pathObj.hashCode()); } @Override public final boolean equals(final Object obj) { return this == obj || obj != null && getClass() == obj.getClass() - && pathObject().equals(((SchemaNodeIdentifier) obj).pathObject()); + && pathObj.equals(((SchemaNodeIdentifier) obj).pathObj); } @Override public final String toString() { - return MoreObjects.toStringHelper(className()).add("qnames", toStringQNames()).toString(); + return MoreObjects.toStringHelper(this) + .add("qnames", pathObj instanceof QName qname ? ImmutableList.of(qname) : simpleQNames()) + .toString(); } - abstract @NonNull Object pathObject(); - - abstract @NonNull String className(); - - private List toStringQNames() { - final var ids = getNodeIdentifiers(); - return ids.size() < 2 ? ids : simplifyQNames(ids); - } - - private static ImmutableList checkQNames(final Collection qnames) { - final var ret = ImmutableList.copyOf(qnames); - checkArgument(!ret.isEmpty(), "SchemaNodeIdentifier has to have at least one node identifier"); - return ret; - } - - private static List simplifyQNames(final List qnames) { + private List simpleQNames() { + final var qnames = coerceList(); final var ret = new ArrayList<>(qnames.size()); QNameModule prev = null; @@ -298,4 +216,9 @@ public abstract sealed class SchemaNodeIdentifier implements Immutable { return ret; } + + @SuppressWarnings("unchecked") + private ImmutableList coerceList() { + return (ImmutableList) pathObj; + } } -- 2.36.6