Clean up AugmentationCodecContext
[mdsal.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / mdsal / binding / dom / codec / impl / AugmentationCodecContext.java
1 /*
2  * Copyright (c) 2014 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.mdsal.binding.dom.codec.impl;
9
10 import com.google.common.base.Throwables;
11 import com.google.common.collect.ImmutableSet;
12 import java.lang.invoke.MethodHandle;
13 import java.lang.invoke.MethodHandles;
14 import java.lang.invoke.MethodType;
15 import java.util.List;
16 import java.util.Map;
17 import org.opendaylight.mdsal.binding.dom.codec.api.BindingAugmentationCodecTreeNode;
18 import org.opendaylight.mdsal.binding.runtime.api.AugmentRuntimeType;
19 import org.opendaylight.yangtools.yang.binding.Augmentation;
20 import org.opendaylight.yangtools.yang.binding.DataObjectStep;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
23 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
25
26 final class AugmentationCodecContext<A extends Augmentation<?>>
27         extends AbstractDataObjectCodecContext<A, AugmentRuntimeType> implements BindingAugmentationCodecTreeNode<A> {
28     private static final MethodType CONSTRUCTOR_TYPE = MethodType.methodType(void.class,
29         AbstractDataObjectCodecContext.class, DataContainerNode.class);
30     private static final MethodType AUGMENTATION_TYPE = MethodType.methodType(Augmentation.class,
31         AugmentationCodecContext.class, DataContainerNode.class);
32
33     private final MethodHandle proxyConstructor;
34
35     private AugmentationCodecContext(final AugmentationCodecPrototype<A> prototype,
36             final DataContainerAnalysis<AugmentRuntimeType> analysis) {
37         super(prototype, analysis);
38
39         final var bindingClass = CodecDataObjectGenerator.generate(prototype.contextFactory().getLoader(),
40             prototype.javaClass(), analysis.leafContexts, analysis.daoProperties, null);
41
42         final MethodHandle ctor;
43         try {
44             ctor = MethodHandles.publicLookup().findConstructor(bindingClass, CONSTRUCTOR_TYPE);
45         } catch (NoSuchMethodException | IllegalAccessException e) {
46             throw new LinkageError("Failed to find contructor for class " + bindingClass, e);
47         }
48
49         proxyConstructor = ctor.asType(AUGMENTATION_TYPE);
50     }
51
52     AugmentationCodecContext(final AugmentationCodecPrototype<A> prototype) {
53         this(prototype, new DataContainerAnalysis<>(prototype, CodecItemFactory.of()));
54     }
55
56     @Override
57     public PathArgument serializePathArgument(final DataObjectStep<?> step) {
58         if (!bindingArg().equals(step)) {
59             throw new IllegalArgumentException("Unexpected argument " + step);
60         }
61         return null;
62     }
63
64     @Override
65     public DataObjectStep<?> deserializePathArgument(final PathArgument arg) {
66         if (arg != null) {
67             throw new IllegalArgumentException("Unexpected argument " + arg);
68         }
69         return bindingArg();
70     }
71
72     @SuppressWarnings("checkstyle:illegalCatch")
73     @Override
74     public A filterFrom(final DataContainerNode parentData) {
75         for (var childArg : ((AugmentationCodecPrototype<?>) prototype()).getChildArgs()) {
76             if (parentData.childByArg(childArg) != null) {
77                 try {
78                     return (A) proxyConstructor.invokeExact(this, parentData);
79                 } catch (final Throwable e) {
80                     Throwables.throwIfUnchecked(e);
81                     throw new IllegalStateException(e);
82                 }
83             }
84         }
85         return null;
86     }
87
88     @Override
89     public ImmutableSet<NodeIdentifier> childPathArguments() {
90         return byYangKeySet();
91     }
92
93     @Override
94     Object deserializeObject(final NormalizedNode normalizedNode) {
95         return filterFrom(checkDataArgument(DataContainerNode.class, normalizedNode));
96     }
97
98     @Override
99     void addYangPathArgument(final List<PathArgument> builder, final DataObjectStep<?> step) {
100         // No-op
101     }
102
103     @Override
104     NodeIdentifier getDomPathArgument() {
105         return null;
106     }
107
108     @Override
109     Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAllAugmentationsFrom(final DataContainerNode data) {
110         return Map.of();
111     }
112 }