Bump to Silicon
[transportpce.git] / test-common / src / main / java / org / opendaylight / transportpce / test / converter / AbstractDataObjectConverter.java
1 /*
2  * Copyright © 2016 AT&T 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.transportpce.test.converter;
9
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Map.Entry;
14 import java.util.Optional;
15 import javax.annotation.Nonnull;
16 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
17 import org.opendaylight.yangtools.yang.binding.DataContainer;
18 import org.opendaylight.yangtools.yang.binding.DataObject;
19 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
20 import org.opendaylight.yangtools.yang.binding.Notification;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
23 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
26 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
27 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
28 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /**
33  * Converts XML and {@link DataObject} vice versa.
34  *
35  */
36 public abstract class AbstractDataObjectConverter implements DataObjectConverter {
37
38     private static final Logger LOG = LoggerFactory.getLogger(AbstractDataObjectConverter.class);
39
40     private final EffectiveModelContext schemaContext;
41     private final BindingNormalizedNodeSerializer codecRegistry;
42
43     /**
44      * This is the default constructor, which should be used.
45      *
46      * @param schemaContext schema context for converter
47      * @param codecRegistry codec registry used for converting
48      *
49      */
50     protected AbstractDataObjectConverter(EffectiveModelContext schemaContext,
51             BindingNormalizedNodeSerializer codecRegistry) {
52         this.schemaContext = schemaContext;
53         this.codecRegistry = codecRegistry;
54     }
55
56     public EffectiveModelContext getSchemaContext() {
57         return schemaContext;
58     }
59
60     public BindingNormalizedNodeSerializer getCodecRegistry() {
61         return codecRegistry;
62     }
63
64     /**
65      * Transforms the given input {@link NormalizedNode} into the given
66      * {@link DataObject}.
67      *
68      * @param normalizedNode normalized node you want to convert
69      * @param rootNode {@link QName} of converted normalized node root
70      *
71      * <p>
72      * The input object should be {@link ContainerNode}
73      * </p>
74      */
75     @Override
76     @SuppressWarnings("unchecked")
77     public <T extends DataObject> Optional<T> getDataObject(
78             @Nonnull NormalizedNode<?, ?> normalizedNode,
79             @Nonnull QName rootNode) {
80         //Preconditions.checkNotNull(normalizedNode);
81         if (normalizedNode instanceof ContainerNode) {
82             YangInstanceIdentifier.PathArgument directChildIdentifier =
83                     YangInstanceIdentifier.of(rootNode).getLastPathArgument();
84             Optional<NormalizedNode<?, ?>> directChild =
85                     NormalizedNodes.getDirectChild(normalizedNode, directChildIdentifier);
86             if (!directChild.isPresent()) {
87                 throw new IllegalStateException(String.format("Could not get the direct child of %s", rootNode));
88             }
89             normalizedNode = directChild.get();
90         }
91         YangInstanceIdentifier rootNodeYangInstanceIdentifier = YangInstanceIdentifier.of(rootNode);
92
93         Map.Entry<?, ?> bindingNodeEntry =
94                 codecRegistry.fromNormalizedNode(rootNodeYangInstanceIdentifier, normalizedNode);
95         if (bindingNodeEntry == null) {
96             return Optional.empty();
97         }
98         return Optional.ofNullable((T) bindingNodeEntry.getValue());
99     }
100
101     @Override
102     @SuppressWarnings("unchecked")
103     public <T extends DataObject> Optional<T> getDataObjectFromRpc(
104             @Nonnull NormalizedNode<?, ?> normalizedNode,
105             @Nonnull SchemaPath rpcSchemaPath) {
106
107         if (! (normalizedNode instanceof ContainerNode)) {
108             LOG.error("converting normalized node is not ContainerNode. It's actual type is {}",
109                     normalizedNode.getClass().getSimpleName());
110             return Optional.empty();
111         }
112         List<QName> qnameList = new ArrayList<>();
113         rpcSchemaPath.getPathFromRoot().forEach(qnameList::add);
114         T rpcDataObject = (T) codecRegistry
115                 .fromNormalizedNodeRpcData(Absolute.of(qnameList), (ContainerNode) normalizedNode);
116         return Optional.ofNullable(rpcDataObject);
117     }
118
119     @Override
120     public <T extends DataObject> Optional<NormalizedNode<?, ?>> toNormalizedNodes(@Nonnull T object,
121             Class<T> dataObjectClass) {
122         Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
123                 codecRegistry.toNormalizedNode(InstanceIdentifier.create(dataObjectClass), object);
124         return Optional.ofNullable(normalizedNode.getValue());
125     }
126
127     @Override
128     public <T extends DataObject> ConvertType<T> dataContainer() {
129         return (object, objectClass) -> {
130             NormalizedNode<?, ?> value =
131                     getCodecRegistry().toNormalizedNode(InstanceIdentifier.create(objectClass), object).getValue();
132             return Optional.ofNullable(value);
133         };
134     }
135
136     @Override
137     public <T extends DataContainer> ConvertType<T> rpcData() {
138         return (object, objectClass) -> {
139             ContainerNode normalizedNodeRpcData = getCodecRegistry().toNormalizedNodeRpcData(object);
140             return Optional.ofNullable(normalizedNodeRpcData);
141         };
142     }
143
144     @Override
145     public <T extends Notification> ConvertType<T> notification() {
146         return (object, objectClass) -> {
147             ContainerNode normalizedNodeNotification = getCodecRegistry().toNormalizedNodeNotification(object);
148             return Optional.ofNullable(normalizedNodeNotification);
149         };
150     }
151 }