*/
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;
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;
/**
* 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<QName> qnames) {
+ super(qnames);
+ }
+
+ private Absolute(final QName qname) {
+ super(qname);
+ }
+
/**
* Create an absolute schema node identifier composed of a single node identifier.
*
* @throws NullPointerException if {@code nodeIdentifier} is null
*/
public static @NonNull Absolute of(final QName nodeIdentifier) {
- return new AbsoluteSingle(nodeIdentifier);
+ return new Absolute(nodeIdentifier);
}
/**
* @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));
}
/**
* @throws IllegalArgumentException if {@code nodeIdentifiers} is empty
*/
public static @NonNull Absolute of(final Collection<QName> 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);
}
/**
*
* @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<QName> qnames) {
+ super(qnames);
+ }
+
+ private Descendant(final QName qname) {
+ super(qname);
+ }
+
/**
* Create a descendant schema node identifier composed of a single node identifier.
*
* @throws NullPointerException if {@code nodeIdentifier} is null
*/
public static @NonNull Descendant of(final QName nodeIdentifier) {
- return new DescendantSingle(nodeIdentifier);
+ return new Descendant(nodeIdentifier);
}
/**
* @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));
}
/**
* @throws IllegalArgumentException if {@code nodeIdentifiers} is empty
*/
public static @NonNull Descendant of(final Collection<QName> 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<QName> 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<QName> qnames;
-
- AbsoluteMultiple(final ImmutableList<QName> qnames) {
- this.qnames = requireNonNull(qnames);
- }
-
- @Override
- public ImmutableList<QName> 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<QName> 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<QName> qnames;
-
- DescandantMultiple(final ImmutableList<QName> qnames) {
- this.qnames = requireNonNull(qnames);
- }
-
- @Override
- public ImmutableList<QName> getNodeIdentifiers() {
- return qnames;
- }
-
- @Override
- Object pathObject() {
- return qnames;
+ private SchemaNodeIdentifier(final ImmutableList<QName> 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<QName> getNodeIdentifiers();
+ public final @NonNull List<QName> 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
*
* @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);
}
/**
*
* @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<QName> checkQNames(final Collection<QName> 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<QName> qnames) {
+ private List<?> simpleQNames() {
+ final var qnames = coerceList();
final var ret = new ArrayList<>(qnames.size());
QNameModule prev = null;
return ret;
}
+
+ @SuppressWarnings("unchecked")
+ private ImmutableList<QName> coerceList() {
+ return (ImmutableList<QName>) pathObj;
+ }
}