blob: e7cd89e20de76ddbd89a22a69530e41aec6093bf [file] [log] [blame]
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.net.driver;
17
18import com.google.common.collect.ImmutableMap;
19
20import java.util.Map;
21import java.util.Set;
22
23import static com.google.common.base.MoreObjects.toStringHelper;
24import static com.google.common.base.Preconditions.checkArgument;
25import static com.google.common.base.Preconditions.checkNotNull;
26import static com.google.common.collect.ImmutableMap.copyOf;
27
28/**
29 * Default implementation of extensible driver.
30 */
31public class DefaultDriver implements Driver {
32
33 private final String name;
34
35 private final String manufacturer;
36 private final String hwVersion;
37 private final String swVersion;
38
39 private final Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours;
40 private final Map<String, String> properties;
41
42
43 /**
44 * Creates a driver with the specified name.
45 *
46 * @param name driver name
47 * @param manufacturer device manufacturer
48 * @param hwVersion device hardware version
49 * @param swVersion device software version
50 * @param behaviours device behaviour classes
51 * @param properties properties for configuration of device behaviour classes
52 */
53 public DefaultDriver(String name, String manufacturer,
54 String hwVersion, String swVersion,
55 Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours,
56 Map<String, String> properties) {
57 this.name = checkNotNull(name, "Name cannot be null");
58 this.manufacturer = checkNotNull(manufacturer, "Manufacturer cannot be null");
59 this.hwVersion = checkNotNull(hwVersion, "HW version cannot be null");
60 this.swVersion = checkNotNull(swVersion, "SW version cannot be null");
61 this.behaviours = copyOf(checkNotNull(behaviours, "Behaviours cannot be null"));
62 this.properties = copyOf(checkNotNull(properties, "Properties cannot be null"));
63 }
64
65 /**
66 * Merges the two drivers while giving preference to this driver when
67 * dealing with conflicts.
68 *
69 * @param other other driver
70 * @return new driver
71 */
Thomas Vachuska5c2f8132015-04-08 23:09:08 -070072 @Override
73 public Driver merge(Driver other) {
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -080074 // Merge the behaviours.
75 ImmutableMap.Builder<Class<? extends Behaviour>, Class<? extends Behaviour>>
76 behaviours = ImmutableMap.builder();
Thomas Vachuska5c2f8132015-04-08 23:09:08 -070077 behaviours.putAll(this.behaviours);
78 other.behaviours().forEach(b -> behaviours.put(b, other.implementation(b)));
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -080079
80 // Merge the properties.
81 ImmutableMap.Builder<String, String> properties = ImmutableMap.builder();
Thomas Vachuska5c2f8132015-04-08 23:09:08 -070082 properties.putAll(this.properties).putAll(other.properties());
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -080083
84 return new DefaultDriver(name, manufacturer, hwVersion, swVersion,
85 behaviours.build(), properties.build());
86 }
87
88 @Override
89 public String name() {
90 return name;
91 }
92
93 @Override
94 public String manufacturer() {
95 return manufacturer;
96 }
97
98 @Override
99 public String hwVersion() {
100 return hwVersion;
101 }
102
103 @Override
104 public String swVersion() {
105 return swVersion;
106 }
107
108 @Override
109 public Set<Class<? extends Behaviour>> behaviours() {
110 return behaviours.keySet();
111 }
112
113 @Override
Thomas Vachuska5c2f8132015-04-08 23:09:08 -0700114 public Class<? extends Behaviour> implementation(Class<? extends Behaviour> behaviour) {
115 return behaviours.get(behaviour);
116 }
117
118 @Override
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -0800119 public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) {
120 return behaviours.containsKey(behaviourClass);
121 }
122
123 /**
124 * Creates an instance of behaviour primed with the specified driver data.
125 *
126 * @param data driver data context
127 * @param behaviourClass driver behaviour class
128 * @param handler indicates behaviour is intended for handler context
129 * @param <T> type of behaviour
130 * @return behaviour instance
131 */
132 public <T extends Behaviour> T createBehaviour(DriverData data,
133 Class<T> behaviourClass,
134 boolean handler) {
135 checkArgument(handler || !HandlerBehaviour.class.isAssignableFrom(behaviourClass),
136 "{} is applicable only to handler context", behaviourClass.getName());
137
138 // Locate the implementation of the requested behaviour.
139 Class<? extends Behaviour> implementation = behaviours.get(behaviourClass);
140 checkArgument(implementation != null, "{} not supported", behaviourClass.getName());
141
142 // Create an instance of the behaviour and apply data as its context.
143 T behaviour = createBehaviour(behaviourClass, implementation);
144 behaviour.setData(data);
145 return behaviour;
146 }
147
148 @SuppressWarnings("unchecked")
149 private <T extends Behaviour> T createBehaviour(Class<T> behaviourClass,
150 Class<? extends Behaviour> implementation) {
151 try {
152 return (T) implementation.newInstance();
153 } catch (InstantiationException | IllegalAccessException e) {
154 // TODO: add a specific unchecked exception
155 throw new IllegalArgumentException("Unable to create behaviour", e);
156 }
157 }
158
159 @Override
160 public Set<String> keys() {
161 return properties.keySet();
162 }
163
164 @Override
165 public String value(String key) {
166 return properties.get(key);
167 }
168
169 @Override
170 public Map<String, String> properties() {
171 return properties;
172 }
173
174 @Override
175 public String toString() {
176 return toStringHelper(this)
177 .add("name", name)
178 .add("manufacturer", manufacturer)
179 .add("hwVersion", hwVersion)
180 .add("swVersion", swVersion)
181 .add("behaviours", behaviours)
182 .add("properties", properties)
183 .toString();
184 }
185
186}