de.dkfz.roddy.config.Configuration.java Source code

Java tutorial

Introduction

Here is the source code for de.dkfz.roddy.config.Configuration.java

Source

/*
 * Copyright (c) 2016 eilslabs.
 *
 * Distributed under the MIT License (license terms are at https://www.github.com/eilslabs/Roddy/LICENSE.txt).
 */

package de.dkfz.roddy.config;

import de.dkfz.roddy.core.ProjectFactory;
import de.dkfz.roddy.tools.RoddyIOHelperMethods;
import de.dkfz.roddy.config.validation.ConfigurationValidationError;
import de.dkfz.roddy.core.ExecutionContext;
import de.dkfz.roddy.plugins.LibrariesFactory;
import de.dkfz.roddy.plugins.PluginInfo;
import org.apache.commons.io.filefilter.WildcardFileFilter;

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

import static de.dkfz.roddy.StringConstants.SPLIT_COMMA;

/**
 * A configuration stores maps of different types:
 * - configuration values / value bundles
 * - basepaths
 * - tool entries
 * - enumerations
 * - filename patterns
 * <p/>
 * A configuration can import from other configurations (only first configurationType of file)
 * A configuration can inherit from other configurations
 *
 * @author michael
 */
public class Configuration implements ContainerParent<Configuration> {

    /**
     * Several levels of configurations.
     * Do not change the order of this! It is queried and compared several times.
     */
    public enum ConfigurationType {
        /**
         * Unknown / Unset
         */
        UNSET,
        /**
         * Other configurations (i.e. definition of filenames, tools)
         */
        OTHER,
        /**
         * For the definition of workflows.
         */
        ANALYSIS,
        /**
         * For the definition of projects
         */
        PROJECT
    }

    private static final de.dkfz.roddy.tools.LoggerWrapper logger = de.dkfz.roddy.tools.LoggerWrapper
            .getLogger(Configuration.class.getSimpleName());
    /**
     * The prototype with basic information about this configuration
     */
    protected final InformationalConfigurationContent informationalConfigurationContent;
    private final List<Configuration> parents = new LinkedList<>();

    private final Map<String, Configuration> subConfigurations = new LinkedHashMap<>();

    private List<ConfigurationValidationError> listOfValidationErrors = new LinkedList<>();
    private List<ConfigurationLoadError> listOfLoadErrors = new LinkedList<>();

    private final RecursiveOverridableMapContainerForConfigurationValues configurationValues = new RecursiveOverridableMapContainerForConfigurationValues(
            this, "configurationValues");

    /**
     * Bundles store values with the same name for the same configuration.
     * This can sometimes be necessary. So you do not need a sub configuration for each different set of
     * values.
     */
    private final RecursiveOverridableMapContainer<String, ConfigurationValueBundle, Configuration> configurationValueBundles = new RecursiveOverridableMapContainer<>(
            this, "configurationValueBundles");

    private final RecursiveOverridableMapContainer<String, ToolEntry, Configuration> tools = new RecursiveOverridableMapContainer<>(
            this, "tools");

    private final RecursiveOverridableMapContainer<String, Enumeration, Configuration> enumerations = new RecursiveOverridableMapContainer<>(
            this, "enumerations");

    private RecursiveOverridableMapContainer<String, FilenamePattern, Configuration> filenamePatterns = new RecursiveOverridableMapContainer<>(
            this, "filenamePatterns");

    /**
     * Creates a new configuration which can be filled by filling the containers.
     */
    public Configuration(InformationalConfigurationContent icc) {
        this.informationalConfigurationContent = icc;
    }

    /**
     * For main configurations
     * Read reversly
     * Remember to set the parent config afterwards.
     * With this configuration no dependency tree is created!
     */
    public Configuration(InformationalConfigurationContent informationalConfigurationContent,
            Configuration parentConfig) {
        this.informationalConfigurationContent = informationalConfigurationContent;
        this.addParent(parentConfig);
    }

    /**
     * For main configurations
     */
    public Configuration(InformationalConfigurationContent informationalConfigurationContent,
            Map<String, Configuration> subConfigurations) {
        this.informationalConfigurationContent = informationalConfigurationContent;
        if (subConfigurations != null) {
            this.subConfigurations.putAll(subConfigurations);
        }
    }

    public InformationalConfigurationContent getInformationalConfigurationContent() {
        return informationalConfigurationContent;
    }

    public List<String> getImportConfigurations() {
        if (informationalConfigurationContent.imports.trim().length() == 0)
            return new LinkedList<String>();
        return Arrays.asList(informationalConfigurationContent.imports.trim().split(SPLIT_COMMA));
    }

