Correct docs declaration
[mdsal.git] / binding2 / mdsal-binding2-dom-codec / src / main / java / org / opendaylight / mdsal / binding / javav2 / dom / codec / impl / context / KeyedListNodeCodecContext.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.dom.codec.impl.context;
9
10 import com.google.common.annotations.Beta;
11 import java.lang.reflect.Method;
12 import java.util.List;
13 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.DataContainerCodecPrototype;
14 import org.opendaylight.mdsal.binding.javav2.spec.base.IdentifiableItem;
15 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeArgument;
16 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
17 import org.opendaylight.yangtools.concepts.Codec;
18 import org.opendaylight.yangtools.concepts.Identifiable;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
22 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
23 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
24 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
25
26 /**
27  * Codec context for serializing and deserializing keyed list node and it's
28  * path.
29  *
30  * @param <D>
31  *            - type of tree node
32  */
33 @Beta
34 public final class KeyedListNodeCodecContext<D extends TreeNode & Identifiable<?>> extends ListNodeCodecContext<D> {
35
36     private final Codec<NodeIdentifierWithPredicates, IdentifiableItem<?, ?>> codec;
37     private final Method keyGetter;
38
39     /**
40      * Prepare context for keyed list node from prototype.
41      *
42      * @param prototype
43      *            - codec prototype of keyed list node
44      */
45     public KeyedListNodeCodecContext(final DataContainerCodecPrototype<ListSchemaNode> prototype) {
46         super(prototype);
47         this.codec = factory().getPathArgumentCodec(getBindingClass(), getSchema());
48         try {
49             this.keyGetter = getBindingClass().getMethod("getIdentifier");
50         } catch (final NoSuchMethodException e) {
51             throw new IllegalStateException("Required method not available", e);
52         }
53     }
54
55     @SuppressWarnings("rawtypes")
56     @Override
57     public void addYangPathArgument(final TreeArgument arg, final List<PathArgument> builder) {
58         /*
59          * DOM Instance Identifier for list is always represent by two entries
60          * one for map and one for children. This is also true for wildcarded
61          * instance identifiers
62          */
63         if (builder == null) {
64             return;
65         }
66
67         super.addYangPathArgument(arg, builder);
68         if (arg instanceof IdentifiableItem<?, ?>) {
69             builder.add(codec.serialize((IdentifiableItem<?, ?>) arg));
70         } else {
71             // Adding wildcarded
72             super.addYangPathArgument(arg, builder);
73         }
74     }
75
76     @Override
77     @SuppressWarnings("rawtypes")
78     public Object getBindingChildValue(final Method method, final NormalizedNodeContainer dom) {
79         if (dom instanceof MapEntryNode && keyGetter.equals(method)) {
80             final NodeIdentifierWithPredicates identifier = ((MapEntryNode) dom).getIdentifier();
81             return codec.deserialize(identifier).getKey();
82         } else {
83             return super.getBindingChildValue(method, dom);
84         }
85     }
86
87     @Override
88     protected TreeArgument<?> getBindingPathArgument(final YangInstanceIdentifier.PathArgument domArg) {
89         if (domArg instanceof NodeIdentifierWithPredicates) {
90             return codec.deserialize((NodeIdentifierWithPredicates) domArg);
91         }
92         return super.getBindingPathArgument(domArg);
93     }
94
95     @SuppressWarnings("rawtypes")
96     public NodeIdentifierWithPredicates serialize(final IdentifiableItem keyValues) {
97         return codec.serialize(keyValues);
98     }
99
100     @SuppressWarnings("rawtypes")
101     @Override
102     public YangInstanceIdentifier.PathArgument serializePathArgument(final TreeArgument arg) {
103         if (arg instanceof IdentifiableItem) {
104             return codec.serialize((IdentifiableItem<?, ?>) arg);
105         }
106         return super.serializePathArgument(arg);
107     }
108
109     @SuppressWarnings("rawtypes")
110     @Override
111     public TreeArgument deserializePathArgument(final YangInstanceIdentifier.PathArgument arg) {
112         if (arg instanceof NodeIdentifierWithPredicates) {
113             return codec.deserialize((NodeIdentifierWithPredicates) arg);
114         }
115         return super.deserializePathArgument(arg);
116     }
117 }
118