Merge "BUG-2329 Add test for anyxmls inside rpc resonse for netcfon-connector"
[controller.git] / opendaylight / adsal / sal / implementation / src / main / java / org / opendaylight / controller / sal / implementation / internal / ProtocolService.java
1 /*
2  * Copyright (c) 2014 NEC Corporation 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
9 package org.opendaylight.controller.sal.implementation.internal;
10
11 import java.util.Map;
12 import java.util.concurrent.ConcurrentMap;
13
14 import org.slf4j.Logger;
15
16 import org.opendaylight.controller.sal.utils.GlobalConstants;
17
18 /**
19  * An instance of this class keeps a protocol plugin service handler.
20  *
21  * @param <T>  Type of protocol plugin service.
22  */
23 public final class ProtocolService<T> {
24     /**
25      * Default priority value.
26      */
27     private static final int  DEFAULT_PRIORITY = 0;
28
29     /**
30      * A protocol plugin service handler.
31      */
32     private final T  service;
33
34     /**
35      * A priority value assigned to this protocol plugin.
36      */
37     private final int  priority;
38
39     /**
40      * Set protocol plugin service.
41      *
42      * @param map     A map that keeps protocol plugin services.
43      * @param props   Service properties.
44      * @param s       Protocol plugin service.
45      * @param logger  A logger instance.
46      * @param <S>     Type of protocol plugin service.
47      */
48     public static <S> void set(ConcurrentMap<String, ProtocolService<S>> map,
49                                Map<?, ?> props, S s, Logger logger) {
50         if (map == null) {
51             logger.error("Protocol plugin service store is null.");
52             return;
53         }
54         if (s == null) {
55             logger.error("Protocol plugin service is null.");
56             return;
57         }
58         if (props == null) {
59             logger.error("Service property is null.");
60             return;
61         }
62
63         if (logger.isTraceEnabled()) {
64             logger.trace("Received set service request: {}", s);
65             for (Map.Entry<?, ?> entry: props.entrySet()) {
66                 logger.trace("Prop key:({}) value:({})", entry.getKey(),
67                              entry.getValue());
68             }
69         }
70
71         Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
72         if (!(value instanceof String)) {
73             logger.error("Unexpected protocol type: {}", value);
74             return;
75         }
76
77         String type = (String)value;
78         ProtocolService<S> service = new ProtocolService<S>(props, s);
79         ProtocolService<S> old = map.putIfAbsent(type, service);
80         while (old != null) {
81             // Compare priority value.
82             if (old.getPriority() >= service.getPriority()) {
83                 logger.trace("Protocol plugin service for {} is already set: " +
84                              "current={}, requested={}", type, old, service);
85                 return;
86             }
87
88             if (map.replace(type, old, service)) {
89                 break;
90             }
91             old = map.putIfAbsent(type, service);
92         }
93
94         logger.debug("Stored protocol plugin service for {}: {}",
95                      type, service);
96     }
97
98     /**
99      * Unset protocol plugin service.
100      *
101      * @param map     A map that keeps protocol plugin services.
102      * @param props   Service properties.
103      * @param s       Protocol plugin service.
104      * @param logger  A logger instance.
105      * @param <S>     Type of protocol plugin service.
106      */
107     public static <S> void unset(ConcurrentMap<String, ProtocolService<S>> map,
108                                  Map<?, ?> props, S s, Logger logger) {
109         if (map == null) {
110             logger.error("Protocol plugin service store is null.");
111             return;
112         }
113         if (s == null) {
114             logger.error("Protocol plugin service is null.");
115             return;
116         }
117         if (props == null) {
118             logger.error("Service property is null.");
119             return;
120         }
121
122         if (logger.isTraceEnabled()) {
123             logger.trace("Received unset service request: {}", s);
124             for (Map.Entry<?, ?> entry: props.entrySet()) {
125                 logger.trace("Prop key:({}) value:({})",
126                              entry.getKey(), entry.getValue());
127             }
128         }
129
130         Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
131         if (!(value instanceof String)) {
132             logger.error("Unexpected protocol type {}: service={}", value, s);
133             return;
134         }
135
136         String type = (String)value;
137         ProtocolService<S> plugin = new ProtocolService<S>(props, s);
138         if (map.remove(type, plugin)) {
139             logger.debug("Removed protocol plugin service for {}: {}",
140                          type, plugin);
141         } else {
142             logger.trace("Ignore unset service request for {}: {}",
143                          type, plugin);
144         }
145     }
146
147     /**
148      * Constructor.
149      *
150      * @param props  Protocol plugin service properties.
151      * @param s      A protocol plugin service handler.
152      */
153     public ProtocolService(Map<?, ?> props, T s) {
154         service = s;
155
156         String key = GlobalConstants.PROTOCOLPLUGINPRIORITY.toString();
157         Object value = props.get(key);
158         if (value instanceof Integer) {
159             priority = ((Integer)value).intValue();
160         } else {
161             priority = DEFAULT_PRIORITY;
162         }
163     }
164
165     /**
166      * Return a protocol plugin service handler.
167      *
168      * @return  A protocol plugin service handler.
169      */
170     public T getService() {
171         return service;
172     }
173
174     /**
175      * Return a priority value assigned to this protocol plugin.
176      *
177      * @return  A priority value.
178      */
179     public int getPriority() {
180         return priority;
181     }
182
183     /**
184      * Determine whether the given object is identical to this object.
185      *
186      * @param o  An object to be compared.
187      * @return   {@code true} if identical. Otherwise {@code false}.
188      */
189     @Override
190     public boolean equals(Object o) {
191         if (o == this) {
192             return true;
193         }
194         if (o == null || o.getClass() != getClass()) {
195             return false;
196         }
197
198         ProtocolService<?> plugin = (ProtocolService<?>)o;
199         return (service.equals(plugin.service) && priority == plugin.priority);
200     }
201
202     /**
203      * Return the hash code of this object.
204      *
205      * @return  The hash code.
206      */
207     @Override
208     public int hashCode() {
209         return service.hashCode() + (priority * 31);
210     }
211
212     /**
213      * Return a string representation of this instance.
214      *
215      * @return  A string representation of this instance.
216      */
217     @Override
218     public String toString() {
219         StringBuilder builder = new StringBuilder("[service=");
220         return builder.append(service).append(", priority=").append(priority).
221             append(']').toString();
222     }
223 }