at.tuwien.minimee.registry.ToolRegistry.java Source code

Java tutorial

Introduction

Here is the source code for at.tuwien.minimee.registry.ToolRegistry.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2010 Vienna University of Technology, 
 * Department of Software Technology and Interactive Systems
 *
 * All rights reserved. This program and the accompanying
 * materials are made available under the terms of the
 * Apache License, Version 2.0 which accompanies
 * this distribution, and is available at
 * http://www.apache.org/licenses/LICENSE-2.0 
 *******************************************************************************/
package at.tuwien.minimee.registry;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.digester.Digester;
import org.apache.commons.logging.Log;

import at.tuwien.minimee.migration.engines.IMigrationEngine;
import at.tuwien.minimee.migration.engines.MultipleMonitoringMigrationEngine;
import at.tuwien.minimee.migration.evaluators.IMinimeeEvaluator;
import at.tuwien.minimee.model.ExperienceBase;
import at.tuwien.minimee.model.Machine;
import at.tuwien.minimee.model.Tool;
import at.tuwien.minimee.model.ToolConfig;
import at.tuwien.minimee.registry.xml.EngineFactory;
import at.tuwien.minimee.registry.xml.EvaluatorFactory;
import eu.planets_project.pp.plato.model.ToolExperience;
import eu.planets_project.pp.plato.model.measurement.MeasurableProperty;
import eu.planets_project.pp.plato.model.measurement.Measurement;
import eu.planets_project.pp.plato.model.scales.FreeStringScale;
import eu.planets_project.pp.plato.model.scales.PositiveFloatScale;
import eu.planets_project.pp.plato.model.values.INumericValue;
import eu.planets_project.pp.plato.services.action.MigrationResult;
import eu.planets_project.pp.plato.util.PlatoLogger;
import eu.planets_project.pp.plato.xml.StrictErrorHandler;

/**
 * This is the internal side of MiniMEE - it contains all tools and configurations
 * that are exposed as services through {@link MiniMeeRegistry}
 * @author cbu
 *
 */
public class ToolRegistry {
    private static Log log = PlatoLogger.getLogger(ToolRegistry.class);

    private HashMap<String, ToolConfig> allToolConfigs = new HashMap<String, ToolConfig>();
    private HashMap<String, IMigrationEngine> allEngines = new HashMap<String, IMigrationEngine>();
    private HashMap<String, Machine> allMachines = new HashMap<String, Machine>();
    private HashMap<String, IMinimeeEvaluator> allEvaluators = new HashMap<String, IMinimeeEvaluator>();

    private HashMap<String, ToolConfig> benchmarkConfigs = new HashMap<String, ToolConfig>();

    private List<Long> timepads = new LinkedList<Long>();

    public void addTimePad(long time) {
        timepads.add(time);
    }

    /**
     * @param toolID
     * @return
     */
    public static String getToolKey(String toolID) {
        String key = "minimee/";
        String toolIdentifier = toolID.substring(toolID.indexOf(key) + key.length());
        return toolIdentifier;
    }

    /**
     * checks the timepad for being valid - if so, the measurement is added 
     * to the experience base.
     * Currently not exposed as a web service since minimee has been integrated
     * with Plato.
     */
    public synchronized boolean addExperience(long otp, String toolID, Measurement m) {
        if (!timepads.contains(otp)) {
            return false;
        } else {
            addExperience(toolID, m);
        }

        return true;
    }

    private ExperienceBase eb = new ExperienceBase();

    public Measurement addExperience(String config, Measurement m) {
        eb.addExperience(config, m);
        return eb.getAverage(config, m);
    }

    private double benchmarkScore = 1.0;

    public double calculateBenchmarkScore() {
        if (benchmarkConfigs.size() == 0)
            return 1.0;
        double score = 0.0;
        for (String config : benchmarkConfigs.keySet()) {
            ToolExperience ex = eb.getToolExperience(config);

            Measurement m = ex.getAverage(MigrationResult.MIGRES_ELAPSED_TIME_PER_MB);
            if (m != null) {
                INumericValue v = (INumericValue) m.getValue();
                score += v.value();
            }
        }
        return score / benchmarkConfigs.size() / 4000;
    }

