From: Robert Varga Date: Fri, 27 Jun 2014 12:46:08 +0000 (+0200) Subject: Revert "Revert "BUG-994: reorganize SchemaPath into a tree"" X-Git-Tag: release/helium~420^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=45dba97a115720dfae3f7aadc672aeabfa894cc0;p=yangtools.git Revert "Revert "BUG-994: reorganize SchemaPath into a tree"" This reverts commit 65f3c40b20bd437268a3ebc83afe23aa07f80eaf. Change-Id: I4540def627dcafbb39afa17a8e4ff076622d347c Signed-off-by: Robert Varga --- diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaPath.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaPath.java index 6a72b0efbd..e1778e47cd 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaPath.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaPath.java @@ -14,11 +14,11 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import java.util.Arrays; -import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; import org.opendaylight.yangtools.concepts.Immutable; -import org.opendaylight.yangtools.util.HashCodeBuilder; import org.opendaylight.yangtools.yang.common.QName; /** @@ -29,8 +29,8 @@ public abstract class SchemaPath implements Immutable { * An absolute SchemaPath. */ private static final class AbsoluteSchemaPath extends SchemaPath { - private AbsoluteSchemaPath(final Iterable path, final int hash) { - super(path, hash); + private AbsoluteSchemaPath(final SchemaPath parent, final QName qname) { + super(parent, qname); } @Override @@ -39,8 +39,8 @@ public abstract class SchemaPath implements Immutable { } @Override - protected SchemaPath createInstance(final Iterable path, final int hash) { - return new AbsoluteSchemaPath(path, hash); + protected SchemaPath createInstance(final SchemaPath parent, final QName qname) { + return new AbsoluteSchemaPath(parent, qname); } } @@ -48,8 +48,8 @@ public abstract class SchemaPath implements Immutable { * A relative SchemaPath. */ private static final class RelativeSchemaPath extends SchemaPath { - private RelativeSchemaPath(final Iterable path, final int hash) { - super(path, hash); + private RelativeSchemaPath(final SchemaPath parent, final QName qname) { + super(parent, qname); } @Override @@ -58,25 +58,30 @@ public abstract class SchemaPath implements Immutable { } @Override - protected SchemaPath createInstance(final Iterable path, final int hash) { - return new RelativeSchemaPath(path, hash); + protected SchemaPath createInstance(final SchemaPath parent, final QName qname) { + return new RelativeSchemaPath(parent, qname); } } /** * Shared instance of the conceptual root schema node. */ - public static final SchemaPath ROOT = new AbsoluteSchemaPath(Collections.emptyList(), Boolean.TRUE.hashCode()); + public static final SchemaPath ROOT = new AbsoluteSchemaPath(null, null); /** * Shared instance of the "same" relative schema node. */ - public static final SchemaPath SAME = new RelativeSchemaPath(Collections.emptyList(), Boolean.FALSE.hashCode()); + public static final SchemaPath SAME = new RelativeSchemaPath(null, null); /** - * List of QName instances which represents complete path to the node. + * Parent path. */ - private final Iterable path; + private final SchemaPath parent; + + /** + * This component. + */ + private final QName qname; /** * Cached hash code. We can use this since we are immutable. @@ -91,7 +96,7 @@ public abstract class SchemaPath implements Immutable { private ImmutableList getLegacyPath() { if (legacyPath == null) { - legacyPath = ImmutableList.copyOf(path); + legacyPath = ImmutableList.copyOf(getPathTowardsRoot()).reverse(); } return legacyPath; @@ -110,9 +115,16 @@ public abstract class SchemaPath implements Immutable { return getLegacyPath(); } - protected SchemaPath(final Iterable path, final int hash) { - this.path = Preconditions.checkNotNull(path); - this.hash = hash; + protected SchemaPath(final SchemaPath parent, final QName qname) { + this.parent = parent; + this.qname = qname; + + int h = parent == null ? 0 : parent.hashCode(); + if (qname != null) { + h = h * 31 + qname.hashCode(); + } + + hash = h; } /** @@ -155,20 +167,7 @@ public abstract class SchemaPath implements Immutable { * @param hash intended hash code * @return A new SchemaPath instance */ - protected abstract SchemaPath createInstance(Iterable path, int hash); - - private SchemaPath trustedCreateChild(final Iterable relative) { - if (Iterables.isEmpty(relative)) { - return this; - } - - final HashCodeBuilder b = new HashCodeBuilder<>(hash); - for (QName p : relative) { - b.addArgument(p); - } - - return createInstance(Iterables.concat(path, relative), b.toInstance()); - } + protected abstract SchemaPath createInstance(SchemaPath parent, QName qname); /** * Create a child path based on concatenation of this path and a relative path. @@ -181,7 +180,12 @@ public abstract class SchemaPath implements Immutable { return this; } - return trustedCreateChild(ImmutableList.copyOf(relative)); + SchemaPath parent = this; + for (QName qname : relative) { + parent = parent.createInstance(parent, qname); + } + + return parent; } /** @@ -192,7 +196,13 @@ public abstract class SchemaPath implements Immutable { */ public SchemaPath createChild(final SchemaPath relative) { Preconditions.checkArgument(!relative.isAbsolute(), "Child creation requires relative path"); - return trustedCreateChild(relative.path); + + SchemaPath parent = this; + for (QName qname : relative.getPathFromRoot()) { + parent = parent.createInstance(parent, qname); + } + + return parent; } /** @@ -215,7 +225,7 @@ public abstract class SchemaPath implements Immutable { * path from the root to the schema node. */ public Iterable getPathFromRoot() { - return path; + return getLegacyPath(); } /** @@ -226,7 +236,35 @@ public abstract class SchemaPath implements Immutable { * path from the schema node towards the root. */ public Iterable getPathTowardsRoot() { - return getLegacyPath().reverse(); + return new Iterable() { + @Override + public Iterator iterator() { + return new Iterator() { + private SchemaPath current = SchemaPath.this; + + @Override + public boolean hasNext() { + return current.parent != null; + } + + @Override + public QName next() { + if (current.parent != null) { + final QName ret = current.qname; + current = current.parent; + return ret; + } else { + throw new NoSuchElementException("No more elements available"); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Component removal not supported"); + } + }; + } + }; } /** @@ -235,13 +273,7 @@ public abstract class SchemaPath implements Immutable { * @return Parent path, null if this SchemaPath is already toplevel. */ public SchemaPath getParent() { - final int size = Iterables.size(path); - if (size != 0) { - final SchemaPath parent = isAbsolute() ? ROOT : SAME; - return parent.trustedCreateChild(Iterables.limit(path, size - 1)); - } else { - return null; - } + return parent; } /** @@ -268,8 +300,22 @@ public abstract class SchemaPath implements Immutable { if (getClass() != obj.getClass()) { return false; } - SchemaPath other = (SchemaPath) obj; - return Iterables.elementsEqual(path, other.path); + final SchemaPath other = (SchemaPath) obj; + + if (qname != null) { + if (!qname.equals(other.qname)) { + return false; + } + } else { + if (other.qname != null) { + return false; + } + } + + if (parent == null) { + return other.parent == null; + } + return parent.equals(other.parent); } @Override @@ -278,6 +324,6 @@ public abstract class SchemaPath implements Immutable { } protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) { - return toStringHelper.add("path", path); + return toStringHelper.add("path", getPathFromRoot()); } } diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java index 2af7159ffe..fc98c1daf0 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java @@ -10,7 +10,6 @@ package org.opendaylight.yangtools.yang.model.util; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import java.net.URI; @@ -869,14 +868,13 @@ public final class SchemaContextUtil { ++colCount; } - final ImmutableList relative = ImmutableList.copyOf( + final Iterable parent = leafrefParentNode.getPath().getPathFromRoot(); + return Iterables.concat(Iterables.limit(parent, Iterables.size(parent) - colCount), Iterables.transform(Iterables.skip(xpaths, colCount), new Function() { @Override public QName apply(final String input) { return stringPathPartToQName(context, module, input); } })); - final Iterable parent = leafrefParentNode.getPath().getPathFromRoot(); - return Iterables.concat(Iterables.limit(parent, Iterables.size(parent) - colCount), relative); } }