2493df11067005b559c7f2ae8c82984bfbb7e218
[transportpce.git] / tests / honeynode / honeynode-common / src / main / java / io / fd / honeycomb / transportpce / binding / converter / AbstractDataObjectConverter.java
1 /*
2  * Copyright (c) 2018 AT&T and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package io.fd.honeycomb.transportpce.binding.converter;
17
18 import com.google.common.base.Preconditions;
19
20 import io.fd.honeycomb.transportpce.binding.converter.api.DataObjectConverter;
21
22 import java.util.Map;
23 import java.util.Map.Entry;
24 import java.util.Optional;
25 import javax.annotation.Nonnull;
26 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
27 import org.opendaylight.yangtools.yang.binding.DataContainer;
28 import org.opendaylight.yangtools.yang.binding.DataObject;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.opendaylight.yangtools.yang.binding.Notification;
31 import org.opendaylight.yangtools.yang.common.QName;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
33 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
36 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
37 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 /**
42  * Converts XML and {@link DataObject} vice versa.
43  *
44  */
45 public abstract class AbstractDataObjectConverter implements DataObjectConverter {
46
47     private static final Logger LOG = LoggerFactory.getLogger(AbstractDataObjectConverter.class);
48
49     private final SchemaContext schemaContext;
50     private final BindingNormalizedNodeSerializer codecRegistry;
51
52     /**
53      * This is the default constructor, which should be used.
54      *
55      * @param schemaContext schema context for converter
56      * @param codecRegistry codec registry used for converting
57      *
58      */
59     protected AbstractDataObjectConverter(SchemaContext schemaContext, BindingNormalizedNodeSerializer codecRegistry) {
60         this.schemaContext = schemaContext;
61         this.codecRegistry = codecRegistry;
62     }
63
64     public SchemaContext getSchemaContext() {
65         return schemaContext;
66     }
67
68     public BindingNormalizedNodeSerializer getCodecRegistry() {
69         return codecRegistry;
70     }
71
72     /**
73      * Transforms the given input {@link NormalizedNode} into the given
74      * {@link DataObject}.
75      *
76      * @param normalizedNode normalized node you want to convert
77      * @param rootNode {@link QName} of converted normalized node root
78      *
79      * <p>
80      * The input object should be {@link ContainerNode}
81      * </p>
82      */
83     @Override
84     @SuppressWarnings("unchecked")
85     public <T extends DataObject> Optional<T> getDataObject(
86             @Nonnull NormalizedNode<?, ?> normalizedNode,
87             @Nonnull QName rootNode) {
88         Preconditions.checkNotNull(normalizedNode);
89         if (normalizedNode instanceof ContainerNode) {
90             YangInstanceIdentifier.PathArgument directChildIdentifier =
91                     YangInstanceIdentifier.of(rootNode).getLastPathArgument();
92             Optional<NormalizedNode<?, ?>> directChild =
93                     NormalizedNodes.getDirectChild(normalizedNode, directChildIdentifier).toJavaUtil();
94             if (!directChild.isPresent()) {
95                 throw new IllegalStateException(String.format("Could not get the direct child of %s", rootNode));
96             }
97             normalizedNode = directChild.get();
98         }
99         YangInstanceIdentifier rootNodeYangInstanceIdentifier = YangInstanceIdentifier.of(rootNode);
100
101         Map.Entry<?, ?> bindingNodeEntry =
102                 codecRegistry.fromNormalizedNode(rootNodeYangInstanceIdentifier, normalizedNode);
103         if (bindingNodeEntry == null) {
104             return Optional.empty();
105         }
106         return Optional.ofNullable((T) bindingNodeEntry.getValue());
107     }
108
109     @Override
110     @SuppressWarnings("unchecked")
111     public <T extends DataObject> Optional<T> getDataObjectFromRpc(
112             @Nonnull NormalizedNode<?, ?> normalizedNode,
113             @Nonnull SchemaPath rpcSchemaPath) {
114
115         if (! (normalizedNode instanceof ContainerNode)) {
116             LOG.error("converting normalized node is not ContainerNode. It's actual type is {}",
117                     normalizedNode.getClass().getSimpleName());
118             return Optional.empty();
119         }
120         T rpcDataObject = (T) codecRegistry.fromNormalizedNodeRpcData(rpcSchemaPath, (ContainerNode) normalizedNode);
121         return Optional.ofNullable(rpcDataObject);
122     }
123
124     @Override
125     public <T extends DataObject> Optional<NormalizedNode<?, ?>> toNormalizedNodes(@Nonnull T object,
126             Class<T> dataObjectClass) {
127         Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
128                 codecRegistry.toNormalizedNode(InstanceIdentifier.create(dataObjectClass), object);
129         return Optional.ofNullable(normalizedNode.getValue());
130     }
131
132     @Override
133     public <T extends DataObject> ConvertType<T> dataContainer() {
134         return (object, objectClass) -> {
135             NormalizedNode<?, ?> value =
136                     getCodecRegistry().toNormalizedNode(InstanceIdentifier.create(objectClass), object).getValue();
137             return Optional.ofNullable(value);
138         };
139     }
140
141     @Override
142     public <T extends DataContainer> ConvertType<T> rpcData() {
143         return (object, objectClass) -> {
144             ContainerNode normalizedNodeRpcData = getCodecRegistry().toNormalizedNodeRpcData(object);
145             return Optional.ofNullable(normalizedNodeRpcData);
146         };
147     }
148
149     @Override
150     public <T extends Notification> ConvertType<T> notification() {
151         return (object, objectClass) -> {
152             ContainerNode normalizedNodeNotification = getCodecRegistry().toNormalizedNodeNotification(object);
153             return Optional.ofNullable(normalizedNodeNotification);
154         };
155     }
156 }