fr.obeo.emf.ceson.CesonRuntime.java Source code

Java tutorial

Introduction

Here is the source code for fr.obeo.emf.ceson.CesonRuntime.java

Source

/*******************************************************************************
 * Copyright (c) 2008, 2014 Obeo.
 * 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:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package fr.obeo.emf.ceson;

import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.logging.Logger;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.BufferedTokenStream;
import org.antlr.v4.runtime.TokenStream;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
//CHECKSTYLE:OFF
import fr.obeo.emf.ceson.parser.CesonLexer;
//CHECKSTYLE:ON
import fr.obeo.emf.ceson.parser.CesonParser;

/**
 * {@link CesonRuntime} is the entry point to ceson.
 * 
 * @author <a href="mailto:romain.guider@obeo.fr">Romain Guider</a>
 */
public class CesonRuntime {
    /**
     * The wild card string.
     */
    private static final String WILDCARD = "*";
    /**
     * the registered {@link EPackage} instances.
     */
    private SortedMap<String, EPackage> ePackages = new TreeMap<String, EPackage>();
    /**
     * current definitions.
     */
    private Map<String, Object> definitions = new TreeMap<String, Object>();
    /**
     * The resource set used for this parser.
     */
    private ResourceSet resourceSet;
    /**
     * whether a single resource is used for generated object or not.
     */
    private boolean singleResource;
    /**
     * The logger ued to report information, warning and problems.
     */
    private Logger logger = Logger.getAnonymousLogger();

    /**
     * Creates a new {@link CesonRuntime} instance.
     * 
     * @param singleResource
     *            whether a single resource is used to generaed object or not.
     */
    public CesonRuntime(boolean singleResource) {
        this.resourceSet = new ResourceSetImpl();
        this.resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(WILDCARD,
                new XMIResourceFactoryImpl());
        this.singleResource = singleResource;
    }

    /**
     * Creates a new {@link CesonRuntime} instance with it's own
     * {@link ResourceSet}, and using a single resource.
     */
    public CesonRuntime() {
        this.resourceSet = new ResourceSetImpl();
        this.resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(WILDCARD,
                new XMIResourceFactoryImpl());
        this.singleResource = true;
    }

    /**
     * Registers a new {@link EPackage}.
     * 
     * @param ePackage
     *            the registered {@link EPackage}.
     */
    public void registerEPackage(EPackage ePackage) {
        ePackages.put(ePackage.getNsPrefix(), ePackage);
    }

    /**
     * Create a parser.
     * 
     * @param input
     *            the parser's input.
     * @return the created {@link CesonParser}
     */
    private CesonParser createParser(String input) {
        TokenStream stream = new BufferedTokenStream(new CesonLexer(new ANTLRInputStream(input)));
        CesonParser parser = new CesonParser(stream);
        return parser;
    }

    /**
     * get or create a {@link Resource} with the specified name.
     * 
     * @param name
     *            the name of the resource
     * @return the corresponding resource.
     */
    private Resource getResource(String name) {
        String resourceName = name;
        Resource result;
        if (name == null || name.length() == 0) {
            resourceName = "resource";
        }
        if (singleResource && resourceSet.getResources().size() > 0) {
            result = resourceSet.getResources().get(0);
        } else {
            result = resourceSet.createResource(URI.createURI("http://ceson//" + resourceName));
        }
        if (!(result instanceof XMIResourceImpl)) {
            throw new IllegalStateException(
                    "The Resource factory has been reconfigured externally. Can't process request.");
        }
        return result;
    }

    /**
     * parse the specified string which must describe a Ceson specification.
     * 
     * @param description
     *            the specification to parse.
     * @return the resource that contains the objects in the specification.
     * @throws CesonException
     *             if a parsing or generation problem occurs.
     */
    public Resource parseSpecification(String description) throws CesonException {
        CesonParser parser = createParser(description);
        CesonModelBuilder modelBuilder = new CesonModelBuilder("");
        parser.addParseListener(modelBuilder);
        try {
            parser.model();
        } catch (IllegalStateException ise) {
            throw new CesonException(ise);
        }
        Resource resource = getResource(modelBuilder.getSpecification().getName());
        EcoreGenerator generator = new EcoreGenerator(ePackages, resource, definitions);
        CSpecification cResult = modelBuilder.getSpecification();
        if (cResult == null || !(cResult instanceof CSpecification)) {
            throw new CesonException("Couldn't parse the given specification.");
        }
        generator.doSwitch((EObject) cResult);
        return resource;
    }

    /**
     * parse the specified string which must describe a Ceson definition.
     * 
     * @param definition
     *            the definition to parse.
     * @return the resource that contains the objects in the specification.
     * @throws CesonException
     *             if a parsing or generation problem occurs.
     */
    public Object define(String definition) throws CesonException {
        CesonParser parser = createParser(definition);
        CesonModelBuilder modelBuilder = new CesonModelBuilder("");
        parser.addParseListener(modelBuilder);
        try {
            parser.definition();
        } catch (IllegalStateException ise) {
            throw new CesonException(ise);
        }
        Resource resource = getResource(modelBuilder.getSpecification().getName());
        EcoreGenerator generator = new EcoreGenerator(ePackages, resource, definitions);
        String varName = (String) modelBuilder.getResult();
        Object cResult = generator.doSwitch((EObject) modelBuilder.getSpecification());
        logger.info("defined " + varName + " to " + cResult);
        return cResult;
    }

    /**
     * parse the specified string which must describe a Ceson value.
     * 
     * @param valueDescription
     *            the valueDescription to parse.
     * @return the resource that contains the objects in the specification.
     * @throws CesonException
     *             if a parsing or generation problem occurs.
     */
    public Object parseValue(String valueDescription) throws CesonException {
        CesonParser parser = createParser(valueDescription);
        CesonModelBuilder modelBuilder = new CesonModelBuilder("");
        parser.addParseListener(modelBuilder);
        try {
            parser.value();
        } catch (IllegalStateException ise) {
            throw new CesonException(ise);
        }
        Resource resource = getResource(modelBuilder.getSpecification().getName());
        EcoreGenerator generator = new EcoreGenerator(ePackages, resource, definitions);
        Object cResult = modelBuilder.getResult();
        if (cResult == null || !(cResult instanceof CValue)) {
            throw new CesonException("Couldn't parse the given definition.");
        }
        return generator.doSwitch((EObject) cResult);
    }

    /**
     * Define a variable with an external {@link Object}.
     * 
     * @param varName
     *            the name of the created definition.
     * @param value
     *            the value of the definition.
     * @return the previous object associated to the name if any.
     */
    public Object define(String varName, Object value) {
        if (varName == null || value == null) {
            throw new IllegalArgumentException("The variable name and the value must be non null.");
        }
        logger.info("defined " + varName + " to " + value);
        return this.definitions.put(varName, value);
    }

    /**
     * Kill a definition and returns it's value if any.
     * 
     * @param varName
     *            the variable name of the definition.
     * @return the value of the killed definition if any.
     */
    public Object killDefinition(String varName) {
        return this.definitions.remove(varName);
    }

    /**
     * Clear all the definitions.
     */
    public void clearDefinitions() {
        this.definitions.clear();
    }

    /**
     * Returns the definition for the specified variable's name.
     * 
     * @param varName
     *            the variable which definition is seeked.
     * @return the value of the definition.
     */
    Object getDefinition(String varName) {
        return this.definitions.get(varName);
    }
}