    private List<Tool> tools = new ArrayList<Tool>();

    private static ToolRegistry me;

    public static ToolRegistry getInstance() {
        if (me == null) {
            me = new ToolRegistry("data/services/miniMEE-tool-configs.xml");
            me.init();
        }
        return me;
    }

    private static void addCreateScale(Digester digester, Class c) {
        String name = c.getName();
        name = name.substring(name.lastIndexOf(".") + 1);
        // XML elements should start with a lower case letter
        name = name.substring(0, 1).toLowerCase() + name.substring(1);
        // create a scale entry for this value
        String pattern = "*/property/" + name;
        digester.addObjectCreate(pattern, c);
        digester.addSetProperties(pattern);
        digester.addSetNext(pattern, "setScale");
    }

    private void init() {
        for (Tool t : tools) {
            for (ToolConfig c : t.getConfigs()) {
                allToolConfigs.put(c.getUrl(), c);
                if (c.isBenchmark()) {
                    benchmarkConfigs.put(c.getUrl(), c);
                }
            }
        }
        for (IMigrationEngine e : allEngines.values()) {
            if (e instanceof MultipleMonitoringMigrationEngine) {
                ((MultipleMonitoringMigrationEngine) e).initEngines();
            }
        }
        List<MeasurableProperty> props = me.getMeasurableProperties();
        log.info("MINIMEE: loaded tools, configs, engines, machines, measurableProperties: " + tools.size()
                + " tools, " + allToolConfigs.size() + " configs, " + benchmarkConfigs.size()
                + " of which are used for the benchmark, " + allEngines.size() + " engines, " + allMachines.size()
                + " machines, " + props.size() + " properties.");
        log.debug("Listing measurable properties...");
        for (MeasurableProperty p : props) {
            log.info(p.getName() + " - " + p.getScale().getDisplayName());
        }

    }

    public static void reload() {
        reload(false);
    }

    public static void reload(String localPath) {
        reload(localPath, true);
    }

    public static void reload(String localPath, boolean absolute) {
        me = new ToolRegistry(localPath, absolute);
        me.init();
    }

    public static void reload(boolean absolute) {
        reload("data/services/miniMEE-tool-configs.xml", absolute);
    }

    public void addTool(Tool t) {
        tools.add(t);
    }

    private ToolRegistry(String configFile, boolean useAbsoluteLoader) {
        load(configFile, useAbsoluteLoader);
    }

    private ToolRegistry(String configFile) throws IllegalArgumentException {
        load(configFile, false);
    }

    private void load(String configFile, boolean useAbsoluteLoader) throws IllegalArgumentException {
        if (useAbsoluteLoader) {
            InputStream in;
            try {
                in = new FileInputStream(new File(configFile));
                load(in);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                throw new IllegalArgumentException(
                        e.getMessage() + " - maybe caused by wrong filename? check: " + configFile);
            }

        } else {
            load(Thread.currentThread().getContextClassLoader().getResourceAsStream(configFile));
        }
    }

