09b87ee54d86d03c535c4a16f18971acddcee40a
[genius.git] / mdsalutil / mdsalutil-api / src / main / java / org / opendaylight / genius / mdsalutil / nxmatches / NxMatchInfoHelper.java
1 /*
2  * Copyright © 2017 Red Hat, Inc. and others.
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.genius.mdsalutil.nxmatches;
9
10 import java.util.HashMap;
11 import java.util.Map;
12 import org.opendaylight.genius.mdsalutil.NxMatchInfo;
13 import org.opendaylight.genius.utils.SuperTypeUtil;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListKey;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlowBuilder;
24 import org.opendaylight.yangtools.concepts.Builder;
25 import org.opendaylight.yangtools.yang.binding.DataObject;
26
27 /**
28  * Helper for Nicira extension matches (this is designed to be absorbed into MatchInfo once we've cleaned up
29  * downstream users).
30  */
31 public abstract class NxMatchInfoHelper<T extends DataObject, B extends Builder<T>> implements NxMatchInfo {
32     private final Class<B> builderClass;
33     // The key class can't be a type parameter, it varies in some subclasses
34     private final Class<? extends ExtensionKey> keyClass;
35
36     protected NxMatchInfoHelper(Class<? extends ExtensionKey> keyClass) {
37         this.keyClass = keyClass;
38         builderClass = SuperTypeUtil.getTypeParameter(getClass(), 1);
39     }
40
41     @Override
42     public void createInnerMatchBuilder(Map<Class<?>, Object> mapMatchBuilder) {
43         populateBuilder((B) mapMatchBuilder.computeIfAbsent(builderClass, key -> {
44             try {
45                 return builderClass.getDeclaredConstructor().newInstance();
46             } catch (ReflectiveOperationException e) {
47                 throw new IllegalStateException("Unable to create an instance of " + builderClass, e);
48             }
49         }));
50     }
51
52     @Override
53     public void setMatch(MatchBuilder matchBuilder, Map<Class<?>, Object> mapMatchBuilder) {
54         B builder = (B) mapMatchBuilder.remove(builderClass);
55
56         if (builder != null) {
57             NxAugMatchNodesNodeTableFlowBuilder nxAugMatchBuilder = new NxAugMatchNodesNodeTableFlowBuilder();
58             applyValue(nxAugMatchBuilder, builder.build());
59             NxAugMatchNodesNodeTableFlow nxAugMatch = nxAugMatchBuilder.build();
60             GeneralAugMatchNodesNodeTableFlow existingAugmentations = matchBuilder
61                     .augmentation(GeneralAugMatchNodesNodeTableFlow.class);
62             GeneralAugMatchNodesNodeTableFlow genAugMatch = generalAugMatchBuilder(existingAugmentations,
63                     nxAugMatch, keyClass);
64             matchBuilder.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, genAugMatch);
65         }
66     }
67
68     private static GeneralAugMatchNodesNodeTableFlow generalAugMatchBuilder(
69             GeneralAugMatchNodesNodeTableFlow existingAugmentations, NxAugMatchNodesNodeTableFlow nxAugMatch,
70             Class<? extends ExtensionKey> extentionKey) {
71
72         Map<ExtensionListKey, ExtensionList> extensions = null;
73
74         if (existingAugmentations != null) {
75             extensions = existingAugmentations.getExtensionList();
76         }
77         if (extensions == null) {
78             extensions = new HashMap<>();
79         }
80
81         ExtensionList extensionList = new ExtensionListBuilder().setExtensionKey(extentionKey)
82                 .setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class,
83                         nxAugMatch).build()).build();
84         extensions.put(extensionList.key(),extensionList);
85         return new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(extensions).build();
86     }
87
88     protected abstract void applyValue(NxAugMatchNodesNodeTableFlowBuilder matchBuilder, T value);
89
90     protected abstract void populateBuilder(B builder);
91
92     @Override
93     public boolean equals(Object other) {
94         if (this == other) {
95             return true;
96         }
97         if (other == null || getClass() != other.getClass()) {
98             return false;
99         }
100
101         NxMatchInfoHelper<?, ?> that = (NxMatchInfoHelper<?, ?>) other;
102
103         if (builderClass != null ? !builderClass.equals(that.builderClass) : that.builderClass != null) {
104             return false;
105         }
106         return keyClass != null ? keyClass.equals(that.keyClass) : that.keyClass == null;
107     }
108
109     @Override
110     public int hashCode() {
111         int result = builderClass != null ? builderClass.hashCode() : 0;
112         result = 31 * result + (keyClass != null ? keyClass.hashCode() : 0);
113         return result;
114     }
115
116     @Override
117     public abstract String toString();
118 }