X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-spi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fspi%2Fmeta%2FNamespaceBehaviour.java;h=8e0dd1ce18e7bafbe8c4b30837a378574b9557f1;hb=d605800fa3da3ea340497c683bd83ea37c12da6c;hp=07dee3eafa7dd4fc206dca8976e860c98357c92c;hpb=e9f837e608239a265d241c7ab90c2b28a68c22e9;p=yangtools.git diff --git a/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java index 07dee3eafa..8e0dd1ce18 100644 --- a/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java +++ b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java @@ -9,17 +9,20 @@ package org.opendaylight.yangtools.yang.parser.spi.meta; import static java.util.Objects.requireNonNull; -import com.google.common.base.MoreObjects; +import com.google.common.annotations.Beta; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.base.Verify; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.yangtools.concepts.Identifiable; -import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yangtools.concepts.AbstractSimpleIdentifiable; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement; +import org.opendaylight.yangtools.yang.parser.spi.SchemaTreeNamespace; /** * Definition / implementation of specific Identifier Namespace behaviour. A namespace behaviour is built on top @@ -30,14 +33,12 @@ import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; * For common behaviour models please use static factories {@link #global(Class)}, {@link #sourceLocal(Class)} and * {@link #treeScoped(Class)}. * - * @param - * Key type - * @param - * Value type - * @param - * Namespace Type + * @param Key type + * @param Value type + * @param Namespace Type */ -public abstract class NamespaceBehaviour> implements Identifiable> { +public abstract class NamespaceBehaviour> + extends AbstractSimpleIdentifiable> { public enum StorageNodeType { /** @@ -47,7 +48,7 @@ public abstract class NamespaceBehaviour> NamespaceBehaviour getNamespaceBehaviour(Class type); + > NamespaceBehaviour getNamespaceBehaviour(Class type); } public interface NamespaceStorageNode { @@ -81,14 +82,11 @@ public abstract class NamespaceBehaviour> V getFromLocalStorage(Class type, K key); + > @Nullable V getFromLocalStorage(Class type, K key); - @Nullable - > Map getAllFromLocalStorage(Class type); + > @Nullable Map getAllFromLocalStorage(Class type); /** * Populate specified namespace with a key/value pair, overwriting previous contents. Similar to @@ -99,8 +97,7 @@ public abstract class NamespaceBehaviour> V putToLocalStorage(Class type, K key, V value); + > @Nullable V putToLocalStorage(Class type, K key, V value); /** * Populate specified namespace with a key/value pair unless the key is already associated with a value. Similar @@ -111,28 +108,54 @@ public abstract class NamespaceBehaviour> V putToLocalStorageIfAbsent(Class type, K key, V value); + > @Nullable V putToLocalStorageIfAbsent(Class type, K key, V value); } - private final @NonNull Class identifier; + /** + * Interface implemented by {@link NamespaceStorageNode}s which support dynamic addition of child elements as they + * are requested. This means that such a node can, defer creation of child namespace storage nodes, in effect lazily + * expanding this namespace on an if-needed basis. + */ + @Beta + public interface OnDemandSchemaTreeStorageNode extends NamespaceStorageNode { + /** + * Request that a new member of this node's schema tree statement be added. Implementations are required to + * perform lookup in their internal structure and create a child if tractable. Resulting node is expected to + * have been registered with local storage, so that it is accessible through + * {@link #getFromLocalStorage(Class, Object)}. + * + *

+ * This method must not change its mind about a child's presence -- once it returns non-present, it has to be + * always returning non-present. + * + *

+ * The results produced by this method are expected to be consistent with + * {@link SchemaTreeAwareEffectiveStatement#findSchemaTreeNode(QName)} and + * {@link SchemaTreeNamespace#getFrom(NamespaceStorageNode, QName)}. + * + * @param qname node identifier of the child being requested + * @return Requested child, if it is present. + * @throws NullPointerException in {@code qname} is null + */ + , E extends SchemaTreeEffectiveStatement> + @Nullable StmtContext requestSchemaTreeChild(QName qname); + } protected NamespaceBehaviour(final Class identifier) { - this.identifier = requireNonNull(identifier); + super(identifier); } /** * Creates a global namespace behaviour for supplied namespace type. Global behaviour stores and loads all values * from root {@link NamespaceStorageNode} with type of {@link StorageNodeType#GLOBAL}. * - * @param identifier - * Namespace identifier. + * @param identifier Namespace identifier. * @param type parameter * @param type parameter * @param type parameter * @return global namespace behaviour for supplied namespace type. */ - public static @Nonnull > NamespaceBehaviour global( + public static > @NonNull NamespaceBehaviour global( final Class identifier) { return new StorageSpecific<>(identifier, StorageNodeType.GLOBAL); } @@ -142,21 +165,20 @@ public abstract class NamespaceBehaviour type parameter * @param type parameter * @param type parameter * @return source-local namespace behaviour for supplied namespace type. */ - public static > NamespaceBehaviour sourceLocal( + public static > @NonNull NamespaceBehaviour sourceLocal( final Class identifier) { return new StorageSpecific<>(identifier, StorageNodeType.SOURCE_LOCAL_SPECIAL); } - public static > NamespaceBehaviour statementLocal( + public static > @NonNull NamespaceBehaviour statementLocal( final Class identifier) { - return new StorageSpecific<>(identifier, StorageNodeType.STATEMENT_LOCAL); + return new StatementLocal<>(identifier); } /** @@ -164,14 +186,13 @@ public abstract class NamespaceBehaviour type parameter * @param type parameter * @param type parameter * @return root-statement-local namespace behaviour for supplied namespace type. */ - public static > NamespaceBehaviour rootStatementLocal( + public static > @NonNull NamespaceBehaviour rootStatementLocal( final Class identifier) { return new StorageSpecific<>(identifier, StorageNodeType.ROOT_STATEMENT_LOCAL); } @@ -187,7 +208,7 @@ public abstract class NamespaceBehaviour type parameter * @return tree-scoped namespace behaviour for supplied namespace type. */ - public static > NamespaceBehaviour treeScoped( + public static > @NonNull NamespaceBehaviour treeScoped( final Class identifier) { return new TreeScoped<>(identifier); } @@ -253,11 +274,6 @@ public abstract class NamespaceBehaviour getIdentifier() { - return identifier; - } - protected final V getFromLocalStorage(final NamespaceStorageNode storage, final K key) { return storage.getFromLocalStorage(getIdentifier(), key); } @@ -270,34 +286,52 @@ public abstract class NamespaceBehaviour> extends NamespaceBehaviour { - StorageNodeType storageType; - - StorageSpecific(final Class identifier, final StorageNodeType type) { + abstract static class AbstractSpecific> + extends NamespaceBehaviour { + AbstractSpecific(final Class identifier) { super(identifier); - storageType = requireNonNull(type); } @Override - public V getFrom(final NamespaceStorageNode storage, final K key) { - NamespaceStorageNode current = findClosestTowardsRoot(storage, storageType); - return getFromLocalStorage(current, key); + public final V getFrom(final NamespaceStorageNode storage, final K key) { + return getFromLocalStorage(findStorageNode(storage), key); } @Override - public Map getAllFrom(final NamespaceStorageNode storage) { - NamespaceStorageNode current = storage; - while (current.getStorageNodeType() != storageType) { - current = current.getParentNamespaceStorage(); - } + public final Map getAllFrom(final NamespaceStorageNode storage) { + return getAllFromLocalStorage(findStorageNode(storage)); + } + + @Override + public final void addTo(final NamespaceStorageNode storage, final K key, final V value) { + addToStorage(findStorageNode(storage), key, value); + } + + abstract NamespaceStorageNode findStorageNode(NamespaceStorageNode storage); + } + + static final class StatementLocal> extends AbstractSpecific { + StatementLocal(final Class identifier) { + super(identifier); + } - return getAllFromLocalStorage(current); + @Override + NamespaceStorageNode findStorageNode(final NamespaceStorageNode storage) { + return storage; + } + } + + static final class StorageSpecific> extends AbstractSpecific { + private final StorageNodeType storageType; + + StorageSpecific(final Class identifier, final StorageNodeType type) { + super(identifier); + storageType = requireNonNull(type); } @Override - public void addTo(final NamespaceBehaviour.NamespaceStorageNode storage, final K key, final V value) { - NamespaceStorageNode current = findClosestTowardsRoot(storage, storageType); - addToStorage(current, key, value); + NamespaceStorageNode findStorageNode(final NamespaceStorageNode storage) { + return findClosestTowardsRoot(storage, storageType); } @Override @@ -306,8 +340,7 @@ public abstract class NamespaceBehaviour> extends NamespaceBehaviour { - + static final class TreeScoped> extends NamespaceBehaviour { TreeScoped(final Class identifier) { super(identifier); } @@ -355,12 +388,7 @@ public abstract class NamespaceBehaviour