X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-common-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fsal%2Fcommon%2Fimpl%2Futil%2Fcompat%2FDataNormalizationOperation.java;h=b8dfca1604eb9e1ca82454f60f508abfffe01694;hp=941f2fdb39059950a5d3ae910848a282c7c3311a;hb=17d82f582a6bc13c78be3b19954ff8c021180e93;hpb=ac7eb6bcfe527ffd6bb25daaa658be5f91ed43ed diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java index 941f2fdb39..b8dfca1604 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java @@ -1,3 +1,10 @@ +/* + * 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.controller.md.sal.common.impl.util.compat; import static com.google.common.base.Preconditions.checkArgument; @@ -14,20 +21,22 @@ import java.util.concurrent.ConcurrentHashMap; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; +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.NodeWithValue; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.Node; import org.opendaylight.yangtools.yang.data.api.SimpleNode; +import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; 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.api.DataContainerNodeAttrBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder; +import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; @@ -38,7 +47,9 @@ import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import com.google.common.base.Optional; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -46,15 +57,21 @@ import com.google.common.collect.ImmutableSet; public abstract class DataNormalizationOperation implements Identifiable { private final T identifier; + private final Optional dataSchemaNode; @Override public T getIdentifier() { return identifier; }; - protected DataNormalizationOperation(final T identifier) { + protected DataNormalizationOperation(final T identifier, final SchemaNode schema) { super(); this.identifier = identifier; + if(schema instanceof DataSchemaNode) { + this.dataSchemaNode = Optional.of((DataSchemaNode) schema); + } else { + this.dataSchemaNode = Optional.absent(); + } } public boolean isMixin() { @@ -70,16 +87,23 @@ public abstract class DataNormalizationOperation impleme return Collections.singleton(identifier.getNodeType()); } - public abstract DataNormalizationOperation getChild(final PathArgument child); + public abstract DataNormalizationOperation getChild(final PathArgument child) throws DataNormalizationException; - public abstract DataNormalizationOperation getChild(QName child); + public abstract DataNormalizationOperation getChild(QName child) throws DataNormalizationException; public abstract NormalizedNode normalize(Node legacyData); + public abstract boolean isLeaf(); + + public Optional getDataSchemaNode() { + // FIXME + return dataSchemaNode; + } + private static abstract class SimpleTypeNormalization extends DataNormalizationOperation { - protected SimpleTypeNormalization(final T identifier) { - super(identifier); + protected SimpleTypeNormalization(final T identifier, final DataSchemaNode potential) { + super(identifier,potential); } @Override @@ -103,16 +127,20 @@ public abstract class DataNormalizationOperation impleme @Override public NormalizedNode createDefault(final PathArgument currentArg) { - // TODO Auto-generated method stub return null; } + @Override + public boolean isLeaf() { + return true; + } + } private static final class LeafNormalization extends SimpleTypeNormalization { - protected LeafNormalization(final NodeIdentifier identifier) { - super(identifier); + protected LeafNormalization(final LeafSchemaNode potential) { + super(new NodeIdentifier(potential.getQName()),potential); } @Override @@ -125,7 +153,7 @@ public abstract class DataNormalizationOperation impleme private static final class LeafListEntryNormalization extends SimpleTypeNormalization { public LeafListEntryNormalization(final LeafListSchemaNode potential) { - super(new NodeWithValue(potential.getQName(), null)); + super(new NodeWithValue(potential.getQName(), null),potential); } @Override @@ -141,16 +169,16 @@ public abstract class DataNormalizationOperation impleme } } - private static abstract class CompositeNodeNormalizationOpertation extends - DataNormalizationOperation { + private static abstract class CompositeNodeNormalizationOperation extends + DataNormalizationOperation { - protected CompositeNodeNormalizationOpertation(final T identifier) { - super(identifier); + protected CompositeNodeNormalizationOperation(final T identifier, final DataSchemaNode schema) { + super(identifier,schema); } @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public final NormalizedNodeContainer normalize(final Node legacyData) { + public final NormalizedNode normalize(final Node legacyData) { checkArgument(legacyData != null); if (!isMixin() && getIdentifier().getNodeType() != null) { checkArgument(getIdentifier().getNodeType().equals(legacyData.getNodeType()), @@ -162,7 +190,13 @@ public abstract class DataNormalizationOperation impleme Set> usedMixins = new HashSet<>(); for (Node childLegacy : compositeNode.getValue()) { - DataNormalizationOperation childOp = getChild(childLegacy.getNodeType()); + final DataNormalizationOperation childOp; + + try { + childOp = getChild(childLegacy.getNodeType()); + } catch (DataNormalizationException e) { + throw new IllegalArgumentException(String.format("Failed to normalize data %s", compositeNode.getValue()), e); + } // We skip unknown nodes if this node is mixin since // it's nodes and parent nodes are interleaved @@ -175,8 +209,7 @@ public abstract class DataNormalizationOperation impleme if (childOp.isMixin()) { if (usedMixins.contains(childOp)) { // We already run / processed that mixin, so to avoid - // dupliciry we are - // skiping next nodes. + // duplicity we are skipping next nodes. continue; } builder.addChild(childOp.normalize(compositeNode)); @@ -185,7 +218,12 @@ public abstract class DataNormalizationOperation impleme builder.addChild(childOp.normalize(childLegacy)); } } - return (NormalizedNodeContainer) builder.build(); + return builder.build(); + } + + @Override + public boolean isLeaf() { + return false; } @SuppressWarnings("rawtypes") @@ -194,39 +232,51 @@ public abstract class DataNormalizationOperation impleme } private static abstract class DataContainerNormalizationOperation extends - CompositeNodeNormalizationOpertation { + CompositeNodeNormalizationOperation { private final DataNodeContainer schema; private final Map> byQName; private final Map> byArg; - protected DataContainerNormalizationOperation(final T identifier, final DataNodeContainer schema) { - super(identifier); + protected DataContainerNormalizationOperation(final T identifier, final DataNodeContainer schema, final DataSchemaNode node) { + super(identifier,node); this.schema = schema; this.byArg = new ConcurrentHashMap<>(); this.byQName = new ConcurrentHashMap<>(); } @Override - public DataNormalizationOperation getChild(final PathArgument child) { + public DataNormalizationOperation getChild(final PathArgument child) throws DataNormalizationException { DataNormalizationOperation potential = byArg.get(child); if (potential != null) { return potential; } - potential = fromSchema(schema, child); + potential = fromLocalSchema(child); return register(potential); } + private DataNormalizationOperation fromLocalSchema(final PathArgument child) throws DataNormalizationException { + if (child instanceof AugmentationIdentifier) { + return fromSchemaAndQNameChecked(schema, ((AugmentationIdentifier) child).getPossibleChildNames() + .iterator().next()); + } + return fromSchemaAndQNameChecked(schema, child.getNodeType()); + } + @Override - public DataNormalizationOperation getChild(final QName child) { + public DataNormalizationOperation getChild(final QName child) throws DataNormalizationException { DataNormalizationOperation potential = byQName.get(child); if (potential != null) { return potential; } - potential = fromSchemaAndPathArgument(schema, child); + potential = fromLocalSchemaAndQName(schema, child); return register(potential); } + protected DataNormalizationOperation fromLocalSchemaAndQName(final DataNodeContainer schema2, final QName child) throws DataNormalizationException { + return fromSchemaAndQNameChecked(schema2, child); + } + private DataNormalizationOperation register(final DataNormalizationOperation potential) { if (potential != null) { byArg.put(potential.getIdentifier(), potential); @@ -240,17 +290,17 @@ public abstract class DataNormalizationOperation impleme } private static final class ListItemNormalization extends - DataContainerNormalizationOperation { + DataContainerNormalizationOperation { private final List keyDefinition; protected ListItemNormalization(final NodeIdentifierWithPredicates identifier, final ListSchemaNode schema) { - super(identifier, schema); + super(identifier, schema,schema); keyDefinition = schema.getKeyDefinition(); } @Override - protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { ImmutableMap.Builder keys = ImmutableMap.builder(); for (QName key : keyDefinition) { @@ -283,14 +333,32 @@ public abstract class DataNormalizationOperation impleme } } + private static final class UnkeyedListItemNormalization extends DataContainerNormalizationOperation { + + protected UnkeyedListItemNormalization(final ListSchemaNode schema) { + super(new NodeIdentifier(schema.getQName()), schema,schema); + } + + @Override + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + return Builders.unkeyedListEntryBuilder().withNodeIdentifier(getIdentifier()); + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.unkeyedListEntryBuilder().withNodeIdentifier((NodeIdentifier) currentArg).build(); + } + + } + private static final class ContainerNormalization extends DataContainerNormalizationOperation { protected ContainerNormalization(final ContainerSchemaNode schema) { - super(new NodeIdentifier(schema.getQName()), schema); + super(new NodeIdentifier(schema.getQName()),schema, schema); } @Override - protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { return Builders.containerBuilder().withNodeIdentifier(getIdentifier()); } @@ -302,10 +370,10 @@ public abstract class DataNormalizationOperation impleme } private static abstract class MixinNormalizationOp extends - CompositeNodeNormalizationOpertation { + CompositeNodeNormalizationOperation { - protected MixinNormalizationOp(final T identifier) { - super(identifier); + protected MixinNormalizationOp(final T identifier, final DataSchemaNode schema) { + super(identifier,schema); } @Override @@ -315,17 +383,36 @@ public abstract class DataNormalizationOperation impleme } - private static final class LeafListMixinNormalization extends MixinNormalizationOp { + + private static final class OrderedLeafListMixinNormalization extends UnorderedLeafListMixinNormalization { + + + public OrderedLeafListMixinNormalization(final LeafListSchemaNode potential) { + super(potential); + } + + @Override + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + return Builders.orderedLeafSetBuilder().withNodeIdentifier(getIdentifier()); + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.orderedLeafSetBuilder().withNodeIdentifier(getIdentifier()).build(); + } + } + + private static class UnorderedLeafListMixinNormalization extends MixinNormalizationOp { private final DataNormalizationOperation innerOp; - public LeafListMixinNormalization(final LeafListSchemaNode potential) { - super(new NodeIdentifier(potential.getQName())); + public UnorderedLeafListMixinNormalization(final LeafListSchemaNode potential) { + super(new NodeIdentifier(potential.getQName()),potential); innerOp = new LeafListEntryNormalization(potential); } @Override - protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier()); } @@ -351,38 +438,34 @@ public abstract class DataNormalizationOperation impleme } } - private static final class AugmentationNormalization extends MixinNormalizationOp { - - private final Map> byQName; - private final Map> byArg; + private static final class AugmentationNormalization extends DataContainerNormalizationOperation { public AugmentationNormalization(final AugmentationSchema augmentation, final DataNodeContainer schema) { - super(augmentationIdentifierFrom(augmentation)); - - ImmutableMap.Builder> byQNameBuilder = ImmutableMap.builder(); - ImmutableMap.Builder> byArgBuilder = ImmutableMap.builder(); - - for (DataSchemaNode augNode : augmentation.getChildNodes()) { - DataSchemaNode resolvedNode = schema.getDataChildByName(augNode.getQName()); - DataNormalizationOperation resolvedOp = fromDataSchemaNode(resolvedNode); - byArgBuilder.put(resolvedOp.getIdentifier(), resolvedOp); - for (QName resQName : resolvedOp.getQNameIdentifiers()) { - byQNameBuilder.put(resQName, resolvedOp); - } - } - byQName = byQNameBuilder.build(); - byArg = byArgBuilder.build(); - + //super(); + super(augmentationIdentifierFrom(augmentation), augmentationProxy(augmentation,schema),null); } @Override - public DataNormalizationOperation getChild(final PathArgument child) { - return byArg.get(child); + public boolean isMixin() { + return true; } + + @Override - public DataNormalizationOperation getChild(final QName child) { - return byQName.get(child); + protected DataNormalizationOperation fromLocalSchemaAndQName(final DataNodeContainer schema, final QName child) + throws DataNormalizationException { + Optional potential = findChildSchemaNode(schema, child); + if (!potential.isPresent()) { + return null; + } + + DataSchemaNode result = potential.get(); + // We try to look up if this node was added by augmentation + if ((schema instanceof DataSchemaNode) && result.isAugmenting()) { + return fromAugmentation(schema, (AugmentationTarget) schema, result); + } + return fromDataSchemaNode(result); } @Override @@ -403,12 +486,12 @@ public abstract class DataNormalizationOperation impleme } - private static final class ListMixinNormalization extends MixinNormalizationOp { + private static class UnorderedMapMixinNormalization extends MixinNormalizationOp { private final ListItemNormalization innerNode; - public ListMixinNormalization(final ListSchemaNode list) { - super(new NodeIdentifier(list.getQName())); + public UnorderedMapMixinNormalization(final ListSchemaNode list) { + super(new NodeIdentifier(list.getQName()),list); this.innerNode = new ListItemNormalization(new NodeIdentifierWithPredicates(list.getQName(), Collections. emptyMap()), list); } @@ -442,13 +525,71 @@ public abstract class DataNormalizationOperation impleme } + + private static class UnkeyedListMixinNormalization extends MixinNormalizationOp { + + private final UnkeyedListItemNormalization innerNode; + + public UnkeyedListMixinNormalization(final ListSchemaNode list) { + super(new NodeIdentifier(list.getQName()),list); + this.innerNode = new UnkeyedListItemNormalization(list); + } + + @SuppressWarnings("rawtypes") + @Override + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + return Builders.unkeyedListBuilder().withNodeIdentifier(getIdentifier()); + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.unkeyedListBuilder().withNodeIdentifier(getIdentifier()).build(); + } + + @Override + public DataNormalizationOperation getChild(final PathArgument child) { + if (child.getNodeType().equals(getIdentifier().getNodeType())) { + return innerNode; + } + return null; + } + + @Override + public DataNormalizationOperation getChild(final QName child) { + if (getIdentifier().getNodeType().equals(child)) { + return innerNode; + } + return null; + } + + } + + private static final class OrderedMapMixinNormalization extends UnorderedMapMixinNormalization { + + public OrderedMapMixinNormalization(final ListSchemaNode list) { + super(list); + } + + @SuppressWarnings("rawtypes") + @Override + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + return Builders.orderedMapBuilder().withNodeIdentifier(getIdentifier()); + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.orderedMapBuilder().withNodeIdentifier(getIdentifier()).build(); + } + + } + private static class ChoiceNodeNormalization extends MixinNormalizationOp { private final ImmutableMap> byQName; private final ImmutableMap> byArg; protected ChoiceNodeNormalization(final org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) { - super(new NodeIdentifier(schema.getQName())); + super(new NodeIdentifier(schema.getQName()),schema); ImmutableMap.Builder> byQNameBuilder = ImmutableMap.builder(); ImmutableMap.Builder> byArgBuilder = ImmutableMap.builder(); @@ -476,7 +617,7 @@ public abstract class DataNormalizationOperation impleme } @Override - protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { return Builders.choiceBuilder().withNodeIdentifier(getIdentifier()); } @@ -486,19 +627,66 @@ public abstract class DataNormalizationOperation impleme } } - public static DataNormalizationOperation fromSchemaAndPathArgument(final DataNodeContainer schema, - final QName child) { - DataSchemaNode potential = schema.getDataChildByName(child); + private static class AnyXmlNormalization extends DataNormalizationOperation { + + protected AnyXmlNormalization( final AnyXmlSchemaNode schema) { + super( new NodeIdentifier(schema.getQName()), schema); + } + + @Override + public DataNormalizationOperation getChild( final PathArgument child ) throws DataNormalizationException { + return null; + } + + @Override + public DataNormalizationOperation getChild( final QName child ) throws DataNormalizationException { + return null; + } + + @Override + public NormalizedNode normalize( final Node legacyData ) { + NormalizedNodeAttrBuilder, AnyXmlNode> builder = + Builders.anyXmlBuilder().withNodeIdentifier( + new NodeIdentifier( legacyData.getNodeType() ) ); + builder.withValue(legacyData); + return builder.build(); + } + + @Override + public boolean isLeaf() { + return false; + } + + @Override + public NormalizedNode createDefault( final PathArgument currentArg ) { + return null; + } + } + + private static final Optional findChildSchemaNode(final DataNodeContainer parent,final QName child) { + DataSchemaNode potential = parent.getDataChildByName(child); if (potential == null) { Iterable choices = FluentIterable.from( - schema.getChildNodes()).filter(org.opendaylight.yangtools.yang.model.api.ChoiceNode.class); + parent.getChildNodes()).filter(org.opendaylight.yangtools.yang.model.api.ChoiceNode.class); potential = findChoice(choices, child); } - checkArgument(potential != null, "Supplied QName %s is not valid according to schema %s", child, schema); - if ((schema instanceof DataSchemaNode) && !((DataSchemaNode) schema).isAugmenting() && potential.isAugmenting()) { - return fromAugmentation(schema, (AugmentationTarget) schema, potential); + return Optional.fromNullable(potential); + } + + private static DataNormalizationOperation fromSchemaAndQNameChecked(final DataNodeContainer schema, + final QName child) throws DataNormalizationException { + + Optional potential = findChildSchemaNode(schema, child); + if (!potential.isPresent()) { + throw new DataNormalizationException(String.format("Supplied QName %s is not valid according to schema %s, potential children nodes: %s", child, schema,schema.getChildNodes())); + } + + DataSchemaNode result = potential.get(); + // We try to look up if this node was added by augmentation + if ((schema instanceof DataSchemaNode) && result.isAugmenting()) { + return fromAugmentation(schema, (AugmentationTarget) schema, result); } - return fromDataSchemaNode(potential); + return fromDataSchemaNode(result); } private static org.opendaylight.yangtools.yang.model.api.ChoiceNode findChoice( @@ -506,7 +694,7 @@ public abstract class DataNormalizationOperation impleme org.opendaylight.yangtools.yang.model.api.ChoiceNode foundChoice = null; choiceLoop: for (org.opendaylight.yangtools.yang.model.api.ChoiceNode choice : choices) { for (ChoiceCaseNode caze : choice.getCases()) { - if (caze.getDataChildByName(child) != null) { + if (findChildSchemaNode(caze, child).isPresent()) { foundChoice = choice; break choiceLoop; } @@ -520,50 +708,86 @@ public abstract class DataNormalizationOperation impleme for (DataSchemaNode child : augmentation.getChildNodes()) { potentialChildren.add(child.getQName()); } - return new AugmentationIdentifier(null, potentialChildren.build()); + return new AugmentationIdentifier(potentialChildren.build()); + } + + private static DataNodeContainer augmentationProxy(final AugmentationSchema augmentation, final DataNodeContainer schema) { + Set children = new HashSet<>(); + for (DataSchemaNode augNode : augmentation.getChildNodes()) { + children.add(schema.getDataChildByName(augNode.getQName())); + } + return new DataSchemaContainerProxy(children); } - private static AugmentationNormalization fromAugmentation(final DataNodeContainer schema, - final AugmentationTarget augments, final DataSchemaNode potential) { + /** + * Returns a DataNormalizationOperation for provided child node + * + * If supplied child is added by Augmentation this operation returns + * a DataNormalizationOperation for augmentation, + * otherwise returns a DataNormalizationOperation for child as + * call for {@link #fromDataSchemaNode(DataSchemaNode)}. + * + * + * @param parent + * @param parentAug + * @param child + * @return + */ + private static DataNormalizationOperation fromAugmentation(final DataNodeContainer parent, + final AugmentationTarget parentAug, final DataSchemaNode child) { AugmentationSchema augmentation = null; - for (AugmentationSchema aug : augments.getAvailableAugmentations()) { - DataSchemaNode child = aug.getDataChildByName(potential.getQName()); - if (child != null) { + for (AugmentationSchema aug : parentAug.getAvailableAugmentations()) { + DataSchemaNode potential = aug.getDataChildByName(child.getQName()); + if (potential != null) { augmentation = aug; break; } } if (augmentation != null) { - return new AugmentationNormalization(augmentation, schema); + return new AugmentationNormalization(augmentation, parent); } else { - return null; - } - } - - private static DataNormalizationOperation fromSchema(final DataNodeContainer schema, final PathArgument child) { - if (child instanceof AugmentationIdentifier) { - return fromSchemaAndPathArgument(schema, ((AugmentationIdentifier) child).getPossibleChildNames() - .iterator().next()); + return fromDataSchemaNode(child); } - return fromSchemaAndPathArgument(schema, child.getNodeType()); } public static DataNormalizationOperation fromDataSchemaNode(final DataSchemaNode potential) { if (potential instanceof ContainerSchemaNode) { return new ContainerNormalization((ContainerSchemaNode) potential); } else if (potential instanceof ListSchemaNode) { - return new ListMixinNormalization((ListSchemaNode) potential); + + return fromListSchemaNode((ListSchemaNode) potential); } else if (potential instanceof LeafSchemaNode) { - return new LeafNormalization(new NodeIdentifier(potential.getQName())); + return new LeafNormalization((LeafSchemaNode) potential); } else if (potential instanceof org.opendaylight.yangtools.yang.model.api.ChoiceNode) { return new ChoiceNodeNormalization((org.opendaylight.yangtools.yang.model.api.ChoiceNode) potential); } else if (potential instanceof LeafListSchemaNode) { - return new LeafListMixinNormalization((LeafListSchemaNode) potential); + return fromLeafListSchemaNode((LeafListSchemaNode) potential); + } else if (potential instanceof AnyXmlSchemaNode) { + return new AnyXmlNormalization( (AnyXmlSchemaNode) potential); } return null; } + private static DataNormalizationOperation fromListSchemaNode(final ListSchemaNode potential) { + List keyDefinition = potential.getKeyDefinition(); + if(keyDefinition == null || keyDefinition.isEmpty()) { + return new UnkeyedListMixinNormalization(potential); + } + if(potential.isUserOrdered()) { + return new OrderedMapMixinNormalization(potential); + } + return new UnorderedMapMixinNormalization(potential); + } + + private static DataNormalizationOperation fromLeafListSchemaNode(final LeafListSchemaNode potential) { + if(potential.isUserOrdered()) { + return new OrderedLeafListMixinNormalization(potential); + } + return new UnorderedLeafListMixinNormalization(potential); + } + + public static DataNormalizationOperation from(final SchemaContext ctx) { return new ContainerNormalization(ctx); }