    public ConfigurationType getConfigurationLevel() {
        return informationalConfigurationContent.type;
    }

    public void removeFilenamePatternsRecursively() {
        this.filenamePatterns = new RecursiveOverridableMapContainer<>(this, "filenamePatterns");
        for (Configuration parent : parents) {
            parent.removeFilenamePatternsRecursively();
        }
    }

    public RecursiveOverridableMapContainer<String, FilenamePattern, Configuration> getFilenamePatterns() {
        return filenamePatterns;
    }

    public RecursiveOverridableMapContainer<String, ToolEntry, Configuration> getTools() {
        return tools;
    }

    public RecursiveOverridableMapContainer<String, Enumeration, Configuration> getEnumerations() {
        return enumerations;
    }

    public RecursiveOverridableMapContainerForConfigurationValues getConfigurationValues() {
        return configurationValues;
    }

    public RecursiveOverridableMapContainer<String, ConfigurationValueBundle, Configuration> getConfigurationValueBundles() {
        return configurationValueBundles;
    }

    /**
     * Returns the name of this configuration
     *
     * @return
     */
    public String getName() {
        return informationalConfigurationContent.name;
    }

    /**
     * Returns the id / path of this configuration like prostate.subproject
     *
     * @return
     */
    @Override
    public String getID() {
        return informationalConfigurationContent.id;
    }

    public String getDescription() {
        return informationalConfigurationContent.description;
    }

    public String getConfiguredClass() {
        return informationalConfigurationContent.className;
    }

    public ResourceSetSize getResourcesSize() {
        if (configurationValues.hasValue(ConfigurationConstants.CFG_USED_RESOURCES_SIZE)) {
            return ResourceSetSize.valueOf(
                    configurationValues.getValue(ConfigurationConstants.CFG_USED_RESOURCES_SIZE).toString());
        }
        return informationalConfigurationContent.usedresourcessize;
    }

    /**
     * If the configuration is a project configuration then the name of the project will be returned.
     * Variants do not alter the project name and use the name of the first project found in their parents.
     * If the project name is not set this returns the configurations simple name (i.e. project, but not qcpipeline.project)
     * TODO: Implement and verify rules: A project can extend a project and a workflow. A variant can extend a project or a variant.
     *
     * @return The projects name or null.
     */
    public String getProjectName() {
        //Search the configuration from which to take the name.
        String projectName = null;
        if (this.getConfigurationLevel() == ConfigurationType.PROJECT) {
            projectName = configurationValues.get("projectName", getName()).toString();
        } else if (this.informationalConfigurationContent.type.ordinal() < ConfigurationType.PROJECT.ordinal()) {
            //This is not a project configuration and not a variant.
        } else if (this.informationalConfigurationContent.type.ordinal() > ConfigurationType.PROJECT.ordinal()) {
            //Return the parents getProjectName(). This is recursive and should lead to the project configuration.
            String tempName = null;
            for (Configuration parent : parents) {
                String tName = parent.getProjectName();
                if (tName == null) {
                    continue;
                }
                tempName = tName;
                break;
            }

            projectName = tempName;
        }

        // Return the value and if not set the name of the config.
        return projectName;
    }

    public List<Configuration> getContainerParents() {
        return parents;
    }

    @Override
    public RecursiveOverridableMapContainer getContainer(String id) {
        if (configurationValues.is(id)) {
            return configurationValues;
        } else if (configurationValueBundles.is(id)) {
            return configurationValueBundles;
        } else if (tools.is(id)) {
            return tools;
        } else if (enumerations.is(id)) {
            return enumerations;
        } else if (filenamePatterns.is(id)) {
            return filenamePatterns;
        }
        return null;
    }

    public void setParent(Configuration c) {
        parents.clear();
        parents.add(c);
    }

    public void addParent(Configuration p) {
        if (p == null)
            return;
        if (!parents.contains(p))
            parents.add(p);
    }

    public Map<String, Configuration> getSubConfigurations() {
        return subConfigurations;
    }

    public List<Configuration> getListOfSubConfigurations() {
        return new LinkedList<Configuration>(subConfigurations.values());
    }

    public File getSourceBrawlWorkflow(String brawlName) {
        List<PluginInfo> pluginInfos = LibrariesFactory.getInstance().getLoadedPlugins();
        Map<String, File> availableBasePaths = new LinkedHashMap<>();
        List<File> allFiles = new LinkedList<>();
        for (PluginInfo pluginInfo : pluginInfos) {
            File[] files = pluginInfo.getBrawlWorkflowDirectory()
                    .listFiles((FileFilter) new WildcardFileFilter(brawlName + ".brawl"));
            if (files != null && files.length > 0)
                allFiles.addAll(Arrays.asList(files));
        }
        if (allFiles.size() == 1)
            return allFiles.get(0);
        logger.severe("Too many braw workflows called " + brawlName);
        return null;
    }

