X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fimpl%2Fschema%2Ftree%2FInMemoryDataTree.java;h=95165371c32c4491838da01c2d25cf51ce54277d;hb=refs%2Fchanges%2F89%2F33489%2F3;hp=0f680fddadf30a6cf11410bf7ef2cb31e069c14a;hpb=b5c32f072f61abfe730a386f8ffe3862491785cd;p=yangtools.git diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTree.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTree.java index 0f680fddad..95165371c3 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTree.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTree.java @@ -8,18 +8,20 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree; import com.google.common.base.MoreObjects; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import java.util.Collections; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes; -import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate; -import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification; -import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException; +import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree; +import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType; import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode; +import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode; +import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,18 +29,22 @@ import org.slf4j.LoggerFactory; /** * Read-only snapshot of the data tree. */ -final class InMemoryDataTree implements DataTree { - private static final YangInstanceIdentifier PUBLIC_ROOT_PATH = YangInstanceIdentifier.create(Collections.emptyList()); +final class InMemoryDataTree extends AbstractDataTreeTip implements TipProducingDataTree { private static final AtomicReferenceFieldUpdater STATE_UPDATER = AtomicReferenceFieldUpdater.newUpdater(InMemoryDataTree.class, DataTreeState.class, "state"); private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTree.class); + private final YangInstanceIdentifier rootPath; + private final TreeType treeType; + /** * Current data store state generation. */ private volatile DataTreeState state; - public InMemoryDataTree(final TreeNode rootNode, final SchemaContext schemaContext) { + public InMemoryDataTree(final TreeNode rootNode, final TreeType treeType, final YangInstanceIdentifier rootPath, final SchemaContext schemaContext) { + this.treeType = Preconditions.checkNotNull(treeType, "treeType"); + this.rootPath = Preconditions.checkNotNull(rootPath, "rootPath"); state = DataTreeState.createInitial(rootNode); if (schemaContext != null) { setSchemaContext(schemaContext); @@ -55,12 +61,31 @@ final class InMemoryDataTree implements DataTree { LOG.debug("Following schema contexts will be attempted {}", newSchemaContext); - final SchemaAwareApplyOperation operation = SchemaAwareApplyOperation.from(newSchemaContext); + final DataSchemaContextTree contextTree = DataSchemaContextTree.from(newSchemaContext); + final DataSchemaContextNode rootContextNode = contextTree.getChild(rootPath); + if (rootContextNode == null) { + LOG.debug("Could not find root {} in new schema context, not upgrading", rootPath); + return; + } + + final DataSchemaNode rootSchemaNode = rootContextNode.getDataSchemaNode(); + if (!(rootSchemaNode instanceof DataNodeContainer)) { + LOG.warn("Root {} resolves to non-container type {}, not upgrading", rootPath, rootSchemaNode); + return; + } + + final ModificationApplyOperation rootNode; + if (rootSchemaNode instanceof ContainerSchemaNode) { + // FIXME: real root needs to enfore presence, but that require pre-population + rootNode = new ContainerModificationStrategy((ContainerSchemaNode) rootSchemaNode, treeType); + } else { + rootNode = SchemaAwareApplyOperation.from(rootSchemaNode, treeType); + } DataTreeState currentState, newState; do { currentState = state; - newState = currentState.withSchemaContext(newSchemaContext, operation); + newState = currentState.withSchemaContext(newSchemaContext, rootNode); } while (!STATE_UPDATER.compareAndSet(this, currentState, newState)); } @@ -69,46 +94,19 @@ final class InMemoryDataTree implements DataTree { return state.newSnapshot(); } - @Override - public void validate(final DataTreeModification modification) throws DataValidationFailedException { - Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass()); - final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification; - - m.getStrategy().checkApplicable(PUBLIC_ROOT_PATH, m.getRootModification(), Optional.of(state.getRoot())); - } - - @Override - public DataTreeCandidate prepare(final DataTreeModification modification) { - Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass()); - - final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification; - final ModifiedNode root = m.getRootModification(); - - if (root.getOperation() == LogicalOperation.NONE) { - return new NoopDataTreeCandidate(PUBLIC_ROOT_PATH, root); - } - - final TreeNode currentRoot = state.getRoot(); - final Optional newRoot = m.getStrategy().apply(m.getRootModification(), - Optional.of(currentRoot), m.getVersion()); - Preconditions.checkState(newRoot.isPresent(), "Apply strategy failed to produce root node"); - return new InMemoryDataTreeCandidate(PUBLIC_ROOT_PATH, root, currentRoot, newRoot.get()); - } - @Override public void commit(final DataTreeCandidate candidate) { if (candidate instanceof NoopDataTreeCandidate) { return; } - Preconditions.checkArgument(candidate instanceof InMemoryDataTreeCandidate, "Invalid candidate class %s", candidate.getClass()); final InMemoryDataTreeCandidate c = (InMemoryDataTreeCandidate)candidate; if (LOG.isTraceEnabled()) { - LOG.trace("Data Tree is {}", NormalizedNodes.toStringTree(c.getAfterRoot().getData())); + LOG.trace("Data Tree is {}", NormalizedNodes.toStringTree(c.getTipRoot().getData())); } - final TreeNode newRoot = c.getAfterRoot(); + final TreeNode newRoot = c.getTipRoot(); DataTreeState currentState, newState; do { currentState = state; @@ -123,8 +121,23 @@ final class InMemoryDataTree implements DataTree { } while (!STATE_UPDATER.compareAndSet(this, currentState, newState)); } + @Override + public YangInstanceIdentifier getRootPath() { + return rootPath; + } + @Override public String toString() { - return MoreObjects.toStringHelper(this).add("object", super.toString()).add("state", state).toString(); + return MoreObjects.toStringHelper(this). + add("object", super.toString()). + add("rootPath", rootPath). + add("state", state). + toString(); + } + + @Override + @Nonnull + protected TreeNode getTipRoot() { + return state.getRoot(); } }