Bug 2766: Fixed parsing and serializing XPath Instance Identifiers
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / transform / base / serializer / BaseDispatcherSerializer.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.Iterables;
12 import com.google.common.collect.Lists;
13 import java.util.List;
14 import java.util.Set;
15 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
16 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
17 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
18 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
19 import org.opendaylight.yangtools.yang.data.impl.schema.transform.FromNormalizedNodeSerializer;
20 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
21 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
22 import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
23
24 /**
25  * Abstract(base) Serializer for DataContainerNodes e.g. ContainerNode, AugmentationNode.
26  */
27 public abstract class BaseDispatcherSerializer<E, N extends DataContainerNode<?>, S> implements
28         FromNormalizedNodeSerializer<E, N, S> {
29
30     /**
31      *
32      * @param schema
33      * @param augmentationSchema
34      * @return Set of real schema objects that represent child nodes of an
35      *         augmentation. Augmentation schema child nodes, if further
36      *         augmented, do not contain further augmented, that are crucial for
37      *         parsing. The real schema object can be retrieved from parent schema: schema.
38      */
39     protected abstract Set<DataSchemaNode> getRealSchemasForAugment(S schema, AugmentationSchema augmentationSchema);
40
41     /**
42      *
43      * @param schema
44      * @param childNode
45      * @return Schema object associated with child node identified as: childNode.
46      *         Schema should be retrieved from parent schema: schema.
47      */
48     protected abstract DataSchemaNode getSchemaForChild(S schema,
49             DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> childNode);
50
51     /**
52      *
53      * @param schema
54      * @param augmentationNode
55      * @return Schema object associated with augmentation child node identified as: augmentationNode.
56      *         Schema should be retrieved from parent schema: schema.
57      */
58     protected abstract AugmentationSchema getAugmentedCase(S schema, AugmentationNode augmentationNode);
59
60     /**
61      *
62      * @return Dispatcher object to dispatch serialization of child elements, might be
63      *         the same instance if provided serializers are immutable.
64      */
65     protected abstract NodeSerializerDispatcher<E> getNodeDispatcher();
66
67     @Override
68     public Iterable<E> serialize(S schema, N node) {
69         List<Iterable<E>> choiceChildren = Lists.newArrayList();
70
71         for (DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> choiceChild : node.getValue()) {
72
73             Object childSchema;
74
75             if (choiceChild instanceof AugmentationNode) {
76
77                 AugmentationSchema augSchema = getAugmentedCase(schema, (AugmentationNode) choiceChild);
78                 Set<DataSchemaNode> realChildSchemas = getRealSchemasForAugment(schema, augSchema);
79                 childSchema = new EffectiveAugmentationSchema(augSchema, realChildSchemas);
80
81             } else {
82                 childSchema = getSchemaForChild(schema, choiceChild);
83             }
84
85             Iterable<E> childElements = getNodeDispatcher().dispatchChildElement(childSchema, choiceChild);
86             choiceChildren.add(Preconditions.checkNotNull(childElements));
87         }
88
89         return Iterables.concat(choiceChildren);
90     }
91 }