de.Keyle.MyPet.api.util.service.ServiceManager.java Source code

Java tutorial

Introduction

Here is the source code for de.Keyle.MyPet.api.util.service.ServiceManager.java

Source

/*
 * This file is part of MyPet
 *
 * Copyright  2011-2016 Keyle
 * MyPet is licensed under the GNU Lesser General Public License.
 *
 * MyPet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * MyPet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package de.Keyle.MyPet.api.util.service;

import com.google.common.base.Optional;
import com.google.common.collect.ArrayListMultimap;
import de.Keyle.MyPet.MyPetApi;
import org.apache.commons.lang.ClassUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * The {@link ServiceManager} manages all interactions with other plugins. Services are stored by class and by the
 * interfaces they implement so they can also be retrieved by them. You can get instances of other plugins and check if
 * other plugins are active.
 */
public class ServiceManager {
    Map<Class<? extends ServiceContainer>, ServiceContainer> services = new HashMap<>();
    Map<String, ServiceContainer> serviceByName = new HashMap<>();

    ArrayListMultimap<Load.State, ServiceContainer> registeredServices = ArrayListMultimap.create();

    public void listServices() {
        MyPetApi.getLogger().info("Loaded services: " + serviceByName.keySet());
    }

    /**
     * register new services here. A service needs the {@link ServiceName} annotation to be accepted.
     *
     * @param serviceClass the service class
     */
    public void registerService(Class<? extends ServiceContainer> serviceClass) {
        Load.State loadingState = Load.State.OnEnable;
        if (serviceClass.isAnnotationPresent(Load.class)) {
            loadingState = serviceClass.getAnnotation(Load.class).value();
        }
        try {
            ServiceContainer service = serviceClass.newInstance();
            registeredServices.put(loadingState, service);
        } catch (Throwable e) {
            MyPetApi.getLogger()
                    .warning("Error occured while creating the " + serviceClass.getName() + " service.");
            e.printStackTrace();
        }
    }

    @SuppressWarnings("unchecked")
    private void registerService(ServiceContainer service) {
        boolean genericService = true;
        for (Object o : ClassUtils.getAllInterfaces(service.getClass())) {
            if (o != ServiceContainer.class && ServiceContainer.class.isAssignableFrom((Class) o)) {
                services.put((Class) o, service);
                genericService = false;
            }
        }
        for (Object o : ClassUtils.getAllSuperclasses(service.getClass())) {
            if (o != ServiceContainer.class && ServiceContainer.class.isAssignableFrom((Class) o)) {
                services.put((Class) o, service);
                genericService = false;
            }
        }
        if (genericService) {
            services.put(ServiceContainer.class, service);
        }
        serviceByName.put(service.getServiceName(), service);
        services.put(service.getClass(), service);
    }

    public void activate(Load.State state) {
        List<ServiceContainer> services = registeredServices.get(state);

        for (ServiceContainer service : services) {
            if (service.onEnable()) {
                registerService(service);
            }
        }

        registeredServices.removeAll(state);
    }

    public void disableServices() {
        for (ServiceContainer service : serviceByName.values()) {
            service.onEnable();
        }
    }

    /**
     * returns all services that inherit from a specific class/interface
     *
     * @param serviceClass class that implements from {@link ServiceContainer}
     * @return list of instances of the service class
     */
    @SuppressWarnings("unchecked")
    public <T extends ServiceContainer> List<T> getServices(Class<? extends T> serviceClass) {
        List<T> list = new ArrayList<>();

        for (ServiceContainer service : services.values()) {
            if (service.getClass().isAssignableFrom(serviceClass) && !list.contains(service)) {
                list.add((T) service);
            }
        }

        return list;
    }

    /**
     * returns if services that inherit from a specific class/interface are available
     *
     * @param serviceClass class that implements from {@link ServiceContainer}
     * @return if any service was found
     */
    public boolean hasServices(Class<? extends ServiceContainer> serviceClass) {
        return services.containsKey(serviceClass);
    }

    /**
     * returns the services of a specific class
     *
     * @param serviceClass class that implements from {@link ServiceContainer}
     * @return instance of the service class
     */
    @SuppressWarnings("unchecked")
    public <T extends ServiceContainer> Optional<T> getService(Class<? extends T> serviceClass) {
        return Optional.fromNullable((T) services.get(serviceClass));
    }

    /**
     * returns the services with a specific {@link ServiceName}
     *
     * @param name name of the plugin
     * @return instance of a service class associated with the plugin name
     */
    public Optional<ServiceContainer> getService(String name) {
        return Optional.fromNullable(serviceByName.get(name));
    }

    /**
     * returns if a services with a specific {@link ServiceName} is available
     *
     * @param name name of the plugin
     * @return if any service was found
     */
    public boolean isServiceActive(String name) {
        return serviceByName.containsKey(name);
    }

    /**
     * returns if a service that inherit from a specific class/interface is available
     *
     * @param serviceClass class that implements from {@link ServiceContainer}
     * @return if any service was found
     */
    public boolean isServiceActive(Class<? extends ServiceContainer> serviceClass) {
        return services.containsKey(serviceClass);
    }
}