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.opendaylight.yangtools.concepts.Identifiable;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.concepts.AbstractIdentifiable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
+import org.opendaylight.yangtools.yang.parser.spi.SchemaTreeNamespace;
/**
* Definition / implementation of specific Identifier Namespace behaviour. A namespace behaviour is built on top
* For common behaviour models please use static factories {@link #global(Class)}, {@link #sourceLocal(Class)} and
* {@link #treeScoped(Class)}.
*
- * @param <K>
- * Key type
- * @param <V>
- * Value type
- * @param <N>
- * Namespace Type
+ * @param <K> Key type
+ * @param <V> Value type
+ * @param <N> Namespace Type
*/
-public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K, V>> implements Identifiable<Class<N>> {
+public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K, V>>
+ extends AbstractIdentifiable<Class<N>> {
public enum StorageNodeType {
/**
/**
* Storage of the root statement of a particular source and any sources it is importing.
*/
- // FIXME: 3.0.0: this is a misnomer and should be renamed
+ // FIXME: 7.0.0: this is a misnomer and should be renamed
SOURCE_LOCAL_SPECIAL,
/**
* Storage of a single statement.
*/
StorageNodeType getStorageNodeType();
- @Nullable
- NamespaceStorageNode getParentNamespaceStorage();
+ @Nullable NamespaceStorageNode getParentNamespaceStorage();
- @Nullable
- <K, V, N extends IdentifierNamespace<K, V>> V getFromLocalStorage(Class<N> type, K key);
+ <K, V, N extends IdentifierNamespace<K, V>> @Nullable V getFromLocalStorage(Class<N> type, K key);
- @Nullable
- <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromLocalStorage(Class<N> type);
+ <K, V, N extends IdentifierNamespace<K, V>> @Nullable Map<K, V> getAllFromLocalStorage(Class<N> type);
/**
* Populate specified namespace with a key/value pair, overwriting previous contents. Similar to
* @param value Value
* @return Previously-stored value, or null if the key was not present
*/
- @Nullable
- <K, V, N extends IdentifierNamespace<K, V>> V putToLocalStorage(Class<N> type, K key, V value);
+ <K, V, N extends IdentifierNamespace<K, V>> @Nullable V putToLocalStorage(Class<N> type, K key, V value);
/**
* Populate specified namespace with a key/value pair unless the key is already associated with a value. Similar
* @param value Value
* @return Preexisting value or null if there was no previous mapping
*/
- @Nullable
- <K, V, N extends IdentifierNamespace<K, V>> V putToLocalStorageIfAbsent(Class<N> type, K key, V value);
+ <K, V, N extends IdentifierNamespace<K, V>> @Nullable V putToLocalStorageIfAbsent(Class<N> type, K key,
+ V value);
}
- private final Class<N> 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 tracktable. Resulting node is expected to
+ * have been registered with local storage, so that it is accessible through
+ * {@link #getFromLocalStorage(Class, Object)}.
+ *
+ * <p>
+ * 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.
+ *
+ * <p>
+ * 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
+ */
+ <D extends DeclaredStatement<QName>, E extends EffectiveStatement<QName, D>>
+ @Nullable StmtContext<QName, D, E> requestSchemaTreeChild(QName qname);
+ }
protected NamespaceBehaviour(final Class<N> 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 <K> type parameter
* @param <V> type parameter
* @param <N> type parameter
* @return global namespace behaviour for supplied namespace type.
*/
- public static @Nonnull <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> global(
+ public static <K, V, N extends IdentifierNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> global(
final Class<N> identifier) {
return new StorageSpecific<>(identifier, StorageNodeType.GLOBAL);
}
* and loads all values from closest {@link NamespaceStorageNode} ancestor with type
* of {@link StorageNodeType#SOURCE_LOCAL_SPECIAL}.
*
- * @param identifier
- * Namespace identifier.
+ * @param identifier Namespace identifier.
* @param <K> type parameter
* @param <V> type parameter
* @param <N> type parameter
* @return source-local namespace behaviour for supplied namespace type.
*/
- public static <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> sourceLocal(
+ public static <K, V, N extends IdentifierNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> sourceLocal(
final Class<N> identifier) {
return new StorageSpecific<>(identifier, StorageNodeType.SOURCE_LOCAL_SPECIAL);
}
- public static <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> statementLocal(
+ public static <K, V, N extends IdentifierNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> statementLocal(
final Class<N> identifier) {
return new StorageSpecific<>(identifier, StorageNodeType.STATEMENT_LOCAL);
}
* behaviour stores and loads all values from closest {@link NamespaceStorageNode} ancestor with type
* of {@link StorageNodeType#ROOT_STATEMENT_LOCAL}.
*
- * @param identifier
- * Namespace identifier.
+ * @param identifier Namespace identifier.
* @param <K> type parameter
* @param <V> type parameter
* @param <N> type parameter
* @return root-statement-local namespace behaviour for supplied namespace type.
*/
- public static <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> rootStatementLocal(
+ public static <K, V, N extends IdentifierNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> rootStatementLocal(
final Class<N> identifier) {
return new StorageSpecific<>(identifier, StorageNodeType.ROOT_STATEMENT_LOCAL);
}
* @param <N> type parameter
* @return tree-scoped namespace behaviour for supplied namespace type.
*/
- public static <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> treeScoped(
+ public static <K, V, N extends IdentifierNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> treeScoped(
final Class<N> identifier) {
return new TreeScoped<>(identifier);
}
*/
public abstract void addTo(NamespaceStorageNode storage, K key, V value);
- @Override
- public Class<N> getIdentifier() {
- return identifier;
- }
-
protected final V getFromLocalStorage(final NamespaceStorageNode storage, final K key) {
return storage.getFromLocalStorage(getIdentifier(), key);
}
}
static final class StorageSpecific<K, V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
- StorageNodeType storageType;
+ private final StorageNodeType storageType;
StorageSpecific(final Class<N> identifier, final StorageNodeType type) {
super(identifier);
}
@Override
- // FIXME: 3.0.0: make this final
- public String toString() {
- return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
- }
-
protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
- return helper.add("identifier", identifier.getName());
+ return helper.add("identifier", getIdentifier().getName());
}
}