diff options
Diffstat (limited to 'framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java')
-rw-r--r-- | framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java new file mode 100644 index 00000000..b7a9f2b7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java @@ -0,0 +1,214 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.net.driver; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; + +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableMap.copyOf; + +/** + * Default implementation of extensible driver. + */ +public class DefaultDriver implements Driver { + + private final String name; + private final Driver parent; + + private final String manufacturer; + private final String hwVersion; + private final String swVersion; + + private final Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours; + private final Map<String, String> properties; + + /** + * Creates a driver with the specified name. + * + * @param name driver name + * @param parent optional parent driver + * @param manufacturer device manufacturer + * @param hwVersion device hardware version + * @param swVersion device software version + * @param behaviours device behaviour classes + * @param properties properties for configuration of device behaviour classes + */ + public DefaultDriver(String name, Driver parent, String manufacturer, + String hwVersion, String swVersion, + Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours, + Map<String, String> properties) { + this.name = checkNotNull(name, "Name cannot be null"); + this.parent = parent; + this.manufacturer = checkNotNull(manufacturer, "Manufacturer cannot be null"); + this.hwVersion = checkNotNull(hwVersion, "HW version cannot be null"); + this.swVersion = checkNotNull(swVersion, "SW version cannot be null"); + this.behaviours = copyOf(checkNotNull(behaviours, "Behaviours cannot be null")); + this.properties = copyOf(checkNotNull(properties, "Properties cannot be null")); + } + + @Override + public Driver merge(Driver other) { + checkArgument(parent == null || Objects.equals(parent, other.parent()), + "Parent drivers are not the same"); + + // Merge the behaviours. + Map<Class<? extends Behaviour>, Class<? extends Behaviour>> + behaviours = Maps.newHashMap(); + behaviours.putAll(this.behaviours); + other.behaviours().forEach(b -> behaviours.put(b, other.implementation(b))); + + // Merge the properties. + ImmutableMap.Builder<String, String> properties = ImmutableMap.builder(); + properties.putAll(this.properties).putAll(other.properties()); + + return new DefaultDriver(name, other.parent(), manufacturer, hwVersion, swVersion, + ImmutableMap.copyOf(behaviours), properties.build()); + } + + @Override + public String name() { + return name; + } + + @Override + public String manufacturer() { + return manufacturer; + } + + @Override + public String hwVersion() { + return hwVersion; + } + + @Override + public String swVersion() { + return swVersion; + } + + @Override + public Driver parent() { + return parent; + } + + @Override + public Set<Class<? extends Behaviour>> behaviours() { + return behaviours.keySet(); + } + + @Override + public Class<? extends Behaviour> implementation(Class<? extends Behaviour> behaviour) { + return behaviours.get(behaviour); + } + + @Override + public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) { + return behaviours.containsKey(behaviourClass) || + (parent != null && parent.hasBehaviour(behaviourClass)); + } + + @Override + public <T extends Behaviour> T createBehaviour(DriverData data, + Class<T> behaviourClass) { + T behaviour = createBehaviour(data, null, behaviourClass); + if (behaviour != null) { + return behaviour; + } else if (parent != null) { + return parent.createBehaviour(data, behaviourClass); + } + throw new IllegalArgumentException(behaviourClass.getName() + " not supported"); + } + + @Override + public <T extends Behaviour> T createBehaviour(DriverHandler handler, + Class<T> behaviourClass) { + T behaviour = createBehaviour(handler.data(), handler, behaviourClass); + if (behaviour != null) { + return behaviour; + } else if (parent != null) { + return parent.createBehaviour(handler, behaviourClass); + } + throw new IllegalArgumentException(behaviourClass.getName() + " not supported"); + } + + // Creates an instance of behaviour primed with the specified driver data. + private <T extends Behaviour> T createBehaviour(DriverData data, DriverHandler handler, + Class<T> behaviourClass) { + //checkArgument(handler != null || !HandlerBehaviour.class.isAssignableFrom(behaviourClass), + // "{} is applicable only to handler context", behaviourClass.getName()); + + // Locate the implementation of the requested behaviour. + Class<? extends Behaviour> implementation = behaviours.get(behaviourClass); + if (implementation != null) { + // Create an instance of the behaviour and apply data as its context. + T behaviour = createBehaviour(behaviourClass, implementation); + behaviour.setData(data); + + // If this is a handler behaviour, also apply handler as its context. + if (handler != null) { + ((HandlerBehaviour) behaviour).setHandler(handler); + } + return behaviour; + } + return null; + } + + @SuppressWarnings("unchecked") + private <T extends Behaviour> T createBehaviour(Class<T> behaviourClass, + Class<? extends Behaviour> implementation) { + try { + return (T) implementation.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + // TODO: add a specific unchecked exception + throw new IllegalArgumentException("Unable to create behaviour", e); + } + } + + @Override + public Set<String> keys() { + return properties.keySet(); + } + + @Override + public String value(String key) { + return properties.get(key); + } + + @Override + public Map<String, String> properties() { + return properties; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("name", name) + .add("parent", parent) + .add("manufacturer", manufacturer) + .add("hwVersion", hwVersion) + .add("swVersion", swVersion) + .add("behaviours", behaviours) + .add("properties", properties) + .toString(); + } + +} |