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.Lists;
import com.google.common.collect.Maps;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.List;
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;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Default implementation of extensible driver.
 */
public class DefaultDriver implements Driver {

    private final Logger log = getLogger(getClass());

    private final String name;
    private final List parents;

    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
     * @deprecated 1.5.0 Falcon Release
     */
    @Deprecated
    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.parents = parent == null ? null : Lists.newArrayList(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"));
    }

    /**
     * Creates a driver with the specified name.
     *
     * @param name         driver name
     * @param parents      optional parent drivers
     * @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, List parents, String manufacturer,
                         String hwVersion, String swVersion,
                         Map, Class> behaviours,
                         Map properties) {
        this.name = checkNotNull(name, "Name cannot be null");
        this.parents = parents == null || parents.isEmpty() ? null : parents;
        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(parents == 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());
        List completeParents = new ArrayList<>();

        if (parents != null) {
            parents.forEach(parent -> other.parents().forEach(otherParent -> {
                if (otherParent.name().equals(parent.name())) {
                    completeParents.add(parent.merge(otherParent));
                } else if (!completeParents.contains(otherParent)) {
                    completeParents.add(otherParent);
                } else if (!completeParents.contains(parent)) {
                    completeParents.add(parent);
                }
            }));
        }
        return new DefaultDriver(name, completeParents.size() > 0 ? completeParents : other.parents(),
                                 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 parents == null ? null : parents.get(0);
    }

    @Override
    public List parents() {
        return parents;
    }

    @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) ||
                (parents != null && parents.stream()
                        .filter(parent -> parent.hasBehaviour(behaviourClass)).count() > 0);
    }

    @Override
    public  T createBehaviour(DriverData data,
                                                   Class behaviourClass) {
        T behaviour = createBehaviour(data, null, behaviourClass);
        if (behaviour != null) {
            return behaviour;
        } else if (parents != null) {
            for (Driver parent : Lists.reverse(parents)) {
                try {
                    return parent.createBehaviour(data, behaviourClass);
                } catch (IllegalArgumentException e) {
                    log.debug("Parent {} does not support behaviour {}", parent, 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 (parents != null && !parents.isEmpty()) {
            for (Driver parent : Lists.reverse(parents)) {
                try {
                    return parent.createBehaviour(handler, behaviourClass);
                } catch (IllegalArgumentException e) {
                    log.debug("Parent {} does not support behaviour {}", parent, 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("parents", parents)
                .add("manufacturer", manufacturer)
                .add("hwVersion", hwVersion)
                .add("swVersion", swVersion)
                .add("behaviours", behaviours)
                .add("properties", properties)
                .toString();
    }

    @Override
    public boolean equals(Object driverToBeCompared) {
        if (this == driverToBeCompared) {
            return true;
        }
        if (driverToBeCompared == null || getClass() != driverToBeCompared.getClass()) {
            return false;
        }

        DefaultDriver driver = (DefaultDriver) driverToBeCompared;

        return name.equals(driver.name());

    }

    @Override
    public int hashCode() {
        return Objects.hashCode(name);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy