fr.inria.atlanmod.instantiator.neoEMF.Launcher.java Source code

Java tutorial

Introduction

Here is the source code for fr.inria.atlanmod.instantiator.neoEMF.Launcher.java

Source

/*******************************************************************************
 * Copyright (c) 2015 Abel Gmez (AtlanMod) 
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Abel Gomez (AtlanMod) - Additional modifications
 *     Amine Benelallam (AtlanMod) - Adaptation for NoeEMF/HBase      
 *******************************************************************************/

package fr.inria.atlanmod.instantiator.neoEMF;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.MessageFormat;
import java.util.Comparator;
import java.util.logging.Logger;

import jline.Terminal;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.Range;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;

import fr.inria.atlanmod.neoemf.core.NeoEMFResourceFactory;
import fr.inria.atlanmod.neoemf.util.NeoEMFURI;

/**
 *  
 * @author <a href="mailto:abel.gomez-llana@inria.fr">Abel Gomez</a>
 * @author <a href="mailto:amine.benelallam@inria.fr">Amine Benelallam</a>
 *
 */

public class Launcher {

    private final static Logger LOGGER = Logger.getLogger(Launcher.class.getName());

    private static final int DEFAULT_AVERAGE_MODEL_SIZE = 1000;
    private static final float DEFAULT_DEVIATION = 0.1f;

    private static final int ERROR = 1;

    private static final String E_PACKAGE_CLASS = "c";
    private static final String E_PACKAGE_CLASS_LONG = "package";
    private static final String OUTPUT_PATH = "u";
    private static final String OUTPUT_PATH_LONG = "suffixe";
    private static final String N_MODELS = "n";
    private static final String N_MODELS_LONG = "number-models";
    private static final String SIZE = "s";
    private static final String SIZE_LONG = "size";
    private static final String VARIATION = "p";
    private static final String VARIATION_LONG = "variation";
    private static final String PROP_VARIATION = "v";
    private static final String PROP_VARIATION_LONG = "properties-variation";
    private static final String DEGREE = "d";
    private static final String DEGREE_LONG = "references-degree";
    private static final String VALUES_SIZE = "z";
    private static final String VALUES_SIZE_LONG = "values-size";
    private static final String SEED = "e";
    private static final String SEED_LONG = "seed";
    private static final String FORCE = "f";
    private static final String FORCE_LONG = "force";
    private static final String DIAGNOSE = "g";
    private static final String DIAGNOSE_LONG = "diagnose";

    private static class OptionComarator<T extends Option> implements Comparator<T> {
        private static final String OPTS_ORDER = "eunspdzefg";

        @Override
        public int compare(T o1, T o2) {
            return OPTS_ORDER.indexOf(o1.getOpt()) - OPTS_ORDER.indexOf(o2.getOpt());
        }
    }

    public static void main(String[] args) throws GenerationException, IOException {

        ResourceSetImpl resourceSet = new ResourceSetImpl();
        { // initializing the registry

            resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(EcorePackage.eNS_PREFIX,
                    new EcoreResourceFactoryImpl());
            resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap()
                    .put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());
            resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put(NeoEMFURI.NEOEMF_HBASE_SCHEME,
                    NeoEMFResourceFactory.eINSTANCE);

        }

        Options options = new Options();

        configureOptions(options);

        CommandLineParser parser = new GnuParser();

