All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.onosproject.net.driver.DefaultDriver Maven / Gradle / Ivy

There is a newer version: 2.7.0
Show newest version
/*
 * 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> behaviours;
    private final Map 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> behaviours,
                         Map 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>
                behaviours = Maps.newHashMap();
        behaviours.putAll(this.behaviours);
        other.behaviours().forEach(b -> behaviours.put(b, other.implementation(b)));

        // Merge the properties.
        ImmutableMap.Builder 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> behaviours() {
        return behaviours.keySet();
    }

    @Override
    public Class implementation(Class behaviour) {
        return behaviours.get(behaviour);
    }

    @Override
    public boolean hasBehaviour(Class behaviourClass) {
        return behaviours.containsKey(behaviourClass) ||
                (parent != null && parent.hasBehaviour(behaviourClass));
    }

    @Override
    public  T createBehaviour(DriverData data,
                                                   Class 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 createBehaviour(DriverHandler handler,
                                                   Class 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 createBehaviour(DriverData data, DriverHandler handler,
                                                    Class behaviourClass) {
        //checkArgument(handler != null || !HandlerBehaviour.class.isAssignableFrom(behaviourClass),
        //              "{} is applicable only to handler context", behaviourClass.getName());

        // Locate the implementation of the requested behaviour.
        Class 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 createBehaviour(Class behaviourClass,
                                                    Class 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 keys() {
        return properties.keySet();
    }

    @Override
    public String value(String key) {
        return properties.get(key);
    }

    @Override
    public Map 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();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy