<commit_before>package com.beolnix.marvin.plugins.providers.osgi;

import com.beolnix.marvin.config.api.ConfigurationProvider;
import com.beolnix.marvin.config.api.error.ConfigurationException;
import com.beolnix.marvin.config.api.model.Configuration;
import com.beolnix.marvin.config.api.model.PluginsSettings;
import com.beolnix.marvin.plugins.api.PluginsListener;
import com.beolnix.marvin.plugins.api.IMPlugin;
import com.beolnix.marvin.plugins.api.error.PluginsProviderConfigurationException;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.fileinstall.internal.DirectoryWatcher;
import org.apache.felix.framework.FrameworkFactory;
import org.apache.felix.main.AutoProcessor;
import org.apache.log4j.*;
import org.osgi.framework.*;
import org.osgi.framework.launch.Framework;

import static org.osgi.framework.FrameworkEvent.ERROR;
import static org.osgi.framework.FrameworkEvent.WARNING;

import java.io.File;
import java.util.*;

/**
 * Created by beolnix on 31/10/15.
 */
public class FelixOSGiContainer implements ServiceListener, FrameworkListener {

    // dependencies
    private final ConfigurationProvider configurationProvider;

    // state
    private Framework framework = null;
    private BundleContext bundleContext = null;
    private List<PluginsListener> pluginsListenerList = new ArrayList<>();
    final private List<IMPlugin> pluginList = new ArrayList<>();
    final private Map<String, Logger> pluginLoggersMap = new HashMap<>();

    // constants
    private final static Logger logger = Logger.getLogger(FelixOSGiContainer.class);

    private FelixOSGiContainer(ConfigurationProvider configurationProvider) {
        this.configurationProvider = configurationProvider;
    }

    public static FelixOSGiContainer createNewInstance(ConfigurationProvider configurationProvider) throws ConfigurationException {
        try {
            FelixOSGiContainer felixOSGiContainer = new FelixOSGiContainer(configurationProvider);
            felixOSGiContainer.checkConfiguration();
            felixOSGiContainer.initFramework();
            return felixOSGiContainer;
        } catch (PluginsProviderConfigurationException e) {
            throw new ConfigurationException(e);
        }
    }

    private void checkConfiguration() throws PluginsProviderConfigurationException {
        try {
            Configuration configuration = configurationProvider.getConfiguration();
            checkForWritable(configuration.getPluginSettings().getCachePath(), "cachePath");
            checkForWritable(configuration.getPluginSettings().getSystemDeployPath(), "systemDeployPath");
            checkForWritable(configuration.getPluginSettings().getPluginsDeployPath(), "pluginsDeployPath");
            checkForWritable(configuration.getPluginSettings().getLogsPath(), "logsPath");
            checkForWritable(configuration.getPluginSettings().getDirPath(), "dirPath");
        } catch (ConfigurationException e) {
            throw new PluginsProviderConfigurationException(e);
        }
    }

    private void checkForWritable(String dirPath, String dirName) throws PluginsProviderConfigurationException {
        if (StringUtils.isBlank(dirPath))
            throw new PluginsProviderConfigurationException(dirName + " must be provided");

        File file = new File(dirPath);
        if (!file.exists()) {
            file.mkdirs();
        }

        if (!file.isDirectory() || !file.canWrite())
            throw new PluginsProviderConfigurationException("can't write to dir with path: " + file.getAbsolutePath());
    }

    @Override
    public void serviceChanged(ServiceEvent event) {
        if (event.getType() == ServiceEvent.REGISTERED) {
            ServiceReference ref = event.getServiceReference();
            Object testObject = bundleContext.getService(ref);
            if (testObject instanceof IMPlugin) {
                IMPlugin newIMPlugin = (IMPlugin) bundleContext.getService(ref);
                synchronized (pluginList) {
                    pluginList.add(newIMPlugin);
                }
                for (PluginsListener pluginsListener : pluginsListenerList) {
                    pluginsListener.deployPlugin(newIMPlugin);
                }

                logger.info("registered new plugin: " + newIMPlugin.getPluginName());
            }
        } else if (event.getType() == ServiceEvent.UNREGISTERING) {
            ServiceReference ref = event.getServiceReference();
            Object testObject = bundleContext.getService(ref);
            if (testObject instanceof IMPlugin) {
                IMPlugin imPlugin = (IMPlugin) bundleContext.getService(ref);
                synchronized (pluginList) {
                    pluginList.remove(imPlugin);
                }
                for (PluginsListener pluginsListener : pluginsListenerList) {
                    pluginsListener.undeployPlugin(imPlugin);
                }

                logger.info("unregistered IMPlugin: " + imPlugin.getPluginName());
            }
        }
    }

