Add binding adapter components for RPC services
[mdsal.git] / binding / mdsal-binding-dom-adapter / src / main / java / org / opendaylight / mdsal / binding / dom / adapter / osgi / Dict.java
1 /*
2  * Copyright (c) 2018 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.dom.adapter.osgi;
9
10 import com.google.common.collect.ImmutableMap;
11 import com.google.common.collect.Iterators;
12 import com.google.common.collect.Maps;
13 import java.util.Dictionary;
14 import java.util.Enumeration;
15 import java.util.Map;
16 import org.eclipse.jdt.annotation.NonNullByDefault;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.mdsal.binding.api.BindingService;
19 import org.osgi.framework.ServiceReference;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 @NonNullByDefault
24 final class Dict extends Dictionary<String, Object> {
25     private static final Logger LOG = LoggerFactory.getLogger(Dict.class);
26     private static final Dict EMPTY = new Dict(ImmutableMap.of());
27
28     private final Map<String, Object> map;
29
30     private Dict(final Map<String, Object> map) {
31         this.map = ImmutableMap.copyOf(map);
32     }
33
34     static Dict fromReference(final ServiceReference<?> ref) {
35         final String[] keys = ref.getPropertyKeys();
36         if (keys.length == 0) {
37             return EMPTY;
38         }
39
40         return new Dict(populateProperties(ref, keys, 0));
41     }
42
43     static Dict fromReference(final ServiceReference<?> ref, final BindingService service) {
44         final Map<String, Object> props = populateProperties(ref, ref.getPropertyKeys(), 1);
45         props.put(AbstractAdaptedService.DELEGATE, service);
46         return new Dict(props);
47     }
48
49     private static Map<String, Object> populateProperties(final ServiceReference<?> ref, final String[] keys,
50             final int extra) {
51         final Map<String, Object> props = Maps.newHashMapWithExpectedSize(keys.length + extra);
52         for (String key : keys) {
53             // Ignore properties with our prefix: we are not exporting those
54             if (!key.startsWith(ServiceProperties.PREFIX)) {
55                 final Object value = ref.getProperty(key);
56                 if (value != null) {
57                     props.put(key, value);
58                 }
59             }
60         }
61
62         // Second phase: apply any our properties
63         for (String key : keys) {
64             if (key.startsWith(ServiceProperties.OVERRIDE_PREFIX)) {
65                 final Object value = ref.getProperty(key);
66                 if (value != null) {
67                     final String newKey = key.substring(ServiceProperties.OVERRIDE_PREFIX.length());
68                     if (!newKey.isEmpty()) {
69                         LOG.debug("Overriding property {}", newKey);
70                         props.put(newKey, value);
71                     }
72                 }
73             }
74         }
75
76         return props;
77     }
78
79     @Override
80     public int size() {
81         return map.size();
82     }
83
84     @Override
85     public boolean isEmpty() {
86         return map.isEmpty();
87     }
88
89     @Override
90     public Enumeration<String> keys() {
91         return Iterators.asEnumeration(map.keySet().iterator());
92     }
93
94     @Override
95     public Enumeration<Object> elements() {
96         return Iterators.asEnumeration(map.values().iterator());
97     }
98
99     @Override
100     public Object get(final @Nullable Object key) {
101         return map.get(key);
102     }
103
104     @Override
105     public Object put(final String key, final Object value) {
106         return map.put(key, value);
107     }
108
109     @Override
110     public Object remove(final @Nullable Object key) {
111         return map.remove(key);
112     }
113
114     @Override
115     public int hashCode() {
116         return map.hashCode();
117     }
118
119     @Override
120     public boolean equals(final @Nullable Object obj) {
121         return this == obj || obj instanceof Dict && map.equals(((Dict) obj).map);
122     }
123
124     @Override
125     public String toString() {
126         return map.toString();
127     }
128 }