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%2FInMemoryDataTreeFactory.java;h=b36776d88c479ed86695185e768c801830cce934;hb=5e2ee5120180b2cff62a6e8c2a2c172fbc625817;hp=ca32f6c1532167b43efb1bdcf35f6a99a260d756;hpb=dafd9f488c8f98e6fca5dd492c9bb29e7194b2cf;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 ca32f6c153..b36776d88c 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 @@ -7,42 +7,109 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.tree; +import com.google.common.base.Preconditions; +import org.kohsuke.MetaInfServices; 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.TipProducingDataTree; -import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType; +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.spi.TreeNodeFactory; import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version; 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; /** * A factory for creating in-memory data trees. */ +@MetaInfServices 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 + @Override + public DataTree create(final DataTreeConfiguration treeConfig) { + return new InMemoryDataTree(TreeNodeFactory.createTreeNode(createRoot(treeConfig.getRootPath()), + Version.initial()), treeConfig, null); } @Override - public TipProducingDataTree create(final TreeType treeType) { - return create(DataTreeConfiguration.getDefault(treeType)); + public DataTree create(final DataTreeConfiguration treeConfig, final SchemaContext initialSchemaContext) { + return create(treeConfig, initialSchemaContext, true); } @Override - public TipProducingDataTree create(final DataTreeConfiguration treeConfig) { - return new InMemoryDataTree(TreeNodeFactory.createTreeNode(createRoot(treeConfig.getRootPath()), - Version.initial()), treeConfig, null); + 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) { @@ -61,32 +128,4 @@ public final class InMemoryDataTreeFactory implements DataTreeFactory { // FIXME: implement augmentations and leaf-lists throw new IllegalArgumentException("Unsupported root node " + arg); } - - @Override - 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); - } - - /** - * Get an instance of this factory. This method cannot fail. - * - * @return Data tree factory instance. - */ - public static InMemoryDataTreeFactory getInstance() { - return INSTANCE; - } }