2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.md.sal.common.impl.util.compat;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static com.google.common.base.Preconditions.checkNotNull;
13 import java.util.Collections;
14 import java.util.HashSet;
15 import java.util.List;
17 import java.util.Map.Entry;
19 import java.util.concurrent.ConcurrentHashMap;
21 import javax.xml.transform.dom.DOMSource;
22 import org.opendaylight.yangtools.concepts.Identifiable;
23 import org.opendaylight.yangtools.yang.common.QName;
24 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
30 import org.opendaylight.yangtools.yang.data.api.Node;
31 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
35 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
36 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
37 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
38 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
39 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
40 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
41 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
42 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
43 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
44 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
45 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
46 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
47 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
48 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
49 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
50 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
51 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
52 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
54 import com.google.common.base.Optional;
55 import com.google.common.collect.FluentIterable;
56 import com.google.common.collect.ImmutableMap;
57 import com.google.common.collect.ImmutableSet;
60 * @deprecated This class provides compatibility between {@link CompositeNode} and {@link NormalizedNode}.
61 * Users of this class should use {@link NormalizedNode}s directly.
64 public abstract class DataNormalizationOperation<T extends PathArgument> implements Identifiable<T> {
66 private final T identifier;
67 private final Optional<DataSchemaNode> dataSchemaNode;
70 public T getIdentifier() {
74 protected DataNormalizationOperation(final T identifier, final SchemaNode schema) {
76 this.identifier = identifier;
77 if(schema instanceof DataSchemaNode) {
78 this.dataSchemaNode = Optional.of((DataSchemaNode) schema);
80 this.dataSchemaNode = Optional.absent();
84 public boolean isMixin() {
89 public boolean isKeyedEntry() {
93 protected Set<QName> getQNameIdentifiers() {
94 return Collections.singleton(identifier.getNodeType());
97 public abstract DataNormalizationOperation<?> getChild(final PathArgument child) throws DataNormalizationException;
99 public abstract DataNormalizationOperation<?> getChild(QName child) throws DataNormalizationException;
101 public abstract NormalizedNode<?, ?> normalize(Node<?> legacyData);
103 public abstract boolean isLeaf();
105 public Optional<DataSchemaNode> getDataSchemaNode() {
107 return dataSchemaNode;
110 private static abstract class SimpleTypeNormalization<T extends PathArgument> extends DataNormalizationOperation<T> {
112 protected SimpleTypeNormalization(final T identifier, final DataSchemaNode potential) {
113 super(identifier,potential);
117 public NormalizedNode<?, ?> normalize(final Node<?> legacyData) {
118 checkArgument(legacyData != null);
119 checkArgument(legacyData instanceof SimpleNode<?>);
120 return normalizeImpl((SimpleNode<?>) legacyData);
123 protected abstract NormalizedNode<?, ?> normalizeImpl(SimpleNode<?> node);
126 public DataNormalizationOperation<?> getChild(final PathArgument child) {
131 public DataNormalizationOperation<?> getChild(final QName child) {
136 public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
141 public boolean isLeaf() {
147 private static final class LeafNormalization extends SimpleTypeNormalization<NodeIdentifier> {
149 protected LeafNormalization(final LeafSchemaNode potential) {
150 super(new NodeIdentifier(potential.getQName()),potential);
154 protected NormalizedNode<?, ?> normalizeImpl(final SimpleNode<?> node) {
155 return ImmutableNodes.leafNode(node.getNodeType(), node.getValue());
160 private static final class LeafListEntryNormalization extends SimpleTypeNormalization<NodeWithValue> {
162 public LeafListEntryNormalization(final LeafListSchemaNode potential) {
163 super(new NodeWithValue(potential.getQName(), null),potential);
167 protected NormalizedNode<?, ?> normalizeImpl(final SimpleNode<?> node) {
168 NodeWithValue nodeId = new NodeWithValue(node.getNodeType(), node.getValue());
169 return Builders.leafSetEntryBuilder().withNodeIdentifier(nodeId).withValue(node.getValue()).build();
174 public boolean isKeyedEntry() {
179 private static abstract class CompositeNodeNormalizationOperation<T extends PathArgument> extends
180 DataNormalizationOperation<T> {
182 protected CompositeNodeNormalizationOperation(final T identifier, final DataSchemaNode schema) {
183 super(identifier,schema);
186 @SuppressWarnings({ "rawtypes", "unchecked" })
188 public final NormalizedNode<?, ?> normalize(final Node<?> legacyData) {
189 checkArgument(legacyData != null);
190 if (!isMixin() && getIdentifier().getNodeType() != null) {
191 checkArgument(getIdentifier().getNodeType().equals(legacyData.getNodeType()),
192 "Node QName must be %s was %s", getIdentifier().getNodeType(), legacyData.getNodeType());
194 checkArgument(legacyData instanceof CompositeNode, "Node %s should be composite", legacyData);
195 CompositeNode compositeNode = (CompositeNode) legacyData;
196 NormalizedNodeContainerBuilder builder = createBuilder(compositeNode);
198 Set<DataNormalizationOperation<?>> usedMixins = new HashSet<>();
199 for (Node<?> childLegacy : compositeNode.getValue()) {
200 final DataNormalizationOperation childOp;
203 childOp = getChild(childLegacy.getNodeType());
204 } catch (DataNormalizationException e) {
205 throw new IllegalArgumentException(String.format("Failed to normalize data %s", compositeNode.getValue()), e);
208 // We skip unknown nodes if this node is mixin since
209 // it's nodes and parent nodes are interleaved
210 if (childOp == null && isMixin()) {
214 checkArgument(childOp != null, "Node %s is not allowed inside %s", childLegacy.getNodeType(),
216 if (childOp.isMixin()) {
217 if (usedMixins.contains(childOp)) {
218 // We already run / processed that mixin, so to avoid
219 // duplicity we are skipping next nodes.
222 builder.addChild(childOp.normalize(compositeNode));
223 usedMixins.add(childOp);
225 builder.addChild(childOp.normalize(childLegacy));
228 return builder.build();
232 public boolean isLeaf() {
236 @SuppressWarnings("rawtypes")
237 protected abstract NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode);
241 private static abstract class DataContainerNormalizationOperation<T extends PathArgument> extends
242 CompositeNodeNormalizationOperation<T> {
244 private final DataNodeContainer schema;
245 private final Map<QName, DataNormalizationOperation<?>> byQName;
246 private final Map<PathArgument, DataNormalizationOperation<?>> byArg;
248 protected DataContainerNormalizationOperation(final T identifier, final DataNodeContainer schema, final DataSchemaNode node) {
249 super(identifier,node);
250 this.schema = schema;
251 this.byArg = new ConcurrentHashMap<>();
252 this.byQName = new ConcurrentHashMap<>();
256 public DataNormalizationOperation<?> getChild(final PathArgument child) throws DataNormalizationException {
257 DataNormalizationOperation<?> potential = byArg.get(child);
258 if (potential != null) {
261 potential = fromLocalSchema(child);
262 return register(potential);
265 private DataNormalizationOperation<?> fromLocalSchema(final PathArgument child) throws DataNormalizationException {
266 if (child instanceof AugmentationIdentifier) {
267 return fromSchemaAndQNameChecked(schema, ((AugmentationIdentifier) child).getPossibleChildNames()
270 return fromSchemaAndQNameChecked(schema, child.getNodeType());
274 public DataNormalizationOperation<?> getChild(final QName child) throws DataNormalizationException {
275 DataNormalizationOperation<?> potential = byQName.get(child);
276 if (potential != null) {
279 potential = fromLocalSchemaAndQName(schema, child);
280 return register(potential);
283 protected DataNormalizationOperation<?> fromLocalSchemaAndQName(final DataNodeContainer schema2, final QName child) throws DataNormalizationException {
284 return fromSchemaAndQNameChecked(schema2, child);
287 private DataNormalizationOperation<?> register(final DataNormalizationOperation<?> potential) {
288 if (potential != null) {
289 byArg.put(potential.getIdentifier(), potential);
290 for (QName qName : potential.getQNameIdentifiers()) {
291 byQName.put(qName, potential);
299 private static final class ListItemNormalization extends
300 DataContainerNormalizationOperation<NodeIdentifierWithPredicates> {
302 private final List<QName> keyDefinition;
304 protected ListItemNormalization(final NodeIdentifierWithPredicates identifier, final ListSchemaNode schema) {
305 super(identifier, schema,schema);
306 keyDefinition = schema.getKeyDefinition();
310 protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
311 ImmutableMap.Builder<QName, Object> keys = ImmutableMap.builder();
312 for (QName key : keyDefinition) {
314 SimpleNode<?> valueNode = checkNotNull(compositeNode.getFirstSimpleByName(key),
315 "List node %s MUST contain leaf %s with value.", getIdentifier().getNodeType(), key);
316 keys.put(key, valueNode.getValue());
319 return Builders.mapEntryBuilder().withNodeIdentifier(
320 new NodeIdentifierWithPredicates(getIdentifier().getNodeType(), keys.build()));
324 public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
325 DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder = Builders
326 .mapEntryBuilder().withNodeIdentifier((NodeIdentifierWithPredicates) currentArg);
327 for (Entry<QName, Object> keyValue : ((NodeIdentifierWithPredicates) currentArg).getKeyValues().entrySet()) {
328 builder.addChild(Builders.leafBuilder()
330 .withNodeIdentifier(new NodeIdentifier(keyValue.getKey())).withValue(keyValue.getValue())
333 return builder.build();
338 public boolean isKeyedEntry() {
343 private static final class UnkeyedListItemNormalization extends DataContainerNormalizationOperation<NodeIdentifier> {
345 protected UnkeyedListItemNormalization(final ListSchemaNode schema) {
346 super(new NodeIdentifier(schema.getQName()), schema,schema);
350 protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
351 return Builders.unkeyedListEntryBuilder().withNodeIdentifier(getIdentifier());
355 public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
356 return Builders.unkeyedListEntryBuilder().withNodeIdentifier((NodeIdentifier) currentArg).build();
361 private static final class ContainerNormalization extends DataContainerNormalizationOperation<NodeIdentifier> {
363 protected ContainerNormalization(final ContainerSchemaNode schema) {
364 super(new NodeIdentifier(schema.getQName()),schema, schema);
368 protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
369 return Builders.containerBuilder().withNodeIdentifier(getIdentifier());
373 public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
374 return Builders.containerBuilder().withNodeIdentifier((NodeIdentifier) currentArg).build();
379 private static abstract class MixinNormalizationOp<T extends PathArgument> extends
380 CompositeNodeNormalizationOperation<T> {
382 protected MixinNormalizationOp(final T identifier, final DataSchemaNode schema) {
383 super(identifier,schema);
387 public final boolean isMixin() {
394 private static final class OrderedLeafListMixinNormalization extends UnorderedLeafListMixinNormalization {
397 public OrderedLeafListMixinNormalization(final LeafListSchemaNode potential) {
402 protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
403 return Builders.orderedLeafSetBuilder().withNodeIdentifier(getIdentifier());
407 public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
408 return Builders.orderedLeafSetBuilder().withNodeIdentifier(getIdentifier()).build();
412 private static class UnorderedLeafListMixinNormalization extends MixinNormalizationOp<NodeIdentifier> {
414 private final DataNormalizationOperation<?> innerOp;
416 public UnorderedLeafListMixinNormalization(final LeafListSchemaNode potential) {
417 super(new NodeIdentifier(potential.getQName()),potential);
418 innerOp = new LeafListEntryNormalization(potential);
422 protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
423 return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier());
427 public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
428 return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier()).build();
432 public DataNormalizationOperation<?> getChild(final PathArgument child) {
433 if (child instanceof NodeWithValue) {
440 public DataNormalizationOperation<?> getChild(final QName child) {
441 if (getIdentifier().getNodeType().equals(child)) {
448 private static final class AugmentationNormalization extends DataContainerNormalizationOperation<AugmentationIdentifier> {
450 public AugmentationNormalization(final AugmentationSchema augmentation, final DataNodeContainer schema) {
452 super(augmentationIdentifierFrom(augmentation), augmentationProxy(augmentation,schema),null);
456 public boolean isMixin() {
463 protected DataNormalizationOperation<?> fromLocalSchemaAndQName(final DataNodeContainer schema, final QName child)
464 throws DataNormalizationException {
465 Optional<DataSchemaNode> potential = findChildSchemaNode(schema, child);
466 if (!potential.isPresent()) {
470 DataSchemaNode result = potential.get();
471 // We try to look up if this node was added by augmentation
472 if ((schema instanceof DataSchemaNode) && result.isAugmenting()) {
473 return fromAugmentation(schema, (AugmentationTarget) schema, result);
475 return fromDataSchemaNode(result);
479 protected Set<QName> getQNameIdentifiers() {
480 return getIdentifier().getPossibleChildNames();
483 @SuppressWarnings("rawtypes")
485 protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) {
486 return Builders.augmentationBuilder().withNodeIdentifier(getIdentifier());
490 public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
491 return Builders.augmentationBuilder().withNodeIdentifier(getIdentifier()).build();
496 private static class UnorderedMapMixinNormalization extends MixinNormalizationOp<NodeIdentifier> {
498 private final ListItemNormalization innerNode;
500 public UnorderedMapMixinNormalization(final ListSchemaNode list) {
501 super(new NodeIdentifier(list.getQName()),list);
502 this.innerNode = new ListItemNormalization(new NodeIdentifierWithPredicates(list.getQName(),
503 Collections.<QName, Object> emptyMap()), list);
506 @SuppressWarnings("rawtypes")
508 protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) {
509 return Builders.mapBuilder().withNodeIdentifier(getIdentifier());
513 public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
514 return Builders.mapBuilder().withNodeIdentifier(getIdentifier()).build();
518 public DataNormalizationOperation<?> getChild(final PathArgument child) {
519 if (child.getNodeType().equals(getIdentifier().getNodeType())) {
526 public DataNormalizationOperation<?> getChild(final QName child) {
527 if (getIdentifier().getNodeType().equals(child)) {
536 private static class UnkeyedListMixinNormalization extends MixinNormalizationOp<NodeIdentifier> {
538 private final UnkeyedListItemNormalization innerNode;
540 public UnkeyedListMixinNormalization(final ListSchemaNode list) {
541 super(new NodeIdentifier(list.getQName()),list);
542 this.innerNode = new UnkeyedListItemNormalization(list);
545 @SuppressWarnings("rawtypes")
547 protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) {
548 return Builders.unkeyedListBuilder().withNodeIdentifier(getIdentifier());
552 public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
553 return Builders.unkeyedListBuilder().withNodeIdentifier(getIdentifier()).build();
557 public DataNormalizationOperation<?> getChild(final PathArgument child) {
558 if (child.getNodeType().equals(getIdentifier().getNodeType())) {
565 public DataNormalizationOperation<?> getChild(final QName child) {
566 if (getIdentifier().getNodeType().equals(child)) {
574 private static final class OrderedMapMixinNormalization extends UnorderedMapMixinNormalization {
576 public OrderedMapMixinNormalization(final ListSchemaNode list) {
580 @SuppressWarnings("rawtypes")
582 protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) {
583 return Builders.orderedMapBuilder().withNodeIdentifier(getIdentifier());
587 public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
588 return Builders.orderedMapBuilder().withNodeIdentifier(getIdentifier()).build();
593 private static class ChoiceNodeNormalization extends MixinNormalizationOp<NodeIdentifier> {
595 private final ImmutableMap<QName, DataNormalizationOperation<?>> byQName;
596 private final ImmutableMap<PathArgument, DataNormalizationOperation<?>> byArg;
598 protected ChoiceNodeNormalization(final ChoiceSchemaNode schema) {
599 super(new NodeIdentifier(schema.getQName()),schema);
600 ImmutableMap.Builder<QName, DataNormalizationOperation<?>> byQNameBuilder = ImmutableMap.builder();
601 ImmutableMap.Builder<PathArgument, DataNormalizationOperation<?>> byArgBuilder = ImmutableMap.builder();
603 for (ChoiceCaseNode caze : schema.getCases()) {
604 for (DataSchemaNode cazeChild : caze.getChildNodes()) {
605 DataNormalizationOperation<?> childOp = fromDataSchemaNode(cazeChild);
606 byArgBuilder.put(childOp.getIdentifier(), childOp);
607 for (QName qname : childOp.getQNameIdentifiers()) {
608 byQNameBuilder.put(qname, childOp);
612 byQName = byQNameBuilder.build();
613 byArg = byArgBuilder.build();
617 public DataNormalizationOperation<?> getChild(final PathArgument child) {
618 return byArg.get(child);
622 public DataNormalizationOperation<?> getChild(final QName child) {
623 return byQName.get(child);
627 protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
628 return Builders.choiceBuilder().withNodeIdentifier(getIdentifier());
632 public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
633 return Builders.choiceBuilder().withNodeIdentifier(getIdentifier()).build();
637 private static class AnyXmlNormalization extends DataNormalizationOperation<NodeIdentifier> {
639 protected AnyXmlNormalization( final AnyXmlSchemaNode schema) {
640 super( new NodeIdentifier(schema.getQName()), schema);
644 public DataNormalizationOperation<?> getChild( final PathArgument child ) throws DataNormalizationException {
649 public DataNormalizationOperation<?> getChild( final QName child ) throws DataNormalizationException {
654 public NormalizedNode<?, ?> normalize( final Node<?> legacyData ) {
655 NormalizedNodeAttrBuilder<NodeIdentifier, DOMSource, AnyXmlNode> builder =
656 Builders.anyXmlBuilder().withNodeIdentifier(
657 new NodeIdentifier( legacyData.getNodeType() ) );
659 // builder.withValue(legacyData);
660 return builder.build();
664 public boolean isLeaf() {
669 public NormalizedNode<?, ?> createDefault( final PathArgument currentArg ) {
674 private static final Optional<DataSchemaNode> findChildSchemaNode(final DataNodeContainer parent,final QName child) {
675 DataSchemaNode potential = parent.getDataChildByName(child);
676 if (potential == null) {
677 Iterable<ChoiceSchemaNode> choices = FluentIterable.from(parent.getChildNodes()).filter(ChoiceSchemaNode.class);
678 potential = findChoice(choices, child);
680 return Optional.fromNullable(potential);
683 private static DataNormalizationOperation<?> fromSchemaAndQNameChecked(final DataNodeContainer schema,
684 final QName child) throws DataNormalizationException {
686 Optional<DataSchemaNode> potential = findChildSchemaNode(schema, child);
687 if (!potential.isPresent()) {
688 throw new DataNormalizationException(String.format("Supplied QName %s is not valid according to schema %s, potential children nodes: %s", child, schema,schema.getChildNodes()));
691 DataSchemaNode result = potential.get();
692 // We try to look up if this node was added by augmentation
693 if ((schema instanceof DataSchemaNode) && result.isAugmenting()) {
694 return fromAugmentation(schema, (AugmentationTarget) schema, result);
696 return fromDataSchemaNode(result);
699 private static ChoiceSchemaNode findChoice(final Iterable<ChoiceSchemaNode> choices, final QName child) {
700 ChoiceSchemaNode foundChoice = null;
701 choiceLoop: for (ChoiceSchemaNode choice : choices) {
702 for (ChoiceCaseNode caze : choice.getCases()) {
703 if (findChildSchemaNode(caze, child).isPresent()) {
704 foundChoice = choice;
712 public static AugmentationIdentifier augmentationIdentifierFrom(final AugmentationSchema augmentation) {
713 ImmutableSet.Builder<QName> potentialChildren = ImmutableSet.builder();
714 for (DataSchemaNode child : augmentation.getChildNodes()) {
715 potentialChildren.add(child.getQName());
717 return new AugmentationIdentifier(potentialChildren.build());
720 private static DataNodeContainer augmentationProxy(final AugmentationSchema augmentation, final DataNodeContainer schema) {
721 Set<DataSchemaNode> children = new HashSet<>();
722 for (DataSchemaNode augNode : augmentation.getChildNodes()) {
723 children.add(schema.getDataChildByName(augNode.getQName()));
725 return new DataSchemaContainerProxy(children);
729 * Returns a DataNormalizationOperation for provided child node
731 * If supplied child is added by Augmentation this operation returns
732 * a DataNormalizationOperation for augmentation,
733 * otherwise returns a DataNormalizationOperation for child as
734 * call for {@link #fromDataSchemaNode(DataSchemaNode)}.
742 private static DataNormalizationOperation<?> fromAugmentation(final DataNodeContainer parent,
743 final AugmentationTarget parentAug, final DataSchemaNode child) {
744 AugmentationSchema augmentation = null;
745 for (AugmentationSchema aug : parentAug.getAvailableAugmentations()) {
746 DataSchemaNode potential = aug.getDataChildByName(child.getQName());
747 if (potential != null) {
753 if (augmentation != null) {
754 return new AugmentationNormalization(augmentation, parent);
756 return fromDataSchemaNode(child);
760 public static DataNormalizationOperation<?> fromDataSchemaNode(final DataSchemaNode potential) {
761 if (potential instanceof ContainerSchemaNode) {
762 return new ContainerNormalization((ContainerSchemaNode) potential);
763 } else if (potential instanceof ListSchemaNode) {
765 return fromListSchemaNode((ListSchemaNode) potential);
766 } else if (potential instanceof LeafSchemaNode) {
767 return new LeafNormalization((LeafSchemaNode) potential);
768 } else if (potential instanceof ChoiceSchemaNode) {
769 return new ChoiceNodeNormalization((ChoiceSchemaNode) potential);
770 } else if (potential instanceof LeafListSchemaNode) {
771 return fromLeafListSchemaNode((LeafListSchemaNode) potential);
772 } else if (potential instanceof AnyXmlSchemaNode) {
773 return new AnyXmlNormalization( (AnyXmlSchemaNode) potential);
778 private static DataNormalizationOperation<?> fromListSchemaNode(final ListSchemaNode potential) {
779 List<QName> keyDefinition = potential.getKeyDefinition();
780 if(keyDefinition == null || keyDefinition.isEmpty()) {
781 return new UnkeyedListMixinNormalization(potential);
783 if(potential.isUserOrdered()) {
784 return new OrderedMapMixinNormalization(potential);
786 return new UnorderedMapMixinNormalization(potential);
789 private static DataNormalizationOperation<?> fromLeafListSchemaNode(final LeafListSchemaNode potential) {
790 if(potential.isUserOrdered()) {
791 return new OrderedLeafListMixinNormalization(potential);
793 return new UnorderedLeafListMixinNormalization(potential);
797 public static DataNormalizationOperation<?> from(final SchemaContext ctx) {
798 return new ContainerNormalization(ctx);
801 public abstract NormalizedNode<?, ?> createDefault(PathArgument currentArg);