X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=protocol%2Frestconf-api%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Frestconf%2Fapi%2FApiPath.java;h=ce0d15f59852beadd8433e0120f3a7aa2c73c2d8;hb=98a77e3fcc488fcbff0e3aa019bd34088e253e96;hp=c2b53de29ae6a13745475293aefc7800fad72bb6;hpb=de23f62b19967963aec73ced9523f6cf4e5b7bc5;p=netconf.git diff --git a/protocol/restconf-api/src/main/java/org/opendaylight/restconf/api/ApiPath.java b/protocol/restconf-api/src/main/java/org/opendaylight/restconf/api/ApiPath.java index c2b53de29a..ce0d15f598 100644 --- a/protocol/restconf-api/src/main/java/org/opendaylight/restconf/api/ApiPath.java +++ b/protocol/restconf-api/src/main/java/org/opendaylight/restconf/api/ApiPath.java @@ -15,11 +15,18 @@ import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.collect.ImmutableList; import com.google.common.escape.Escaper; import com.google.common.escape.Escapers; +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamException; import java.text.ParseException; import java.util.HexFormat; +import java.util.List; import java.util.Objects; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yangtools.concepts.HierarchicalIdentifier; import org.opendaylight.yangtools.concepts.Immutable; import org.opendaylight.yangtools.yang.common.UnresolvedQName; import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified; @@ -30,7 +37,10 @@ import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified; * as a series of {@link Step}s. */ @NonNullByDefault -public final class ApiPath implements Immutable { +public record ApiPath(ImmutableList steps) implements HierarchicalIdentifier { + @java.io.Serial + private static final long serialVersionUID = 1L; + /** * A single step in an {@link ApiPath}. */ @@ -104,7 +114,8 @@ public final class ApiPath implements Immutable { public static final class ListInstance extends Step { private final ImmutableList keyValues; - ListInstance(final @Nullable String module, final String identifier, final ImmutableList keyValues) { + public ListInstance(final @Nullable String module, final String identifier, + final ImmutableList keyValues) { super(module, identifier); this.keyValues = requireNonNull(keyValues); } @@ -164,10 +175,8 @@ public final class ApiPath implements Immutable { private static final ApiPath EMPTY = new ApiPath(ImmutableList.of()); - private final ImmutableList steps; - - private ApiPath(final ImmutableList steps) { - this.steps = requireNonNull(steps); + public ApiPath { + requireNonNull(steps); } /** @@ -179,6 +188,10 @@ public final class ApiPath implements Immutable { return EMPTY; } + public static ApiPath of(final List steps) { + return steps.isEmpty() ? EMPTY : new ApiPath(ImmutableList.copyOf(steps)); + } + /** * Parse an {@link ApiPath} from a raw Request URI fragment or another source. The string is expected to contain * percent-encoded bytes. Any sequence of such bytes is interpreted as a {@code UTF-8}-encoded string. Invalid @@ -207,16 +220,57 @@ public final class ApiPath implements Immutable { return str.isEmpty() ? EMPTY : parseString(ApiPathParser.newUrl(), str); } + /** + * Return the {@link Step}s of this path. + * + * @return Path steps + */ public ImmutableList steps() { return steps; } + @Override + public boolean contains(final ApiPath other) { + if (this == other) { + return true; + } + final var oit = other.steps.iterator(); + for (var step : steps) { + if (!oit.hasNext() || !step.equals(oit.next())) { + return false; + } + } + return true; + } + + /** + * Returns the index of a Step in this path matching specified module and identifier. This method is equivalent to + * {@code indexOf(module, identifier, 0)}. + * + * @param module Requested {@link Step#module()} + * @param identifier Requested {@link Step#identifier()} + * @return Index of the step in {@link #steps}, or {@code -1} if a matching step is not found + * @throws NullPointerException if {@code identifier} is {@code null} + */ public int indexOf(final String module, final String identifier) { - final var m = requireNonNull(module); + return indexOf(module, identifier, 0); + } + + /** + * Returns the index of a Step in this path matching specified module and identifier, starting search at specified + * index. + * + * @param module Requested {@link Step#module()} + * @param identifier Requested {@link Step#identifier()} + * @param fromIndex index from which to search + * @return Index of the step in {@link #steps}, or {@code -1} if a matching step is not found + * @throws NullPointerException if {@code identifier} is {@code null} + */ + public int indexOf(final String module, final String identifier, final int fromIndex) { final var id = requireNonNull(identifier); - for (int i = 0, size = steps.size(); i < size; ++i) { + for (int i = fromIndex, size = steps.size(); i < size; ++i) { final var step = steps.get(i); - if (m.equals(step.module) && id.equals(step.identifier.getLocalName())) { + if (id.equals(step.identifier.getLocalName()) && Objects.equals(module, step.module)) { return i; } } @@ -229,13 +283,7 @@ public final class ApiPath implements Immutable { public ApiPath subPath(final int fromIndex, final int toIndex) { final var subList = steps.subList(fromIndex, toIndex); - if (subList == steps) { - return this; - } else if (subList.isEmpty()) { - return EMPTY; - } else { - return new ApiPath(subList); - } + return subList == steps ? this : of(subList); } @Override @@ -266,8 +314,31 @@ public final class ApiPath implements Immutable { return sb.toString(); } + @java.io.Serial + Object writeReplace() throws ObjectStreamException { + return new APv1(toString()); + } + + @java.io.Serial + private void writeObject(final ObjectOutputStream stream) throws IOException { + throw nse(); + } + + @java.io.Serial + private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException { + throw nse(); + } + + @java.io.Serial + private void readObjectNoData() throws ObjectStreamException { + throw nse(); + } + + private NotSerializableException nse() { + return new NotSerializableException(getClass().getName()); + } + private static ApiPath parseString(final ApiPathParser parser, final String str) throws ParseException { - final var steps = parser.parseSteps(str); - return steps.isEmpty() ? EMPTY : new ApiPath(steps); + return of(parser.parseSteps(str)); } }