    public File getSourceToolPath(String tool) {
        List<PluginInfo> pluginInfos = LibrariesFactory.getInstance().getLoadedPlugins();
        Map<String, File> availableBasePaths = new LinkedHashMap<>();
        for (PluginInfo pluginInfo : pluginInfos) {
            availableBasePaths.putAll(pluginInfo.getToolsDirectories());
        }

        ToolEntry te = tools.getValue(tool);
        if (te.basePathId.length() > 0 && !availableBasePaths.containsKey(te.basePathId)) {
            throw new RuntimeException("Base path for tool " + tool + " is not configured");
        }
        File bPath = availableBasePaths.get(te.basePathId);

        Map<String, String> localPath = new LinkedHashMap<>();
        localPath.put(ConfigurationConstants.CVALUE_PLACEHOLDER_EXECUTION_DIRECTORY, ".");
        File toolPath = new File(bPath.getAbsolutePath(), te.path);
        return toolPath;
    }

    public File getProcessingToolPath(ExecutionContext context, String tool) {
        ToolEntry te = tools.getValue(tool);
        File toolPath = new File(
                new File(new File(context.getExecutionDirectory(), "analysisTools"), te.basePathId), te.path);
        return toolPath;
    }

    public String getProcessingToolMD5(String tool) {
        if (tool == null || tool == "") {
            logger.warning("Tool id not correctly specified for md5 query.");
            return "";
        }
        File sourceToolPath = getSourceToolPath(tool);
        return RoddyIOHelperMethods.getMD5OfFile(sourceToolPath);
    }

    public boolean getPreventJobExecution() {
        return configurationValues.getBoolean(ConfigurationConstants.CFG_PREVENT_JOB_EXECUTION);
    }

    public void disableJobExecution() {
        configurationValues.add(new ConfigurationValue(ConfigurationConstants.CFG_PREVENT_JOB_EXECUTION, "true"));
    }

    public boolean getUseCentralAnalysisArchive() {
        return configurationValues.getBoolean(ConfigurationConstants.CFG_USE_CENTRAL_ANALYSIS_ARCHIVE, true);
    }

    public String getSSHExecutionUser() {
        return configurationValues.get(ConfigurationFactory.XMLTAG_EXECUTIONSERVICE_SSHUSER).toString();
    }

    public boolean getShowSSHCalls() {
        return configurationValues.getBoolean(ConfigurationFactory.XMLTAG_EXECUTIONSERVICE_SHOW_SSHCALLS);
    }

    @Override
    public String toString() {
        return String.format("Configuration %s / %s of type %s", getName(), getID(), getClass().getName());
    }

    //
    //    public FilenamePattern getFilenamePattern(BaseFile cls, BaseFile derivedFromCls) {
    //        Class _cls = cls.getClass();
    //        Class _derivedFromCls = derivedFromCls.getClass();
    //        FilenamePattern pattern = getFilenamePattern(FilenamePattern.assembleID(_cls, _derivedFromCls));
    //        return pattern;
    //    }
    //
    //    public FilenamePattern getFilenamePattern(BaseFile newFile, FileStage stage) {
    //        Class cls = newFile.getClass();
    //        FilenamePattern pattern = getFilenamePattern(FilenamePattern.assembleID(cls, stage));
    //        return pattern;
    //    }
    public void addValidationError(ConfigurationValidationError error) {
        this.listOfValidationErrors.add(error);
    }

    public void addLoadError(ConfigurationLoadError error) {
        this.listOfLoadErrors.add(error);
    }

    public List<ConfigurationLoadError> getListOfLoadErrors() {
        LinkedList<ConfigurationLoadError> errors = new LinkedList<>();
        for (Configuration c : parents) {
            errors.addAll(c.getListOfLoadErrors());
        }
        errors.addAll(listOfLoadErrors);
        return errors;
    }

    public boolean isInvalid() {
        return this.listOfValidationErrors.size() > 0;
    }

    //    /**
    //     * Integrates another configuration without overriding existing values.
    //     *
    //     * @param cfg
    //     */
    //    public void integrate(Configuration cfg, boolean completeHierarchy) {
    //        ConfigurationFactory.integrateConfig(cfg, this, completeHierarchy);
    //    }

}