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