X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=yang%2Fyang-data-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fimpl%2Fschema%2Ftree%2FInMemoryDataTreeFactory.java;h=a44ae5c98c2e22697266bc02b2af378fd3171a21;hb=a6ea70c09b13489918c387d54cde8f1095721acc;hp=486c1c2cf5569641e6de28df1ea444f67925c998;hpb=5d50486aed75e0b94a06952add2cc5d9a62ba053;p=yangtools.git diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTreeFactory.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTreeFactory.java index 486c1c2cf5..a44ae5c98c 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTreeFactory.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTreeFactory.java @@ -1,12 +1,38 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ package org.opendaylight.yangtools.yang.data.impl.schema.tree; - +import com.google.common.base.Preconditions; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; +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.DataTreeConfiguration; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration.Builder; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeFactory; +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.TreeNodeFactory; import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version; -import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder; +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.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; /** @@ -14,17 +40,125 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; */ public final class InMemoryDataTreeFactory implements DataTreeFactory { private static final InMemoryDataTreeFactory INSTANCE = new InMemoryDataTreeFactory(); + private static final NormalizedNode ROOT_CONTAINER = ImmutableNodes.containerNode(SchemaContext.NAME); private InMemoryDataTreeFactory() { // Never instantiated externally } + @Deprecated + @Override + public TipProducingDataTree create(final TreeType treeType) { + return create(DataTreeConfiguration.getDefault(treeType)); + } + + @Deprecated @Override - public InMemoryDataTree create() { - final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME); - final NormalizedNode data = Builders.containerBuilder().withNodeIdentifier(root).build(); + public TipProducingDataTree create(final TreeType treeType, final YangInstanceIdentifier rootPath) { + if (rootPath.isEmpty()) { + return create(treeType); + } + + final DataTreeConfiguration defConfig = DataTreeConfiguration.getDefault(treeType); + final DataTreeConfiguration config; + if (!rootPath.isEmpty()) { + config = new Builder(treeType).setMandatoryNodesValidation(defConfig.isMandatoryNodesValidationEnabled()) + .setRootPath(rootPath).setUniqueIndexes(defConfig.isUniqueIndexEnabled()).build(); + } else { + config = defConfig; + } + + return new InMemoryDataTree(TreeNodeFactory.createTreeNode(createRoot(rootPath), Version.initial()), config, + null); + } + + @Override + public TipProducingDataTree create(final DataTreeConfiguration treeConfig) { + return new InMemoryDataTree(TreeNodeFactory.createTreeNode(createRoot(treeConfig.getRootPath()), + Version.initial()), treeConfig, null); + } + + @Override + public DataTree create(final DataTreeConfiguration treeConfig, final SchemaContext initialSchemaContext) { + return create(treeConfig, initialSchemaContext, true); + } + + @Override + public DataTree create(final DataTreeConfiguration treeConfig, final SchemaContext initialSchemaContext, + final NormalizedNodeContainer initialRoot) throws DataValidationFailedException { + final DataTree ret = create(treeConfig, initialSchemaContext, false); + + final DataTreeModification mod = ret.takeSnapshot().newModification(); + mod.write(YangInstanceIdentifier.EMPTY, initialRoot); + mod.ready(); + + ret.validate(mod); + final DataTreeCandidate candidate = ret.prepare(mod); + ret.commit(candidate); + return ret; + } + + private static DataTree create(final DataTreeConfiguration treeConfig, final SchemaContext initialSchemaContext, + final boolean maskMandatory) { + final DataSchemaNode rootSchemaNode = getRootSchemaNode(initialSchemaContext, treeConfig.getRootPath()); + final NormalizedNode rootDataNode = createRoot((DataNodeContainer)rootSchemaNode, + treeConfig.getRootPath()); + return new InMemoryDataTree(TreeNodeFactory.createTreeNode(rootDataNode, Version.initial()), treeConfig, + initialSchemaContext, rootSchemaNode, maskMandatory); + } + + private static DataSchemaNode getRootSchemaNode(final SchemaContext schemaContext, + final YangInstanceIdentifier rootPath) { + final DataSchemaContextTree contextTree = DataSchemaContextTree.from(schemaContext); + final DataSchemaContextNode rootContextNode = contextTree.getChild(rootPath); + Preconditions.checkArgument(rootContextNode != null, "Failed to find root %s in schema context", rootPath); + + final DataSchemaNode rootSchemaNode = rootContextNode.getDataSchemaNode(); + Preconditions.checkArgument(rootSchemaNode instanceof DataNodeContainer, + "Root %s resolves to non-container type %s", rootPath, rootSchemaNode); + return rootSchemaNode; + } + + private static NormalizedNode createRoot(final DataNodeContainer schemaNode, + final YangInstanceIdentifier path) { + if (path.isEmpty()) { + Preconditions.checkArgument(schemaNode instanceof ContainerSchemaNode, + "Conceptual tree root has to be a container, not %s", schemaNode); + return ROOT_CONTAINER; + } + + final PathArgument arg = path.getLastPathArgument(); + if (schemaNode instanceof ContainerSchemaNode) { + Preconditions.checkArgument(arg instanceof NodeIdentifier, "Mismatched container %s path %s", schemaNode, + path); + return ImmutableContainerNodeBuilder.create().withNodeIdentifier((NodeIdentifier) arg).build(); + } else if (schemaNode instanceof ListSchemaNode) { + // This can either be a top-level list or its individual entry + if (arg instanceof NodeIdentifierWithPredicates) { + return ImmutableNodes.mapEntryBuilder().withNodeIdentifier((NodeIdentifierWithPredicates) arg).build(); + } + Preconditions.checkArgument(arg instanceof NodeIdentifier, "Mismatched list %s path %s", schemaNode, path); + return ImmutableNodes.mapNodeBuilder().withNodeIdentifier((NodeIdentifier) arg).build(); + } else { + throw new IllegalArgumentException("Unsupported root schema " + schemaNode); + } + } + + private static NormalizedNode createRoot(final YangInstanceIdentifier path) { + if (path.isEmpty()) { + return ROOT_CONTAINER; + } + + final PathArgument arg = path.getLastPathArgument(); + if (arg instanceof NodeIdentifier) { + return ImmutableContainerNodeBuilder.create().withNodeIdentifier((NodeIdentifier) arg).build(); + } + if (arg instanceof NodeIdentifierWithPredicates) { + return ImmutableNodes.mapEntryBuilder().withNodeIdentifier((NodeIdentifierWithPredicates) arg).build(); + } - return new InMemoryDataTree(TreeNodeFactory.createTreeNode(data, Version.initial()), null); + // FIXME: implement augmentations and leaf-lists + throw new IllegalArgumentException("Unsupported root node " + arg); } /** @@ -32,7 +166,7 @@ public final class InMemoryDataTreeFactory implements DataTreeFactory { * * @return Data tree factory instance. */ - public static final InMemoryDataTreeFactory getInstance() { + public static InMemoryDataTreeFactory getInstance() { return INSTANCE; } }