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

net.e6tech.elements.common.launch.LaunchController Maven / Gradle / Ivy

There is a newer version: 2.7.9
Show newest version
/*
 * Copyright 2015-2019 Futeh Kao
 *
 * 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 net.e6tech.elements.common.launch;

import net.e6tech.elements.common.resources.*;

import java.util.*;
import java.util.concurrent.CountDownLatch;

/**
 * Created by futeh.
 */
public class LaunchController implements LaunchListener {
    private static Map provisions = new HashMap<>();
    private Properties properties = new Properties();
    private List listeners = new LinkedList<>();
    private List arguments = new ArrayList<>();
    private ResourceManager resourceManager;
    private CountDownLatch latch;
    private ResourceManagerBuilder resourceManagerBuilder = ResourceManager::new;
    private ScriptLoader scriptLoader = ResourceManager::load;

    public LaunchController() {
        property("home", System.getProperty("home", System.getProperty("user.dir")));
        property("env", System.getProperty("env", "dev"));
        properties.put("args", arguments);
    }

    protected LaunchController(Properties properties) {
        this.properties.putAll(properties);
        this.properties.put("args", arguments);
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public ResourceManager getResourceManager() {
        return resourceManager;
    }

    public LaunchController property(String property, Object value) {
        if (value == null)
            return this;
        properties.put(property, value);
        return this;
    }

    public LaunchController properties(Map map) {
        properties.putAll(map);
        return this;
    }

    public void addProperties(Properties properties) {
        this.properties.putAll(properties);
    }

    public String getProperty(String key) {
        return this.properties.getProperty(key);
    }

    public String getLaunchScript() {
        return properties.getProperty("launch");
    }

    public void setLaunchScript(String launchScript) {
        properties.setProperty("launch", launchScript);
    }

    public List getArguments() {
        return arguments;
    }

    public void setArguments(List arguments) {
        this.arguments.clear();
        this.arguments.addAll(arguments);
    }

    public void addArgument(String arg) {
        arguments.add(arg);
    }

    public ResourceManagerBuilder getResourceManagerBuilder() {
        return resourceManagerBuilder;
    }

    public void setResourceManagerBuilder(ResourceManagerBuilder resourceManagerBuilder) {
        Objects.requireNonNull(resourceManagerBuilder);
        this.resourceManagerBuilder = resourceManagerBuilder;
    }

    public ScriptLoader getScriptLoader() {
        return scriptLoader;
    }

    public void setScriptLoader(ScriptLoader scriptLoader) {
        Objects.requireNonNull(scriptLoader);
        this.scriptLoader = scriptLoader;
    }

    public LaunchController launchScript(String launchScript) {
        setLaunchScript(launchScript);
        return this;
    }

    public LaunchController addLaunchListener(LaunchListener listener) {
        listeners.add(listener);
        return this;
    }

    public LaunchController removeLaunchListener(LaunchListener listener) {
        listeners.remove(listener);
        return this;
    }

    public LaunchController addCreatedListener(CreatedListener listener) {
        listeners.add(listener);
        return this;
    }

    // listener for catching when both env variables and system properties are defined.
    public LaunchController addBootstrapEndVariables(BootstrapSystemPropertiesListener listener) {
        addCreatedListener(rm ->
                rm.getBootstrap().addBootstrapSystemPropertiesListener(listener));
        return this;
    }

    // Almost same as addBootstrapEndVariables but after various boot list are configured.
    public LaunchController addBootstrapEndEnv(BootstrapEndEnv listener) {
        addCreatedListener(rm ->
            rm.getBootstrap().addBootstrapEndEnv(listener));
        return this;
    }

    public LaunchController evalAfterCreated(String script) {
        return addCreatedListener(rm -> rm.eval(script));
    }

    public LaunchController removeCreatedListener(CreatedListener listener) {
        listeners.remove(listener);
        return this;
    }

    public LaunchController inject(Object object) {
        if (provisions.get(getLaunchScript()) != null) {
            provisions.get(getLaunchScript()).inject(object);
        } else {
            addLaunchListener(provision -> provision.inject(object));
        }
        return this;
    }

    @Override
    public void created(ResourceManager rm) {
        for (LaunchListener listener : listeners)
            listener.created(rm);
    }

    @Override
    public void launched(Provision provision) {
        provisions.put(getLaunchScript(), provision);
        for (LaunchListener listener : listeners)
            listener.launched(provision);

        resourceManager.onLaunched();
    }

    public LaunchController launch() {
        String launchScript = getLaunchScript();
        if (provisions.containsKey(launchScript))
            return this;
        (new Launch(this)).launch();
        return this;
    }

    public CountDownLatch getLatch() {
        return latch;
    }

    public void setLatch(CountDownLatch latch) {
        this.latch = latch;
    }

    public ResourceManager initResourceManager() {
        if (resourceManager == null) {
            resourceManager = resourceManagerBuilder.build(getProperties());
            created(resourceManager);
        }
        return resourceManager;
    }

    @SuppressWarnings({"squid:S2274", "squid:CommentedOutCodeLine", "squid:S106", "squid:S1148"})
    public void launch(List listeners ) {
        String file = getLaunchScript();
        if (file == null)
            throw new IllegalArgumentException("launch file not specified, use launch=");

        initResourceManager();
        listeners.forEach(listener -> listener.created(resourceManager));
        try {
            scriptLoader.load(resourceManager, file);
            resourceManager.onShutdown("LaunchController " + getLaunchScript(), notification -> provisions.remove(getLaunchScript()));
        } catch (Exception e) {
            e.printStackTrace(); // we cannot use Logger yet
            System.exit(1);
        }

        latch.countDown();

        // if ShutdownNotification is detected, this code will call resourceManager.notifyAll in order
        // to break out of the next synchronized block that contains resourceManager.wait.
        resourceManager.addResourceProvider(ResourceProvider.wrap("Launcher", (OnShutdown) () -> {
            synchronized (resourceManager) {
                resourceManager.notifyAll();
            }
        }));

        Thread thread = new Thread(() -> {
            // wait on resourceManager ... if ShutdownNotification is detected, the code just above will break out of
            // the wait.
            synchronized (resourceManager) {
                try {
                    resourceManager.wait();
                    System.out.println("Launcher thread stopped");  // we cannot use Logger yet
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        thread.setDaemon(false);
        thread.start();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy