blob: 4a176d782cb91f8162d530c2ed8adb1e285de4c5 [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;
alshabib975617b2015-04-09 13:26:53 -070019import com.google.common.collect.Maps;
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -080020
21import java.util.Map;
22import java.util.Set;
23
24import static com.google.common.base.MoreObjects.toStringHelper;
25import static com.google.common.base.Preconditions.checkArgument;
26import static com.google.common.base.Preconditions.checkNotNull;
27import static com.google.common.collect.ImmutableMap.copyOf;
28
29/**
30 * Default implementation of extensible driver.
31 */
32public class DefaultDriver implements Driver {
33
34 private final String name;
35
36 private final String manufacturer;
37 private final String hwVersion;
38 private final String swVersion;
39
40 private final Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours;
41 private final Map<String, String> properties;
42
43
44 /**
45 * Creates a driver with the specified name.
46 *
47 * @param name driver name
48 * @param manufacturer device manufacturer
49 * @param hwVersion device hardware version
50 * @param swVersion device software version
51 * @param behaviours device behaviour classes
52 * @param properties properties for configuration of device behaviour classes
53 */
54 public DefaultDriver(String name, String manufacturer,
55 String hwVersion, String swVersion,
56 Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours,
57 Map<String, String> properties) {
58 this.name = checkNotNull(name, "Name cannot be null");
59 this.manufacturer = checkNotNull(manufacturer, "Manufacturer cannot be null");
60 this.hwVersion = checkNotNull(hwVersion, "HW version cannot be null");
61 this.swVersion = checkNotNull(swVersion, "SW version cannot be null");
62 this.behaviours = copyOf(checkNotNull(behaviours, "Behaviours cannot be null"));
63 this.properties = copyOf(checkNotNull(properties, "Properties cannot be null"));
64 }
65
66 /**
67 * Merges the two drivers while giving preference to this driver when
68 * dealing with conflicts.
69 *
70 * @param other other driver
71 * @return new driver
72 */
Thomas Vachuska5c2f8132015-04-08 23:09:08 -070073 @Override
74 public Driver merge(Driver other) {
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -080075 // Merge the behaviours.
alshabib975617b2015-04-09 13:26:53 -070076 Map<Class<? extends Behaviour>, Class<? extends Behaviour>>
77 behaviours = Maps.newHashMap();
Thomas Vachuska5c2f8132015-04-08 23:09:08 -070078 behaviours.putAll(this.behaviours);
79 other.behaviours().forEach(b -> behaviours.put(b, other.implementation(b)));
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -080080
81 // Merge the properties.
82 ImmutableMap.Builder<String, String> properties = ImmutableMap.builder();
Thomas Vachuska5c2f8132015-04-08 23:09:08 -070083 properties.putAll(this.properties).putAll(other.properties());
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -080084
85 return new DefaultDriver(name, manufacturer, hwVersion, swVersion,
alshabib975617b2015-04-09 13:26:53 -070086 ImmutableMap.copyOf(behaviours), properties.build());
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -080087 }
88
89 @Override
90 public String name() {
91 return name;
92 }
93
94 @Override
95 public String manufacturer() {
96 return manufacturer;
97 }
98
99 @Override
100 public String hwVersion() {
101 return hwVersion;
102 }
103
104 @Override
105 public String swVersion() {
106 return swVersion;
107 }
108
109 @Override
110 public Set<Class<? extends Behaviour>> behaviours() {
111 return behaviours.keySet();
112 }
113
114 @Override
Thomas Vachuska5c2f8132015-04-08 23:09:08 -0700115 public Class<? extends Behaviour> implementation(Class<? extends Behaviour> behaviour) {
116 return behaviours.get(behaviour);
117 }
118
119 @Override
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -0800120 public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) {
121 return behaviours.containsKey(behaviourClass);
122 }
123
124 /**
125 * Creates an instance of behaviour primed with the specified driver data.
126 *
127 * @param data driver data context
128 * @param behaviourClass driver behaviour class
129 * @param handler indicates behaviour is intended for handler context
130 * @param <T> type of behaviour
131 * @return behaviour instance
132 */
133 public <T extends Behaviour> T createBehaviour(DriverData data,
134 Class<T> behaviourClass,
135 boolean handler) {
136 checkArgument(handler || !HandlerBehaviour.class.isAssignableFrom(behaviourClass),
137 "{} is applicable only to handler context", behaviourClass.getName());
138
139 // Locate the implementation of the requested behaviour.
140 Class<? extends Behaviour> implementation = behaviours.get(behaviourClass);
141 checkArgument(implementation != null, "{} not supported", behaviourClass.getName());
142
143 // Create an instance of the behaviour and apply data as its context.
144 T behaviour = createBehaviour(behaviourClass, implementation);
145 behaviour.setData(data);
146 return behaviour;
147 }
148
149 @SuppressWarnings("unchecked")
150 private <T extends Behaviour> T createBehaviour(Class<T> behaviourClass,
151 Class<? extends Behaviour> implementation) {
152 try {
153 return (T) implementation.newInstance();
154 } catch (InstantiationException | IllegalAccessException e) {
155 // TODO: add a specific unchecked exception
156 throw new IllegalArgumentException("Unable to create behaviour", e);
157 }
158 }
159
160 @Override
161 public Set<String> keys() {
162 return properties.keySet();
163 }
164
165 @Override
166 public String value(String key) {
167 return properties.get(key);
168 }
169
170 @Override
171 public Map<String, String> properties() {
172 return properties;
173 }
174
175 @Override
176 public String toString() {
177 return toStringHelper(this)
178 .add("name", name)
179 .add("manufacturer", manufacturer)
180 .add("hwVersion", hwVersion)
181 .add("swVersion", swVersion)
182 .add("behaviours", behaviours)
183 .add("properties", properties)
184 .toString();
185 }
186
187}