    @Override
    public void frameworkEvent(FrameworkEvent event) {
        switch (event.getType()) {
            case ERROR:
                if (event.getThrowable() != null) {
                    logger.error(event.getThrowable().getMessage(), event.getThrowable());
                    pluginsListenerList.forEach(l -> l.onError(event.getThrowable()));
                } else if (event.getBundle() != null) {
                    logger.error("Boundle '" + event.getBundle().getSymbolicName() +
                            "' has been stopped because of the error.");
                }
                break;
            case WARNING:
                if (event.getThrowable() != null) {
                    logger.error(event.getThrowable().getMessage(), event.getThrowable());
                } else if (event.getBundle() != null) {
                    logger.error("Boundle '" + event.getBundle().getSymbolicName() +
                            "' has been stopped because of the error.");
                }
                break;
            default:
                if (event.getThrowable() != null) {
                    logger.error(event.getThrowable().getMessage(), event.getThrowable());
                }
                break;
        }
    }


    private Properties getConfig() throws PluginsProviderConfigurationException {
        PluginsSettings ps = null;
        try {
            ps = configurationProvider.getPluginSettings();
        } catch (ConfigurationException e) {
            throw new PluginsProviderConfigurationException(e);
        }<commit_msg>adopt FelixOSGiContainer to changes in API 0.2<commit_after>package com.beolnix.marvin.plugins.providers.osgi;

import com.beolnix.marvin.config.api.ConfigurationProvider;
import com.beolnix.marvin.config.api.error.ConfigurationException;
import com.beolnix.marvin.config.api.model.Configuration;
import com.beolnix.marvin.config.api.model.PluginsSettings;
import com.beolnix.marvin.plugins.api.PluginsListener;
import com.beolnix.marvin.plugins.api.IMPlugin;
import com.beolnix.marvin.plugins.api.error.PluginsProviderConfigurationException;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.fileinstall.internal.DirectoryWatcher;
import org.apache.felix.framework.FrameworkFactory;
import org.apache.felix.main.AutoProcessor;
import org.apache.log4j.*;
import org.osgi.framework.*;
import org.osgi.framework.launch.Framework;

import static org.osgi.framework.FrameworkEvent.ERROR;
import static org.osgi.framework.FrameworkEvent.WARNING;

import java.io.File;
import java.util.*;

/**
 * Created by beolnix on 31/10/15.
 */
public class FelixOSGiContainer implements ServiceListener, FrameworkListener {

    // dependencies
    private final ConfigurationProvider configurationProvider;

    // state
    private Framework framework = null;
    private BundleContext bundleContext = null;
    private List<PluginsListener> pluginsListenerList = new ArrayList<>();
    final private List<IMPlugin> pluginList = new ArrayList<>();
    final private Map<String, Logger> pluginLoggersMap = new HashMap<>();

    // constants
    private final static Logger logger = Logger.getLogger(FelixOSGiContainer.class);

    private FelixOSGiContainer(ConfigurationProvider configurationProvider) {
        this.configurationProvider = configurationProvider;
    }

    public static FelixOSGiContainer createNewInstance(ConfigurationProvider configurationProvider) throws ConfigurationException {
        try {
            FelixOSGiContainer felixOSGiContainer = new FelixOSGiContainer(configurationProvider);
            felixOSGiContainer.checkConfiguration();
            felixOSGiContainer.initFramework();
            return felixOSGiContainer;
        } catch (PluginsProviderConfigurationException e) {
            throw new ConfigurationException(e);
        }
    }

    private void checkConfiguration() throws PluginsProviderConfigurationException {
        try {
            Configuration configuration = configurationProvider.getConfiguration();
            checkForWritable(configuration.getPluginSettings().getCachePath(), "cachePath");
            checkForWritable(configuration.getPluginSettings().getSystemDeployPath(), "systemDeployPath");
            checkForWritable(configuration.getPluginSettings().getPluginsDeployPath(), "pluginsDeployPath");
            checkForWritable(configuration.getPluginSettings().getLogsPath(), "logsPath");
            checkForWritable(configuration.getPluginSettings().getDirPath(), "dirPath");
        } catch (ConfigurationException e) {
            throw new PluginsProviderConfigurationException(e);
        }
    }

    private void checkForWritable(String dirPath, String dirName) throws PluginsProviderConfigurationException {
        if (StringUtils.isBlank(dirPath))
            throw new PluginsProviderConfigurationException(dirName + " must be provided");

        File file = new File(dirPath);
        if (!file.exists()) {
            file.mkdirs();
        }

        if (!file.isDirectory() || !file.canWrite())
            throw new PluginsProviderConfigurationException("can't write to dir with path: " + file.getAbsolutePath());
    }

    @Override
    public void serviceChanged(ServiceEvent event) {
        if (event.getType() == ServiceEvent.REGISTERED) {
            ServiceReference ref = event.getServiceReference();
            Object testObject = bundleContext.getService(ref);
            if (testObject instanceof IMPlugin) {
                IMPlugin newIMPlugin = (IMPlugin) bundleContext.getService(ref);
                synchronized (pluginList) {
                    pluginList.add(newIMPlugin);
                }
                for (PluginsListener pluginsListener : pluginsListenerList) {
                    pluginsListener.deployPlugin(newIMPlugin);
                }

                logger.info("registered new plugin: " + newIMPlugin.getPluginName());
            }
        } else if (event.getType() == ServiceEvent.UNREGISTERING) {
            ServiceReference ref = event.getServiceReference();
            Object testObject = bundleContext.getService(ref);
            if (testObject instanceof IMPlugin) {
                IMPlugin imPlugin = (IMPlugin) bundleContext.getService(ref);
                synchronized (pluginList) {
                    pluginList.remove(imPlugin);
                }
                for (PluginsListener pluginsListener : pluginsListenerList) {
                    pluginsListener.undeployPlugin(imPlugin);
                }

                logger.info("unregistered IMPlugin: " + imPlugin.getPluginName());
            }
        }
    }

    @Override
    public void frameworkEvent(FrameworkEvent event) {
        switch (event.getType()) {
            case ERROR:
                if (event.getThrowable() != null) {
                    logger.error(event.getThrowable().getMessage(), event.getThrowable());
                    pluginsListenerList.forEach( e -> {
                        if (event.getBundle() != null) {
                            e.onError(event.getBundle().getSymbolicName(), event.getThrowable());
                        } else {
                            e.onError("Undefined bundle.", event.getThrowable());
                        }
                    });
                } else if (event.getBundle() != null) {
                    logger.error("Boundle '" + event.getBundle().getSymbolicName() +
                            "' has been stopped because of the error.");
                }
                break;
            case WARNING:
                if (event.getThrowable() != null) {
                    logger.error(event.getThrowable().getMessage(), event.getThrowable());
                } else if (event.getBundle() != null) {
                    logger.error("Boundle '" + event.getBundle().getSymbolicName() +
                            "' has been stopped because of the error.");
                }
                break;
            default:
                if (event.getThrowable() != null) {
                    logger.error(event.getThrowable().getMessage(), event.getThrowable());
                }
                break;
        }
    }


    private Properties getConfig() throws PluginsProviderConfigurationException {
        PluginsSettings ps = null;
        try {
            ps = configurationProvider.getPluginSettings();
        } catch (ConfigurationException e) {
            throw new PluginsProviderConfigurationException(e);
        }
{'fraction_non_alphanumeric': 0.09452479338842976, 'fraction_numerical': 0.0011806375442739079, 'mean_word_length': 2.522089397089397, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2411264', 'n_tokens_mistral': 3359, 'n_tokens_neox': 3192, 'n_words': 645}