        try {
            CommandLine commandLine = parser.parse(options, args);

            String epackage_class = commandLine.getOptionValue(E_PACKAGE_CLASS);

            LOGGER.info("Start loading the package");
            Class<?> inClazz = Launcher.class.getClassLoader().loadClass(epackage_class);
            EPackage _package = (EPackage) inClazz.getMethod("init").invoke(null);

            Resource metamodelResource = new XMIResourceImpl(URI.createFileURI("dummy"));
            metamodelResource.getContents().add(_package);
            LOGGER.info("Finish loading the package");

            int size = Launcher.DEFAULT_AVERAGE_MODEL_SIZE;
            if (commandLine.hasOption(SIZE)) {
                Number number = (Number) commandLine.getParsedOptionValue(SIZE);
                size = (int) Math.min(Integer.MAX_VALUE, number.longValue());
            }

            float variation = Launcher.DEFAULT_DEVIATION;
            if (commandLine.hasOption(VARIATION)) {
                Number number = (Number) commandLine.getParsedOptionValue(VARIATION);
                if (number.floatValue() < 0.0f || number.floatValue() > 1.0f) {
                    throw new ParseException(MessageFormat.format("Invalid value for option -{0}: {1}", VARIATION,
                            number.floatValue()));
                }
                variation = number.floatValue();
            }

            float propVariation = Launcher.DEFAULT_DEVIATION;
            if (commandLine.hasOption(PROP_VARIATION)) {
                Number number = (Number) commandLine.getParsedOptionValue(PROP_VARIATION);
                if (number.floatValue() < 0.0f || number.floatValue() > 1.0f) {
                    throw new ParseException(MessageFormat.format("Invalid value for option -{0}: {1}",
                            PROP_VARIATION, number.floatValue()));
                }
                propVariation = number.floatValue();
            }

            long seed = System.currentTimeMillis();
            if (commandLine.hasOption(SEED)) {
                seed = ((Number) commandLine.getParsedOptionValue(SEED)).longValue();
            }

            Range<Integer> range = Range.between(Math.round(size * (1 - variation)),
                    Math.round(size * (1 + variation)));

            GenericMetamodelConfig config = new GenericMetamodelConfig(metamodelResource, range, seed);
            GenericMetamodelGenerator modelGen = new GenericMetamodelGenerator(config);

            if (commandLine.hasOption(OUTPUT_PATH)) {
                String outDir = commandLine.getOptionValue(OUTPUT_PATH);
                //java.net.URI intermediateURI = java.net.URI.create(outDir);
                modelGen.setSamplesPath(outDir);
            }

            int numberOfModels = 1;
            if (commandLine.hasOption(N_MODELS)) {
                numberOfModels = ((Number) commandLine.getParsedOptionValue(N_MODELS)).intValue();
            }

            int valuesSize = GenericMetamodelConfig.DEFAULT_AVERAGE_VALUES_LENGTH;
            if (commandLine.hasOption(VALUES_SIZE)) {
                Number number = (Number) commandLine.getParsedOptionValue(VALUES_SIZE);
                valuesSize = (int) Math.min(Integer.MAX_VALUE, number.longValue());
            }

            int referencesSize = GenericMetamodelConfig.DEFAULT_AVERAGE_REFERENCES_SIZE;
            if (commandLine.hasOption(VALUES_SIZE)) {
                Number number = (Number) commandLine.getParsedOptionValue(DEGREE);
                referencesSize = (int) Math.min(Integer.MAX_VALUE, number.longValue());
            }

            config.setValuesRange(Math.round(valuesSize * (1 - propVariation)),
                    Math.round(valuesSize * (1 + propVariation)));

            config.setReferencesRange(Math.round(referencesSize * (1 - propVariation)),
                    Math.round(referencesSize * (1 + propVariation)));

            config.setPropertiesRange(Math.round(referencesSize * (1 - propVariation)),
                    Math.round(referencesSize * (1 + propVariation)));

            long start = System.currentTimeMillis();
            modelGen.runGeneration(resourceSet, numberOfModels, size, variation);
            long end = System.currentTimeMillis();
            LOGGER.info(
                    MessageFormat.format("Generation finished after {0} s", Long.toString((end - start) / 1000)));

            if (commandLine.hasOption(DIAGNOSE)) {
                for (Resource resource : resourceSet.getResources()) {
                    LOGGER.info(
                            MessageFormat.format("Requested validation for resource ''{0}''", resource.getURI()));
                    BasicDiagnostic diagnosticChain = diagnoseResource(resource);
                    if (!isFailed(diagnosticChain)) {
                        LOGGER.info(MessageFormat.format("Result of the diagnosis of resurce ''{0}'' is ''OK''",
                                resource.getURI()));
                    } else {
                        LOGGER.severe(MessageFormat.format("Found ''{0}'' error(s) in the resource ''{1}''",
                                diagnosticChain.getChildren().size(), resource.getURI()));
                        for (Diagnostic diagnostic : diagnosticChain.getChildren()) {
                            LOGGER.fine(diagnostic.getMessage());
                        }
                    }
                }
                LOGGER.info("Validation finished");
            }

        } catch (ParseException e) {
            System.err.println(e.getLocalizedMessage());
            HelpFormatter formatter = new HelpFormatter();
            formatter.setOptionComparator(new OptionComarator<Option>());
            try {
                formatter.setWidth(Math.max(Terminal.getTerminal().getTerminalWidth(), 80));
            } catch (Throwable t) {
                LOGGER.warning("Unable to get console information");
            }
            ;
            formatter.printHelp("java -jar <this-file.jar>", options, true);
            System.exit(ERROR);
        } catch (ClassNotFoundException t) {
            System.err.println("ERROR: Unable to load class" + t.getLocalizedMessage());
            StringWriter stringWriter = new StringWriter();
            t.printStackTrace(new PrintWriter(stringWriter));
            System.err.println(stringWriter.toString());
        } catch (Throwable t) {
            System.err.println("ERROR: " + t.getLocalizedMessage());
            StringWriter stringWriter = new StringWriter();
            t.printStackTrace(new PrintWriter(stringWriter));
            System.err.println(t);
            LOGGER.severe(stringWriter.toString());
            System.exit(ERROR);
        }
    }

    private static BasicDiagnostic diagnoseResource(Resource resource) {
        BasicDiagnostic diagnosticChain = new BasicDiagnostic();
        for (EObject eObject : resource.getContents()) {
            Diagnostician.INSTANCE.validate(eObject, diagnosticChain);
        }
        return diagnosticChain;
    }

    private static boolean isFailed(BasicDiagnostic diagnosticChain) {
        return (diagnosticChain.getSeverity() & Diagnostic.ERROR) == Diagnostic.ERROR;
    }

    @SuppressWarnings("unused")
    private static boolean isWarning(BasicDiagnostic diagnosticChain) {
        return (diagnosticChain.getSeverity() & Diagnostic.WARNING) == Diagnostic.WARNING;
    }

    /**
     * Configures the program options
     *
     * @param options
     */
    private static void configureOptions(Options options) {
        Option metamodelOpt = OptionBuilder.create(E_PACKAGE_CLASS);
        metamodelOpt.setLongOpt(E_PACKAGE_CLASS_LONG);
        metamodelOpt.setArgName("path to the ePackage implementation");
        metamodelOpt.setDescription("PackgeImpl");
        metamodelOpt.setArgs(1);
        metamodelOpt.setRequired(true);

        Option outDirOpt = OptionBuilder.create(OUTPUT_PATH);
        outDirOpt.setLongOpt(OUTPUT_PATH_LONG);
        outDirOpt.setArgName("neoEMF output uri");
        outDirOpt.setDescription("Output directory (defaults to working dir)");
        outDirOpt.setArgs(1);
        outDirOpt.setRequired(true);

        Option nModelsOpt = OptionBuilder.create(N_MODELS);
        nModelsOpt.setLongOpt(N_MODELS_LONG);
        nModelsOpt.setArgName("models");
        nModelsOpt.setDescription("Number of generated models (defaults to 1)");
        nModelsOpt.setType(Number.class);
        nModelsOpt.setArgs(1);

        Option sizeOption = OptionBuilder.create(SIZE);
        sizeOption.setLongOpt(SIZE_LONG);
        sizeOption.setArgName("size");
        sizeOption.setDescription(MessageFormat.format("Average models'' size (defaults to {0})",
                Launcher.DEFAULT_AVERAGE_MODEL_SIZE));
        sizeOption.setType(Number.class);
        sizeOption.setArgs(1);

        Option variationOption = OptionBuilder.create(VARIATION);
        variationOption.setLongOpt(VARIATION_LONG);
        variationOption.setArgName("proportion");
        variationOption.setDescription(MessageFormat
                .format("Variation ([0..1]) in the models'' size (defaults to {0})", Launcher.DEFAULT_DEVIATION));
        variationOption.setType(Number.class);
        variationOption.setArgs(1);

        Option propVariationOption = OptionBuilder.create(PROP_VARIATION);
        propVariationOption.setLongOpt(PROP_VARIATION_LONG);
        propVariationOption.setArgName("properties deviation");
        propVariationOption.setDescription(MessageFormat.format(
                "Variation ([0..1]) in the properties'' size (defaults to {0})", Launcher.DEFAULT_DEVIATION));
        propVariationOption.setType(Number.class);
        propVariationOption.setArgs(1);

        Option seedOption = OptionBuilder.create(SEED);
        seedOption.setLongOpt(SEED_LONG);
        seedOption.setArgName("seed");
        seedOption.setDescription("Seed number (random by default)");
        seedOption.setType(Number.class);
        seedOption.setArgs(1);

        Option valuesSizeOption = OptionBuilder.create(VALUES_SIZE);
        valuesSizeOption.setLongOpt(VALUES_SIZE_LONG);
        valuesSizeOption.setArgName("size");
        valuesSizeOption.setDescription(MessageFormat.format(
                "Average size for attributes with variable length (defaults to {0}). Actual sizes may vary +/- {1}%.",
                GenericMetamodelConfig.DEFAULT_AVERAGE_VALUES_LENGTH,
                GenericMetamodelConfig.DEFAULT_VALUES_DEVIATION * 100));
        valuesSizeOption.setType(Number.class);
        valuesSizeOption.setArgs(1);

        Option degreeOption = OptionBuilder.create(DEGREE);
        degreeOption.setLongOpt(DEGREE_LONG);
        degreeOption.setArgName("degree");
        degreeOption.setDescription(MessageFormat.format(
                "Average number of references per EObject (defaults to {0}). Actual sizes may vary +/- {1}%.",
                GenericMetamodelConfig.DEFAULT_AVERAGE_REFERENCES_SIZE,
                GenericMetamodelConfig.DEFAULT_REFERENCES_DEVIATION * 100));
        degreeOption.setType(Number.class);
        degreeOption.setArgs(1);

        Option forceOption = OptionBuilder.create(FORCE);
        forceOption.setLongOpt(FORCE_LONG);
        forceOption.setDescription("Force the generation, even if input metamodels contain errors");

        Option diagnoseOption = OptionBuilder.create(DIAGNOSE);
        diagnoseOption.setLongOpt(DIAGNOSE_LONG);
        diagnoseOption.setDescription("Run diagnosis on the result model");

        options.addOption(metamodelOpt);
        options.addOption(outDirOpt);
        options.addOption(nModelsOpt);
        options.addOption(sizeOption);
        options.addOption(variationOption);
        options.addOption(propVariationOption);
        options.addOption(valuesSizeOption);
        options.addOption(degreeOption);
        options.addOption(seedOption);
        options.addOption(forceOption);
        options.addOption(diagnoseOption);
    }

    /**
     * Registers the packages
     * @param resource
     */
    @SuppressWarnings("unused")
    private static void registerPackages(Resource resource) {
        EObject eObject = resource.getContents().get(0);
        if (eObject instanceof EPackage) {
            EPackage p = (EPackage) eObject;
            EPackage.Registry.INSTANCE.put(p.getNsURI(), p);
        }
    }
}