blob: e95ddcad8dd8ac5098a4cba79e7e220503345eea [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 */
72 DefaultDriver merge(DefaultDriver other) {
73 // Merge the behaviours.
74 ImmutableMap.Builder<Class<? extends Behaviour>, Class<? extends Behaviour>>
75 behaviours = ImmutableMap.builder();
76 behaviours.putAll(other.behaviours).putAll(this.behaviours);
77
78 // Merge the properties.
79 ImmutableMap.Builder<String, String> properties = ImmutableMap.builder();
80 properties.putAll(other.properties).putAll(this.properties);
81
82 return new DefaultDriver(name, manufacturer, hwVersion, swVersion,
83 behaviours.build(), properties.build());
84 }
85
86 @Override
87 public String name() {
88 return name;
89 }
90
91 @Override
92 public String manufacturer() {
93 return manufacturer;
94 }
95
96 @Override
97 public String hwVersion() {
98 return hwVersion;
99 }
100
101 @Override
102 public String swVersion() {
103 return swVersion;
104 }
105
106 @Override
107 public Set<Class<? extends Behaviour>> behaviours() {
108 return behaviours.keySet();
109 }
110
111 @Override
112 public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) {
113 return behaviours.containsKey(behaviourClass);
114 }
115
116 /**
117 * Creates an instance of behaviour primed with the specified driver data.
118 *
119 * @param data driver data context
120 * @param behaviourClass driver behaviour class
121 * @param handler indicates behaviour is intended for handler context
122 * @param <T> type of behaviour
123 * @return behaviour instance
124 */
125 public <T extends Behaviour> T createBehaviour(DriverData data,
126 Class<T> behaviourClass,
127 boolean handler) {
128 checkArgument(handler || !HandlerBehaviour.class.isAssignableFrom(behaviourClass),
129 "{} is applicable only to handler context", behaviourClass.getName());
130
131 // Locate the implementation of the requested behaviour.
132 Class<? extends Behaviour> implementation = behaviours.get(behaviourClass);
133 checkArgument(implementation != null, "{} not supported", behaviourClass.getName());
134
135 // Create an instance of the behaviour and apply data as its context.
136 T behaviour = createBehaviour(behaviourClass, implementation);
137 behaviour.setData(data);
138 return behaviour;
139 }
140
141 @SuppressWarnings("unchecked")
142 private <T extends Behaviour> T createBehaviour(Class<T> behaviourClass,
143 Class<? extends Behaviour> implementation) {
144 try {
145 return (T) implementation.newInstance();
146 } catch (InstantiationException | IllegalAccessException e) {
147 // TODO: add a specific unchecked exception
148 throw new IllegalArgumentException("Unable to create behaviour", e);
149 }
150 }
151
152 @Override
153 public Set<String> keys() {
154 return properties.keySet();
155 }
156
157 @Override
158 public String value(String key) {
159 return properties.get(key);
160 }
161
162 @Override
163 public Map<String, String> properties() {
164 return properties;
165 }
166
167 @Override
168 public String toString() {
169 return toStringHelper(this)
170 .add("name", name)
171 .add("manufacturer", manufacturer)
172 .add("hwVersion", hwVersion)
173 .add("swVersion", swVersion)
174 .add("behaviours", behaviours)
175 .add("properties", properties)
176 .toString();
177 }
178
179}