e19b625ef2f266bb2559fb2914ee76b8756559d0
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / transform / base / serializer / NodeSerializerDispatcher.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 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
11 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
12 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
13 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
14 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
15 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
16 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
17 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
18 import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
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.ContainerSchemaNode;
22 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
25
26 import com.google.common.base.Preconditions;
27 import com.google.common.collect.Iterables;
28
29 /**
30  *
31  * Dispatches the serialization process of nodes according to schema and returns the serialized elements.
32  *
33  * @param <E> type of serialized elements
34  */
35 public interface NodeSerializerDispatcher<E> {
36
37     Iterable<E> dispatchChildElement(Object childSchema,
38             DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild);
39
40     /**
41      * Abstract implementation that implements the dispatch conditions. Only requires serializers to be provided.
42      * The same instance of serializer can be provided in case it is immutable.
43      */
44     public static abstract class BaseNodeSerializerDispatcher<E> implements NodeSerializerDispatcher<E> {
45
46         @Override
47         public final Iterable<E> dispatchChildElement(Object childSchema,
48                 DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild) {
49             if (dataContainerChild instanceof ContainerNode) {
50                 return onContainerNode(childSchema, dataContainerChild);
51             } else if (dataContainerChild instanceof LeafNode<?>) {
52                 return onLeafNode(childSchema, dataContainerChild);
53             } else if (dataContainerChild instanceof MixinNode) {
54                 if (dataContainerChild instanceof LeafSetNode<?>) {
55                     return onLeafListNode(childSchema, dataContainerChild);
56                 } else if (dataContainerChild instanceof MapNode) {
57                     return onListNode(childSchema, dataContainerChild);
58                 } else if (dataContainerChild instanceof ChoiceNode) {
59                     return onChoiceNode(childSchema, dataContainerChild);
60                 } else if (dataContainerChild instanceof AugmentationNode) {
61                     return onAugmentationSchema(childSchema, dataContainerChild);
62                 }
63             }
64             throw new IllegalArgumentException("Unable to serialize " + childSchema);
65         }
66
67         private Iterable<E> onAugmentationSchema(Object childSchema,
68                 DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild) {
69             checkSchemaCompatibility(childSchema, AugmentationSchema.class, dataContainerChild);
70             return getAugmentationNodeSerializer().serialize((AugmentationSchema) childSchema,
71                     (AugmentationNode) dataContainerChild);
72         }
73
74         private Iterable<E> onChoiceNode(Object childSchema,
75                 DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild) {
76             checkSchemaCompatibility(childSchema, org.opendaylight.yangtools.yang.model.api.ChoiceNode.class,
77                     dataContainerChild);
78             return getChoiceNodeSerializer()
79                     .serialize((org.opendaylight.yangtools.yang.model.api.ChoiceNode) childSchema,
80                             (ChoiceNode) dataContainerChild);
81         }
82
83         private Iterable<E> onListNode(Object childSchema,
84                 DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild) {
85             checkSchemaCompatibility(childSchema, ListSchemaNode.class, dataContainerChild);
86             return getMapNodeSerializer().serialize((ListSchemaNode) childSchema, (MapNode) dataContainerChild);
87         }
88
89         private Iterable<E> onLeafListNode(Object childSchema,
90                 DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild) {
91             checkSchemaCompatibility(childSchema, LeafListSchemaNode.class, dataContainerChild);
92             return getLeafSetNodeSerializer().serialize((LeafListSchemaNode) childSchema,
93                     (LeafSetNode<?>) dataContainerChild);
94         }
95
96         private Iterable<E> onLeafNode(Object childSchema,
97                 DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild) {
98             checkSchemaCompatibility(childSchema, LeafSchemaNode.class, dataContainerChild);
99             Iterable<E> elements = getLeafNodeSerializer().serialize((LeafSchemaNode) childSchema,
100                     (LeafNode<?>) dataContainerChild);
101             checkOnlyOneSerializedElement(elements, dataContainerChild);
102             return elements;
103         }
104
105         private static void checkOnlyOneSerializedElement(Iterable<?> elements,
106                 DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild) {
107             final int size = Iterables.size(elements);
108             Preconditions.checkArgument(size == 1,
109                     "Unexpected count of elements for entry serialized from: %s, should be 1, was: %s",
110                     dataContainerChild, size);
111         }
112
113         private Iterable<E> onContainerNode(Object childSchema,
114                 DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild) {
115             checkSchemaCompatibility(childSchema, ContainerSchemaNode.class, dataContainerChild);
116
117             Iterable<E> elements = getContainerNodeSerializer().serialize((ContainerSchemaNode) childSchema,
118                     (ContainerNode) dataContainerChild);
119             checkOnlyOneSerializedElement(elements, dataContainerChild);
120             return elements;
121         }
122
123         private static void checkSchemaCompatibility(Object childSchema, Class<?> containerSchemaNodeClass,
124                 DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild) {
125             Preconditions.checkArgument(containerSchemaNodeClass.isAssignableFrom(childSchema.getClass()),
126                     "Incompatible schema: %s with node: %s, expected: %s", childSchema, dataContainerChild,
127                     containerSchemaNodeClass);
128         }
129
130         protected abstract FromNormalizedNodeSerializer<E, ContainerNode, ContainerSchemaNode> getContainerNodeSerializer();
131
132         protected abstract FromNormalizedNodeSerializer<E, LeafNode<?>, LeafSchemaNode> getLeafNodeSerializer();
133
134         protected abstract FromNormalizedNodeSerializer<E, LeafSetNode<?>, LeafListSchemaNode> getLeafSetNodeSerializer();
135
136         protected abstract FromNormalizedNodeSerializer<E, MapNode, ListSchemaNode> getMapNodeSerializer();
137
138         protected abstract FromNormalizedNodeSerializer<E, org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode, org.opendaylight.yangtools.yang.model.api.ChoiceNode> getChoiceNodeSerializer();
139
140         protected abstract FromNormalizedNodeSerializer<E, AugmentationNode, AugmentationSchema> getAugmentationNodeSerializer();
141     }
142 }