From 7af7cb55efabba3429211fe1c295b40fb616e15f Mon Sep 17 00:00:00 2001 From: Tomas Cere Date: Tue, 28 Apr 2015 14:35:13 +0200 Subject: [PATCH] Add hooking into NormalizedNodeParsers. Makes it possible to add a ParsingStrategy into the parsers, to allow for callbacks/custom processing while parsing. DefaultParsingStrategy has the same behaviour as the already present parsers. Change-Id: I5998af4befaf31d3af3f4cf5e2f46ddc32b1e05b Signed-off-by: Tomas Cere Signed-off-by: Maros Marsalek --- .../generator/impl/BindingGeneratorImpl.java | 1 + .../transform/ToNormalizedNodeParser.java | 2 + .../parser/AugmentationNodeBaseParser.java | 8 +- .../base/parser/BaseDispatcherParser.java | 102 +++++++++++++++--- .../base/parser/ChoiceNodeBaseParser.java | 8 +- .../base/parser/ContainerNodeBaseParser.java | 9 +- .../base/parser/ExtensibleParser.java | 60 +++++++++++ .../base/parser/LeafNodeBaseParser.java | 46 ++++++-- .../parser/LeafSetEntryNodeBaseParser.java | 45 ++++++-- .../base/parser/LeafSetNodeBaseParser.java | 1 - .../base/parser/ListEntryNodeBaseParser.java | 12 ++- .../base/parser/ListNodeBaseParser.java | 43 +++++++- .../base/parser/MapNodeBaseParser.java | 8 ++ .../parser/OrderedListNodeBaseParser.java | 10 ++ .../parser/UnkeyedListNodeBaseParser.java | 8 ++ .../dom/parser/AugmentationNodeDomParser.java | 14 ++- .../dom/parser/ChoiceNodeDomParser.java | 17 ++- .../dom/parser/ContainerNodeDomParser.java | 18 ++-- .../DomToNormalizedNodeParserFactory.java | 89 +++++++++++++++ .../dom/parser/LeafNodeDomParser.java | 13 ++- .../dom/parser/LeafSetEntryNodeDomParser.java | 17 ++- .../dom/parser/ListEntryNodeDomParser.java | 8 +- .../dom/parser/MapEntryNodeDomParser.java | 10 +- .../dom/parser/MapNodeDomParser.java | 10 +- .../dom/parser/OrderedListNodeDomParser.java | 10 +- .../parser/UnkeyedListEntryNodeDomParser.java | 6 +- .../dom/parser/UnkeyedListNodeDomParser.java | 8 ++ .../operations/YangDataOperationsTest.java | 2 +- 28 files changed, 512 insertions(+), 73 deletions(-) create mode 100644 yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ExtensibleParser.java diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java index 66f3bc0424..15b818e43d 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java @@ -38,6 +38,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import org.opendaylight.yangtools.sal.binding.generator.impl.YangTemplate; import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil; import org.opendaylight.yangtools.binding.generator.util.BindingTypes; import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl; diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/ToNormalizedNodeParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/ToNormalizedNodeParser.java index a300cc07d4..04c4ed8f73 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/ToNormalizedNodeParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/ToNormalizedNodeParser.java @@ -7,6 +7,7 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform; +import javax.annotation.Nullable; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; /** @@ -33,5 +34,6 @@ public interface ToNormalizedNodeParser, S> { * @param schema * @return NormalizedNode as a result of parsing list of E elements with schema S */ + @Nullable N parse(Iterable xmlDom, S schema); } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/AugmentationNodeBaseParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/AugmentationNodeBaseParser.java index 7c3938fe08..bd7853a5dd 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/AugmentationNodeBaseParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/AugmentationNodeBaseParser.java @@ -26,7 +26,13 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; * @param type of elements to be parsed */ public abstract class AugmentationNodeBaseParser extends - BaseDispatcherParser { + BaseDispatcherParser { + + public AugmentationNodeBaseParser(final BuildingStrategy buildingStrategy) { + super(buildingStrategy); + } + + public AugmentationNodeBaseParser() {} @Override protected final DataContainerNodeBuilder getBuilder(final AugmentationSchema schema) { diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/BaseDispatcherParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/BaseDispatcherParser.java index a594e5d763..503da68031 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/BaseDispatcherParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/BaseDispatcherParser.java @@ -14,30 +14,42 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; +import javax.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.AttributesBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema; /** * Abstract(base) Parser for DataContainerNodes e.g. ContainerNode, AugmentationNode. */ -public abstract class BaseDispatcherParser, S> - implements ToNormalizedNodeParser { +public abstract class BaseDispatcherParser, S> + implements ExtensibleParser { + + private final BuildingStrategy buildingStrategy; + + public BaseDispatcherParser(final BuildingStrategy buildingStrategy) { + this.buildingStrategy = buildingStrategy; + } + + public BaseDispatcherParser() { + this.buildingStrategy = new SimpleBuildingStrategy<>(); + } /** * * @param schema * @return New(empty) instance of a builder to build node identified by schema. */ - protected abstract DataContainerNodeBuilder getBuilder(S schema); + protected abstract DataContainerNodeBuilder getBuilder(S schema); /** * @@ -88,12 +100,19 @@ public abstract class BaseDispatcherParser, S> */ protected abstract NodeParserDispatcher getDispatcher(); + /** + * can return null only if you override ParsingStrategy and explicitely return null + * @param elements + * @param schema + * @return + */ + @Nullable @Override public N parse(final Iterable elements, final S schema) { checkAtLeastOneNode(schema, elements); - DataContainerNodeBuilder containerBuilder = getBuilder(schema); + DataContainerNodeBuilder containerBuilder = getBuilder(schema); // Map child nodes to QName LinkedListMultimap mappedChildElements = mapChildElements(elements); @@ -106,6 +125,36 @@ public abstract class BaseDispatcherParser, S> Map mappedChoiceChildNodes = mapChildElementsFromChoices(schema); LinkedListMultimap choicesToElements = LinkedListMultimap.create(); + Map attributes = getAttributes(elements.iterator().next()); + if (containerBuilder instanceof AttributesBuilder) { + final int size = Iterables.size(elements); + Preconditions.checkArgument(size == 1, "Unexpected number of elements: %s, should be 1 for: %s", + size, schema); + ((AttributesBuilder) containerBuilder).withAttributes(attributes); + } + + //parse keys first + if (schema instanceof ListSchemaNode) { + for (QName qname : ((ListSchemaNode) schema).getKeyDefinition()) { + if(mappedChildElements.get(qname.withoutRevision()).isEmpty()) { + continue; + } + + DataSchemaNode childSchema = getSchemaForChild(schema, qname); + List childrenForQName = mappedChildElements.removeAll(qname.withoutRevision()); + + + DataContainerChild optionalChildNode = getDispatcher() + .dispatchChildElement(childSchema, childrenForQName); + if (optionalChildNode != null) { + containerBuilder.withChild(optionalChildNode); + } + } + } + + //stage attribues for strategy before going deeper in the recursion + buildingStrategy.prepareAttributes(attributes, containerBuilder); + // process Child nodes for (QName childPartialQName : mappedChildElements.keySet()) { DataSchemaNode childSchema = getSchemaForChild(schema, childPartialQName); @@ -125,32 +174,39 @@ public abstract class BaseDispatcherParser, S> choicesToElements.putAll(choiceSchema, childrenForQName); // Regular child nodes } else { - DataContainerChild builtChildNode = getDispatcher() + DataContainerChild optionalChildNode = getDispatcher() .dispatchChildElement(childSchema, childrenForQName); - containerBuilder.withChild(builtChildNode); + if (optionalChildNode != null) { + containerBuilder.withChild(optionalChildNode); + } } } // TODO ordering is not preserved for choice and augment elements for (ChoiceSchemaNode choiceSchema : choicesToElements.keySet()) { - containerBuilder.withChild(getDispatcher().dispatchChildElement(choiceSchema, - choicesToElements.get(choiceSchema))); + DataContainerChild optionalChild = getDispatcher() + .dispatchChildElement(choiceSchema, choicesToElements.get(choiceSchema)); + if (optionalChild != null) { + containerBuilder.withChild(optionalChild); + } } for (AugmentationSchema augmentSchema : augmentsToElements.keySet()) { Set realChildSchemas = getRealSchemasForAugment(schema, augmentSchema); EffectiveAugmentationSchema augSchemaProxy = new EffectiveAugmentationSchema(augmentSchema, realChildSchemas); - containerBuilder.withChild(getDispatcher().dispatchChildElement(augSchemaProxy, augmentsToElements.get(augmentSchema))); + DataContainerChild optionalChild = getDispatcher() + .dispatchChildElement(augSchemaProxy, augmentsToElements.get(augmentSchema)); + if (optionalChild != null) { + containerBuilder.withChild(optionalChild); + } } - if (containerBuilder instanceof AttributesBuilder) { - final int size = Iterables.size(elements); - Preconditions.checkArgument(size == 1, "Unexpected number of elements: %s, should be 1 for: %s", - size, schema); - ((AttributesBuilder) containerBuilder).withAttributes(getAttributes(elements.iterator().next())); - } + return buildingStrategy.build(containerBuilder); + } - return containerBuilder.build(); + @Override + public BuildingStrategy getBuildingStrategy() { + return buildingStrategy; } protected Map getAttributes(final E e) { @@ -175,4 +231,16 @@ public abstract class BaseDispatcherParser, S> Preconditions.checkArgument(!Iterables.isEmpty(childNodes), "Node detected 0 times, should be at least 1, identified by: %s, found: %s", schema, childNodes); } + + public static class SimpleBuildingStrategy

> implements BuildingStrategy { + @Override + public N build(final NormalizedNodeBuilder builder) { + return builder.build(); + } + + @Override + public void prepareAttributes(final Map attributes, final NormalizedNodeBuilder containerBuilder) { + // NOOP + } + } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ChoiceNodeBaseParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ChoiceNodeBaseParser.java index a82f71685a..371c59c355 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ChoiceNodeBaseParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ChoiceNodeBaseParser.java @@ -28,7 +28,13 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; * * @param type of elements to be parsed */ -public abstract class ChoiceNodeBaseParser extends BaseDispatcherParser { +public abstract class ChoiceNodeBaseParser extends BaseDispatcherParser { + + protected ChoiceNodeBaseParser() {} + + protected ChoiceNodeBaseParser(final BuildingStrategy buildingStrategy) { + super(buildingStrategy); + } @Override protected final DataContainerNodeBuilder getBuilder( diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ContainerNodeBaseParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ContainerNodeBaseParser.java index f7cca88155..99801cf3a1 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ContainerNodeBaseParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ContainerNodeBaseParser.java @@ -27,7 +27,13 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; * @param type of elements to be parsed */ public abstract class ContainerNodeBaseParser extends - BaseDispatcherParser { + BaseDispatcherParser { + + public ContainerNodeBaseParser() {} + + public ContainerNodeBaseParser(final BuildingStrategy buildingStrategy) { + super(buildingStrategy); + } @Override protected final DataContainerNodeBuilder getBuilder( @@ -63,4 +69,5 @@ public abstract class ContainerNodeBaseParser extends @Override protected abstract Map getAttributes(E e); + } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ExtensibleParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ExtensibleParser.java new file mode 100644 index 0000000000..e2b5ec7e6d --- /dev/null +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ExtensibleParser.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015 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.transform.base.parser; + +import java.util.Map; +import javax.annotation.Nullable; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser; + +/** + * Extensible parser allows its subclasses to customize the building process of normalized nodes + * + * @param

+ * @param + * @param + * @param + */ +public interface ExtensibleParser

, S> + extends ToNormalizedNodeParser { + + /** + * Provide building strategy + */ + BuildingStrategy getBuildingStrategy(); + + /** + * Building strategy serves as a set of hooks into the parsing process. + * + * @param

+ * @param + */ + interface BuildingStrategy

> { + + /** + * Build normalized node from its builder + * + * @param builder filled builder for node + * @return built normalized node or null if the node should not be built + */ + @Nullable N build(NormalizedNodeBuilder builder); + + /** + * Hook for subclasses to handle attributes associated with current node. This is called before the build method + * and allows subclasses to react to node's attributes e.g. modification operation + * + * @param attributes attributes for node + * @param containerBuilder builder created for node. Can be modified according to attributes e.g. remove attribute + */ + void prepareAttributes(Map attributes, NormalizedNodeBuilder containerBuilder); + } +} diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafNodeBaseParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafNodeBaseParser.java index 4056d1da18..f5dc67e1a3 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafNodeBaseParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafNodeBaseParser.java @@ -7,27 +7,36 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser; +import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; import java.util.Map; - import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; -import com.google.common.base.Preconditions; -import com.google.common.collect.Iterables; - /** * Abstract(base) parser for LeafNodes, parses elements of type E. * * @param type of elements to be parsed */ -public abstract class LeafNodeBaseParser implements - ToNormalizedNodeParser, LeafSchemaNode> { +public abstract class LeafNodeBaseParser implements ExtensibleParser, LeafSchemaNode> { + + private final BuildingStrategy> buildingStrategy; + + public LeafNodeBaseParser() { + buildingStrategy = new SimpleLeafBuildingStrategy(); + } + public LeafNodeBaseParser(final BuildingStrategy> buildingStrategy) { + this.buildingStrategy = buildingStrategy; + } + + @SuppressWarnings("unchecked") @Override public final LeafNode parse(Iterable elements, LeafSchemaNode schema) { final int size = Iterables.size(elements); @@ -36,11 +45,13 @@ public abstract class LeafNodeBaseParser implements final E e = elements.iterator().next(); Object value = parseLeaf(e, schema); - NormalizedNodeAttrBuilder> leafBuilder = Builders.leafBuilder(schema); + NormalizedNodeAttrBuilder> leafBuilder = + Builders.leafBuilder(schema); leafBuilder.withAttributes(getAttributes(e)); - return leafBuilder.withValue(value).build(); + final BuildingStrategy rawBuildingStrat = buildingStrategy; + return (LeafNode) rawBuildingStrat.build(leafBuilder.withValue(value)); } /** @@ -59,4 +70,21 @@ public abstract class LeafNodeBaseParser implements * @return attributes mapped to QNames */ protected abstract Map getAttributes(E e); + + @Override + public BuildingStrategy> getBuildingStrategy() { + return buildingStrategy; + } + + public static class SimpleLeafBuildingStrategy implements BuildingStrategy> { + @Override + public LeafNode build(final NormalizedNodeBuilder> builder) { + return builder.build(); + } + + @Override + public void prepareAttributes(final Map attributes, final NormalizedNodeBuilder> containerBuilder) { + // NOOP + } + } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafSetEntryNodeBaseParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafSetEntryNodeBaseParser.java index 526cdf8615..7006c269ad 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafSetEntryNodeBaseParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafSetEntryNodeBaseParser.java @@ -7,29 +7,38 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser; +import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; import java.util.Map; - import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue; import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; -import com.google.common.base.Preconditions; -import com.google.common.collect.Iterables; - /** * Abstract(base) parser for LeafSetEntryNodes, parses elements of type E. * * @param type of elements to be parsed */ -public abstract class LeafSetEntryNodeBaseParser implements - ToNormalizedNodeParser, LeafListSchemaNode> { +public abstract class LeafSetEntryNodeBaseParser implements ExtensibleParser, LeafListSchemaNode> { + + private final BuildingStrategy> buildingStrategy; + + public LeafSetEntryNodeBaseParser() { + buildingStrategy = new SimpleLeafSetEntryBuildingStrategy(); + } + public LeafSetEntryNodeBaseParser(final BuildingStrategy> buildingStrategy) { + this.buildingStrategy = buildingStrategy; + } + + @SuppressWarnings("unchecked") @Override - public final LeafSetEntryNode parse(Iterable elements, LeafListSchemaNode schema) { + public final LeafSetEntryNode parse(Iterable elements, LeafListSchemaNode schema) { final int size = Iterables.size(elements); Preconditions.checkArgument(size == 1, "Xml elements mapped to leaf node illegal count: %s", size); @@ -39,8 +48,15 @@ public abstract class LeafSetEntryNodeBaseParser implements NormalizedNodeAttrBuilder> leafEntryBuilder = Builders .leafSetEntryBuilder(schema); leafEntryBuilder.withAttributes(getAttributes(e)); + leafEntryBuilder.withValue(value); + + final BuildingStrategy rawBuildingStrat = buildingStrategy; + return (LeafSetEntryNode) rawBuildingStrat.build(leafEntryBuilder); + } - return leafEntryBuilder.withValue(value).build(); + @Override + public BuildingStrategy> getBuildingStrategy() { + return buildingStrategy; } /** @@ -60,4 +76,15 @@ public abstract class LeafSetEntryNodeBaseParser implements */ protected abstract Map getAttributes(E e); + public static class SimpleLeafSetEntryBuildingStrategy implements BuildingStrategy> { + + @Override + public LeafSetEntryNode build(final NormalizedNodeBuilder> builder) { + return builder.build(); + } + + @Override + public void prepareAttributes(final Map attributes, final NormalizedNodeBuilder> containerBuilder) { + } + } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafSetNodeBaseParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafSetNodeBaseParser.java index 4cdae37f35..3669cba16b 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafSetNodeBaseParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafSetNodeBaseParser.java @@ -8,7 +8,6 @@ package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser; import java.util.Collections; - import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ListEntryNodeBaseParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ListEntryNodeBaseParser.java index dfa34abcc7..cd0b478ec0 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ListEntryNodeBaseParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ListEntryNodeBaseParser.java @@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser; import java.util.Map; import java.util.Set; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; @@ -24,8 +25,15 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; * @param * type of elements to be parsed */ -public abstract class ListEntryNodeBaseParser> extends - BaseDispatcherParser { +public abstract class ListEntryNodeBaseParser

> extends + BaseDispatcherParser { + + public ListEntryNodeBaseParser(final BuildingStrategy buildingStrategy) { + super(buildingStrategy); + } + + public ListEntryNodeBaseParser() { + } @Override protected final Set getRealSchemasForAugment(final ListSchemaNode schema, final AugmentationSchema augmentSchema) { diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ListNodeBaseParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ListNodeBaseParser.java index 67c97a767d..f8bc9c120b 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ListNodeBaseParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ListNodeBaseParser.java @@ -8,9 +8,12 @@ package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser; import java.util.Collections; +import java.util.Map; +import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; @@ -21,17 +24,32 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; * type of elements to be parsed */ public abstract class ListNodeBaseParser, O extends NormalizedNode, S extends ListSchemaNode> - implements ToNormalizedNodeParser { + implements ExtensibleParser { + + private final BuildingStrategy buildingStrategy; + + public ListNodeBaseParser() { + buildingStrategy = new SimpleListNodeBuildingStrategy<>(); + } + + public ListNodeBaseParser(final BuildingStrategy buildingStrategy) { + this.buildingStrategy = buildingStrategy; + } @Override - public final O parse(Iterable childNodes, S schema) { + public O parse(Iterable childNodes, S schema) { CollectionNodeBuilder listBuilder = provideBuilder(schema); + + buildingStrategy.prepareAttributes(Collections.emptyMap(), listBuilder); + for (E childNode : childNodes) { N listChild = getListEntryNodeParser().parse(Collections.singletonList(childNode), schema); - listBuilder.withChild(listChild); + if (listChild != null) { + listBuilder.withChild(listChild); + } } - return listBuilder.build(); + return buildingStrategy.build(listBuilder); } /** @@ -46,4 +64,21 @@ public abstract class ListNodeBaseParser, O ex * @return prepares builder which will contain entries of list according to concrete list type */ protected abstract CollectionNodeBuilder provideBuilder(S schema); + + @Override + public BuildingStrategy getBuildingStrategy() { + return buildingStrategy; + } + + public static class SimpleListNodeBuildingStrategy> implements BuildingStrategy { + @Override + public O build(final NormalizedNodeBuilder builder) { + return builder.build(); + } + + @Override + public void prepareAttributes(final Map attributes, final NormalizedNodeBuilder containerBuilder) { + // NOOP + } + } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/MapNodeBaseParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/MapNodeBaseParser.java index a57a694e12..8056340465 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/MapNodeBaseParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/MapNodeBaseParser.java @@ -7,6 +7,7 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; @@ -21,6 +22,13 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; */ public abstract class MapNodeBaseParser extends ListNodeBaseParser { + public MapNodeBaseParser() { + } + + public MapNodeBaseParser(final BuildingStrategy buildingStrategy) { + super(buildingStrategy); + } + protected CollectionNodeBuilder provideBuilder(ListSchemaNode schema) { return Builders.mapBuilder(schema); } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/OrderedListNodeBaseParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/OrderedListNodeBaseParser.java index 6278accb61..a2ca255ce8 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/OrderedListNodeBaseParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/OrderedListNodeBaseParser.java @@ -7,6 +7,7 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; @@ -21,8 +22,17 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; */ public abstract class OrderedListNodeBaseParser extends ListNodeBaseParser { + + public OrderedListNodeBaseParser() { + } + + public OrderedListNodeBaseParser(final BuildingStrategy buildingStrategy) { + super(buildingStrategy); + } + @Override protected CollectionNodeBuilder provideBuilder(ListSchemaNode schema) { return Builders.orderedMapBuilder(schema); } + } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/UnkeyedListNodeBaseParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/UnkeyedListNodeBaseParser.java index 14d47890cf..73e7f39052 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/UnkeyedListNodeBaseParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/UnkeyedListNodeBaseParser.java @@ -22,6 +22,14 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; */ public abstract class UnkeyedListNodeBaseParser extends ListNodeBaseParser { + + public UnkeyedListNodeBaseParser(final BuildingStrategy buildingStrategy) { + super(buildingStrategy); + } + + public UnkeyedListNodeBaseParser() { + } + @Override protected CollectionNodeBuilder provideBuilder(ListSchemaNode schema) { CollectionNodeBuilder listBuilder = Builders.unkeyedListBuilder(); diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/AugmentationNodeDomParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/AugmentationNodeDomParser.java index 73167f407a..3fed808ad9 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/AugmentationNodeDomParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/AugmentationNodeDomParser.java @@ -7,15 +7,16 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser; +import com.google.common.base.Preconditions; +import com.google.common.collect.LinkedListMultimap; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.AugmentationNodeBaseParser; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher; import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils; import org.w3c.dom.Element; -import com.google.common.base.Preconditions; -import com.google.common.collect.LinkedListMultimap; - final class AugmentationNodeDomParser extends AugmentationNodeBaseParser { private final NodeParserDispatcher dispatcher; @@ -31,6 +32,13 @@ final class AugmentationNodeDomParser extends AugmentationNodeBaseParser buildingStrategy, + final NodeParserDispatcher dispatcher, final boolean strictParsing) { + super(buildingStrategy); + this.dispatcher = Preconditions.checkNotNull(dispatcher); + this.strictParsing = strictParsing; + } + @Override protected LinkedListMultimap mapChildElements(Iterable elements) { return DomUtils.mapChildElements(elements); diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ChoiceNodeDomParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ChoiceNodeDomParser.java index 97e8a6171c..2c2ccc6ad7 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ChoiceNodeDomParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ChoiceNodeDomParser.java @@ -7,25 +7,31 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser; +import com.google.common.base.Preconditions; +import com.google.common.collect.LinkedListMultimap; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ChoiceNodeBaseParser; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher; import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils; import org.w3c.dom.Element; -import com.google.common.base.Preconditions; -import com.google.common.collect.LinkedListMultimap; - final class ChoiceNodeDomParser extends ChoiceNodeBaseParser { private final NodeParserDispatcher dispatcher; - ChoiceNodeDomParser(NodeParserDispatcher dispatcher) { + ChoiceNodeDomParser(final NodeParserDispatcher dispatcher) { + this.dispatcher = Preconditions.checkNotNull(dispatcher); + } + + ChoiceNodeDomParser(final NodeParserDispatcher dispatcher, final BuildingStrategy buildingStrategy) { + super(buildingStrategy); this.dispatcher = Preconditions.checkNotNull(dispatcher); } @Override - protected LinkedListMultimap mapChildElements(Iterable xml) { + protected LinkedListMultimap mapChildElements(final Iterable xml) { return DomUtils.mapChildElements(xml); } @@ -33,4 +39,5 @@ final class ChoiceNodeDomParser extends ChoiceNodeBaseParser { protected NodeParserDispatcher getDispatcher() { return dispatcher; } + } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ContainerNodeDomParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ContainerNodeDomParser.java index ed4f2772ed..397df436a5 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ContainerNodeDomParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ContainerNodeDomParser.java @@ -7,17 +7,17 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser; +import com.google.common.base.Preconditions; +import com.google.common.collect.LinkedListMultimap; import java.util.Map; - import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ContainerNodeBaseParser; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher; import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils; import org.w3c.dom.Element; -import com.google.common.base.Preconditions; -import com.google.common.collect.LinkedListMultimap; - final class ContainerNodeDomParser extends ContainerNodeBaseParser { private final NodeParserDispatcher dispatcher; @@ -25,10 +25,16 @@ final class ContainerNodeDomParser extends ContainerNodeBaseParser { ContainerNodeDomParser(final NodeParserDispatcher dispatcher) { this.dispatcher = Preconditions.checkNotNull(dispatcher); - this.strictParsing = super.strictParsing(); + strictParsing = super.strictParsing(); + } + + public ContainerNodeDomParser(final NodeParserDispatcher dispatcher, final boolean strictParsing) { + this.dispatcher = dispatcher; + this.strictParsing = strictParsing; } - ContainerNodeDomParser(final NodeParserDispatcher dispatcher, final boolean strictParsing) { + ContainerNodeDomParser(final NodeParserDispatcher dispatcher, final BuildingStrategy parsingStrategy, final boolean strictParsing) { + super(parsingStrategy); this.dispatcher = Preconditions.checkNotNull(dispatcher); this.strictParsing = strictParsing; } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/DomToNormalizedNodeParserFactory.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/DomToNormalizedNodeParserFactory.java index 8e6381748e..b86289a7be 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/DomToNormalizedNodeParserFactory.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/DomToNormalizedNodeParserFactory.java @@ -7,6 +7,7 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode; import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode; import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode; @@ -22,6 +23,11 @@ import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode; import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider; import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser; import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParserFactory; +import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.BaseDispatcherParser; +import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ExtensibleParser; +import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafNodeBaseParser; +import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafSetEntryNodeBaseParser; +import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ListNodeBaseParser; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher; import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; @@ -34,6 +40,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.w3c.dom.Element; public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeParserFactory { + private final AugmentationNodeDomParser augmentationNodeParser; private final ChoiceNodeDomParser choiceNodeParser; private final ContainerNodeDomParser containerNodeParser; @@ -67,6 +74,31 @@ public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeP augmentationNodeParser = new AugmentationNodeDomParser(dispatcher, strictParsing); } + private DomToNormalizedNodeParserFactory(final XmlCodecProvider codecProvider, final SchemaContext schema, + final BuildingStrategyProvider buildingStratProvider, final boolean strictParsing) { + leafNodeParser = new LeafNodeDomParser(codecProvider, schema, buildingStratProvider.forLeaf()); + leafSetEntryNodeParser = new LeafSetEntryNodeDomParser(codecProvider, schema, buildingStratProvider.forLeafSetEntry()); + + // no buildingStrategy for Augment (no use case for now) + leafSetNodeParser = new LeafSetNodeDomParser(leafSetEntryNodeParser); + // no buildingStrategy for anyXml (probably not necessary) + anyXmlNodeParser = new AnyXmlDomParser(); + + final NodeParserDispatcher dispatcher = new NodeParserDispatcher.BaseNodeParserDispatcher(this) { + + }; + + containerNodeParser = new ContainerNodeDomParser(dispatcher, buildingStratProvider.forContainer(), strictParsing); + mapEntryNodeParser = new MapEntryNodeDomParser(dispatcher, buildingStratProvider.forMapEntry(), strictParsing); + mapNodeParser = new MapNodeDomParser(mapEntryNodeParser, buildingStratProvider.forMap()); + orderedListNodeParser = new OrderedListNodeDomParser(mapEntryNodeParser, buildingStratProvider.forOrderedList()); + unkeyedListEntryNodeParser = new UnkeyedListEntryNodeDomParser(buildingStratProvider.forUnkeyedListEntry(), dispatcher); + unkeyedListNodeParser = new UnkeyedListNodeDomParser(buildingStratProvider.forUnkeyedList(), unkeyedListEntryNodeParser); + choiceNodeParser = new ChoiceNodeDomParser(dispatcher, buildingStratProvider.forChoice()); + // no buildingStrategy for Augment (no use case for now) + augmentationNodeParser = new AugmentationNodeDomParser(buildingStratProvider.forAugmentation(), dispatcher, strictParsing); + } + @Deprecated private DomToNormalizedNodeParserFactory(final XmlCodecProvider codecProvider) { leafNodeParser = new LeafNodeDomParser(codecProvider); @@ -96,6 +128,17 @@ public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeP return new DomToNormalizedNodeParserFactory(codecProvider, schema, true); } + public static DomToNormalizedNodeParserFactory getInstance(final XmlCodecProvider codecProvider, final SchemaContext schema, + final BuildingStrategyProvider buildingStratProvider) { + return new DomToNormalizedNodeParserFactory(codecProvider, schema, buildingStratProvider, true); + } + + public static DomToNormalizedNodeParserFactory getInstance(final XmlCodecProvider codecProvider, final SchemaContext schema, + final BuildingStrategyProvider buildingStratProvider, + final boolean strictParsing) { + return new DomToNormalizedNodeParserFactory(codecProvider, schema, buildingStratProvider, strictParsing); + } + @Deprecated public static DomToNormalizedNodeParserFactory getInstance(final XmlCodecProvider codecProvider) { return new DomToNormalizedNodeParserFactory(codecProvider); @@ -160,4 +203,50 @@ public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeP public ToNormalizedNodeParser getAnyXmlNodeParser() { return anyXmlNodeParser; } + + /** + * Base provider of building strategies used for customizing parsing process + */ + public static abstract class BuildingStrategyProvider { + + protected ExtensibleParser.BuildingStrategy> forLeaf() { + return new LeafNodeBaseParser.SimpleLeafBuildingStrategy(); + } + + protected ExtensibleParser.BuildingStrategy> forLeafSetEntry() { + return new LeafSetEntryNodeBaseParser.SimpleLeafSetEntryBuildingStrategy(); + } + + protected ExtensibleParser.BuildingStrategy forContainer() { + return new BaseDispatcherParser.SimpleBuildingStrategy<>(); + } + + protected ExtensibleParser.BuildingStrategy forMapEntry() { + return new BaseDispatcherParser.SimpleBuildingStrategy<>(); + } + + protected ExtensibleParser.BuildingStrategy forMap() { + return new ListNodeBaseParser.SimpleListNodeBuildingStrategy<>(); + } + + protected ExtensibleParser.BuildingStrategy forOrderedList() { + return new ListNodeBaseParser.SimpleListNodeBuildingStrategy<>(); + } + + protected ExtensibleParser.BuildingStrategy forUnkeyedListEntry() { + return new BaseDispatcherParser.SimpleBuildingStrategy<>(); + } + + protected ExtensibleParser.BuildingStrategy forUnkeyedList() { + return new ListNodeBaseParser.SimpleListNodeBuildingStrategy<>(); + } + + protected ExtensibleParser.BuildingStrategy forChoice() { + return new BaseDispatcherParser.SimpleBuildingStrategy<>(); + } + + public ExtensibleParser.BuildingStrategy forAugmentation() { + return new BaseDispatcherParser.SimpleBuildingStrategy<>(); + } + } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/LeafNodeDomParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/LeafNodeDomParser.java index 2e8ab87bd7..25b57ccf08 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/LeafNodeDomParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/LeafNodeDomParser.java @@ -7,9 +7,11 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser; +import com.google.common.base.Preconditions; import java.util.Map; - import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafNodeBaseParser; import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils; @@ -17,8 +19,6 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.w3c.dom.Element; -import com.google.common.base.Preconditions; - final class LeafNodeDomParser extends LeafNodeBaseParser { private final XmlCodecProvider codecProvider; @@ -29,6 +29,12 @@ final class LeafNodeDomParser extends LeafNodeBaseParser { this.codecProvider = Preconditions.checkNotNull(codecProvider); } + LeafNodeDomParser(XmlCodecProvider codecProvider, final SchemaContext schema, final BuildingStrategy> strategy) { + super(strategy); + this.ctx = schema; + this.codecProvider = Preconditions.checkNotNull(codecProvider); + } + @Deprecated LeafNodeDomParser(XmlCodecProvider codecProvider) { this(codecProvider, null); @@ -43,4 +49,5 @@ final class LeafNodeDomParser extends LeafNodeBaseParser { protected Map getAttributes(Element element) { return DomUtils.toAttributes(element.getAttributes()); } + } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/LeafSetEntryNodeDomParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/LeafSetEntryNodeDomParser.java index 0458cd5d10..decf901337 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/LeafSetEntryNodeDomParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/LeafSetEntryNodeDomParser.java @@ -7,9 +7,11 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser; +import com.google.common.base.Preconditions; import java.util.Map; - import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafSetEntryNodeBaseParser; import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils; @@ -17,15 +19,19 @@ import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.w3c.dom.Element; -import com.google.common.base.Preconditions; - final class LeafSetEntryNodeDomParser extends LeafSetEntryNodeBaseParser { private final XmlCodecProvider codecProvider; private final SchemaContext ctx; - LeafSetEntryNodeDomParser(XmlCodecProvider codecProvider, final SchemaContext schema) { - ctx = schema; + LeafSetEntryNodeDomParser(final XmlCodecProvider codecProvider, final SchemaContext schema) { + this.ctx = schema; + this.codecProvider = Preconditions.checkNotNull(codecProvider); + } + + LeafSetEntryNodeDomParser(final XmlCodecProvider codecProvider, final SchemaContext schema, final BuildingStrategy> strategy) { + super(strategy); + this.ctx = schema; this.codecProvider = Preconditions.checkNotNull(codecProvider); } @@ -43,4 +49,5 @@ final class LeafSetEntryNodeDomParser extends LeafSetEntryNodeBaseParser getAttributes(Element element) { return DomUtils.toAttributes(element.getAttributes()); } + } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ListEntryNodeDomParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ListEntryNodeDomParser.java index 92496d79f7..90aca17fd8 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ListEntryNodeDomParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ListEntryNodeDomParser.java @@ -11,13 +11,14 @@ import com.google.common.base.Preconditions; import com.google.common.collect.LinkedListMultimap; import java.util.Map; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ListEntryNodeBaseParser; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher; import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils; import org.w3c.dom.Element; -abstract class ListEntryNodeDomParser> extends ListEntryNodeBaseParser { +abstract class ListEntryNodeDomParser

> extends ListEntryNodeBaseParser { private final NodeParserDispatcher dispatcher; @@ -25,6 +26,11 @@ abstract class ListEntryNodeDomParser> extends Li this.dispatcher = Preconditions.checkNotNull(dispatcher); } + ListEntryNodeDomParser(final BuildingStrategy buildingStrategy, final NodeParserDispatcher dispatcher) { + super(buildingStrategy); + this.dispatcher = dispatcher; + } + @Override protected LinkedListMultimap mapChildElements(Iterable elements) { return DomUtils.mapChildElementsForSingletonNode(elements.iterator().next()); diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/MapEntryNodeDomParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/MapEntryNodeDomParser.java index a6c467c222..05a086476c 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/MapEntryNodeDomParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/MapEntryNodeDomParser.java @@ -15,12 +15,14 @@ import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.No import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.w3c.dom.Element; -final class MapEntryNodeDomParser extends ListEntryNodeDomParser { +final class MapEntryNodeDomParser extends ListEntryNodeDomParser { private final boolean strictParsing; MapEntryNodeDomParser(final NodeParserDispatcher dispatcher) { super(dispatcher); + // TODO strict parsing attribute should be injected into superclass via a constructor + // WIth current approach (getter) we have to call super.strictParsing in constructor and cannot reuse constructors this.strictParsing = super.strictParsing(); } @@ -29,6 +31,12 @@ final class MapEntryNodeDomParser extends ListEntryNodeDomParser { this.strictParsing = strictParsing; } + MapEntryNodeDomParser(final NodeParserDispatcher dispatcher, final BuildingStrategy strategy, + final boolean strictParsing) { + super(strategy, dispatcher); + this.strictParsing = strictParsing; + } + @Override protected final DataContainerNodeBuilder getBuilder( ListSchemaNode schema) { diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/MapNodeDomParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/MapNodeDomParser.java index 748564fdd1..0f1c822ae1 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/MapNodeDomParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/MapNodeDomParser.java @@ -7,7 +7,9 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.MapNodeBaseParser; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; @@ -17,7 +19,12 @@ final class MapNodeDomParser extends MapNodeBaseParser { private final MapEntryNodeDomParser mapEntryParser; - MapNodeDomParser(MapEntryNodeDomParser mapEntryParser) { + MapNodeDomParser(final MapEntryNodeDomParser mapEntryParser) { + this.mapEntryParser = mapEntryParser; + } + + MapNodeDomParser(MapEntryNodeDomParser mapEntryParser, final BuildingStrategy strategy) { + super(strategy); this.mapEntryParser = mapEntryParser; } @@ -25,4 +32,5 @@ final class MapNodeDomParser extends MapNodeBaseParser { protected ToNormalizedNodeParser getListEntryNodeParser() { return mapEntryParser; } + } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/OrderedListNodeDomParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/OrderedListNodeDomParser.java index 787bff8856..920c30f342 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/OrderedListNodeDomParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/OrderedListNodeDomParser.java @@ -7,7 +7,9 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode; import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.OrderedListNodeBaseParser; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; @@ -17,7 +19,12 @@ final class OrderedListNodeDomParser extends OrderedListNodeBaseParser private final MapEntryNodeDomParser mapEntryNodeParser; - OrderedListNodeDomParser(MapEntryNodeDomParser mapEntryNodeParser) { + OrderedListNodeDomParser(final MapEntryNodeDomParser mapEntryNodeParser) { + this.mapEntryNodeParser = mapEntryNodeParser; + } + + OrderedListNodeDomParser(MapEntryNodeDomParser mapEntryNodeParser, final BuildingStrategy strategy) { + super(strategy); this.mapEntryNodeParser = mapEntryNodeParser; } @@ -25,4 +32,5 @@ final class OrderedListNodeDomParser extends OrderedListNodeBaseParser protected ToNormalizedNodeParser getListEntryNodeParser() { return mapEntryNodeParser; } + } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/UnkeyedListEntryNodeDomParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/UnkeyedListEntryNodeDomParser.java index 781f06cb71..79d478fb47 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/UnkeyedListEntryNodeDomParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/UnkeyedListEntryNodeDomParser.java @@ -16,12 +16,16 @@ import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.No import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.w3c.dom.Element; -final class UnkeyedListEntryNodeDomParser extends ListEntryNodeDomParser { +final class UnkeyedListEntryNodeDomParser extends ListEntryNodeDomParser { UnkeyedListEntryNodeDomParser(final NodeParserDispatcher dispatcher) { super(dispatcher); } + UnkeyedListEntryNodeDomParser(final BuildingStrategy buildingStrategy, final NodeParserDispatcher dispatcher) { + super(buildingStrategy, dispatcher); + } + @Override protected final DataContainerNodeBuilder getBuilder( ListSchemaNode schema) { diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/UnkeyedListNodeDomParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/UnkeyedListNodeDomParser.java index 15eed32a2d..21ec64e5a5 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/UnkeyedListNodeDomParser.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/UnkeyedListNodeDomParser.java @@ -7,7 +7,9 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode; import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser; import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.UnkeyedListNodeBaseParser; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; @@ -21,8 +23,14 @@ final class UnkeyedListNodeDomParser extends UnkeyedListNodeBaseParser this.unkeyedListEntryNodeParser = unkeyedListEntryNodeParser; } + UnkeyedListNodeDomParser(final BuildingStrategy buildingStrategy, final UnkeyedListEntryNodeDomParser unkeyedListEntryNodeParser) { + super(buildingStrategy); + this.unkeyedListEntryNodeParser = unkeyedListEntryNodeParser; + } + @Override protected ToNormalizedNodeParser getListEntryNodeParser() { return unkeyedListEntryNodeParser; } + } diff --git a/yang/yang-data-operations/src/test/java/org/opendaylight/yangtools/yang/data/operations/YangDataOperationsTest.java b/yang/yang-data-operations/src/test/java/org/opendaylight/yangtools/yang/data/operations/YangDataOperationsTest.java index f05db1e5da..2fd5694c01 100644 --- a/yang/yang-data-operations/src/test/java/org/opendaylight/yangtools/yang/data/operations/YangDataOperationsTest.java +++ b/yang/yang-data-operations/src/test/java/org/opendaylight/yangtools/yang/data/operations/YangDataOperationsTest.java @@ -178,7 +178,7 @@ public class YangDataOperationsTest { Document currentConfigElement = readXmlToDocument(resourceAsStream); Preconditions.checkNotNull(currentConfigElement); - return Optional.of(DomToNormalizedNodeParserFactory.getInstance(DomUtils.defaultValueCodecProvider(), schema).getContainerNodeParser().parse( + return Optional.fromNullable(DomToNormalizedNodeParserFactory.getInstance(DomUtils.defaultValueCodecProvider(), schema).getContainerNodeParser().parse( Collections.singletonList(currentConfigElement.getDocumentElement()), containerNode)); } -- 2.36.6