    private void load(InputStream config) throws IllegalArgumentException {
        Digester digester = new Digester();
        digester.setValidating(true);
        digester.setErrorHandler(new StrictErrorHandler());

        digester.push(this);
        digester.addObjectCreate("*/tool", Tool.class);
        digester.addSetProperties("*/tool");

        digester.addObjectCreate("*/config", ToolConfig.class);
        digester.addSetProperties("*/config");
        digester.addBeanPropertySetter("*/config/name", "name");
        digester.addBeanPropertySetter("*/config/executablePath", "executablePath");
        digester.addBeanPropertySetter("*/config/engineName", "engine");
        digester.addBeanPropertySetter("*/config/params", "params");
        digester.addBeanPropertySetter("*/config/inEnding", "inEnding");
        digester.addBeanPropertySetter("*/config/outEnding", "outEnding");
        digester.addBeanPropertySetter("*/config/noOutFile", "noOutFile");
        digester.addBeanPropertySetter("*/config/initialisationDir", "initialisationDir");
        digester.addCallMethod("*/config/evaluators/evaluator", "addEvaluator", 0);

        digester.addSetNext("*/config", "addConfig");
        digester.addSetNext("*/tool", "addTool");

        digester.addFactoryCreate("*/evaluators/evaluator", EvaluatorFactory.class);
        digester.addSetProperties("*/evaluators/evaluator");
        digester.addSetNext("*/evaluators/evaluator", "addEvaluator");

        //Digester engineDigester = new Digester();
        //        engineDigester.setValidating(true);
        //        engineDigester.setErrorHandler(new StrictErrorHandler());
        //        engineDigester.push(this);
        digester.addFactoryCreate("*/engine", EngineFactory.class);
        digester.addSetProperties("*/engine");
        digester.addObjectCreate("*/measurableProperties/property", MeasurableProperty.class);
        digester.addSetProperties("*/measurableProperties/property");

        addCreateScale(digester, PositiveFloatScale.class);
        addCreateScale(digester, FreeStringScale.class);

        digester.addSetNext("*/measurableProperties/property", "addProperty");
        digester.addCallMethod("*/includedEngine", "addEngineName", 0);
        digester.addCallMethod("*/nextEngine", "setNextEngineName", 0);

        digester.addSetNext("*/engine", "addEngine");

        digester.addObjectCreate("*/machine", Machine.class);
        digester.addSetProperties("*/machine");
        digester.addSetNext("*/machine", "addMachine");
        try {

            digester.setUseContextClassLoader(true);
            digester.setValidating(false);
            digester.parse(config);

            //            config = Thread.currentThread().getContextClassLoader().getResourceAsStream(configFile);
            //            engineDigester.setValidating(false);
            //            engineDigester.setUseContextClassLoader(true);            
            //            engineDigester.parse(config);

        } catch (Exception e) {
            log.error("Error in config file! ", e);
        }
    }

    public List<Tool> getTools() {
        return tools;
    }

    public static void main(String[] args) {
        reload("d:\\test.xml");
    }

    public List<IMigrationEngine> getMigrationEngines() {
        return null;
    }

    public void addMachine(Machine m) {
        allMachines.put(m.getId(), m);
    }

    public void addEngine(IMigrationEngine e) {
        allEngines.put(e.getName(), e);
    }

    public void addEvaluator(IMinimeeEvaluator e) {
        allEvaluators.put(e.getName(), e);
    }

    public HashMap<String, IMigrationEngine> getAllEngines() {
        return allEngines;
    }

    public void setAllEngines(HashMap<String, IMigrationEngine> allEngines) {
        this.allEngines = allEngines;
    }

    public HashMap<String, ToolConfig> getAllToolConfigs() {
        return allToolConfigs;
    }

    public void setAllToolConfigs(HashMap<String, ToolConfig> allTools) {
        this.allToolConfigs = allTools;
    }

    public ToolConfig getToolConfig(String id) {
        return allToolConfigs.get(id);
    }

    public IMigrationEngine getEngine(String name) {
        return allEngines.get(name);
    }

    public Machine getMachine(String name) {
        return allMachines.get(name);
    }

    public IMinimeeEvaluator getEvaluator(String name) {
        return allEvaluators.get(name);
    }

    public List<MeasurableProperty> getMeasurableProperties() {
        List<MeasurableProperty> l = new ArrayList<MeasurableProperty>();
        for (IMigrationEngine e : allEngines.values()) {
            for (MeasurableProperty p : e.getMeasurableProperties()) {
                if (!l.contains(p)) {
                    l.add(p);
                }
            }
        }
        return l;
    }

    public void setTools(List<Tool> tools) {
        this.tools = tools;
    }

    public double getBenchmarkScore() {
        return benchmarkScore;
    }

    public void setBenchmarkScore(double benchmarkScore) {
        this.benchmarkScore = benchmarkScore;
    }

    public ExperienceBase getEb() {
        return eb;
    }
}