Package org.andromda.scriptwrappers

Source Code of org.andromda.scriptwrappers.GroovyScriptWrapper

package org.andromda.scriptwrappers;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;

import java.lang.reflect.Method;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;


/**
* This is a wrapper class for a Groovy script. The generated Java classes contain a private
* final copy of this wrapper and delegates all methods to this class so that their Groovy-counterparts
* can be executed.
*
* @author Chad Brandon
*/
public class GroovyScriptWrapper
{
    private String scriptPath;
    private Object stub;

    /**
     * StubClass is always the generated class (not any subclasses),
     * while stub may be an instance of a subclassed scripted class.
     */
    public GroovyScriptWrapper(
        Object stub,
        String scriptPath)
        throws java.lang.InstantiationError
    {
        this.stub = stub;
        this.scriptPath = scriptPath;
    }

    /**
     * Invokes the method with the given <code>methodName</code> on the instance.
     *
     * @param methodName the name of the method to invoke.
     * @param args the arguments to pass to the method.
     * @return the return result of invoking the operation.
     */
    public Object invoke(
        String methodName,
        Object[] args)
    {
        try
        {
            final GroovyClassLoader grooveyClassLoader = new GroovyClassLoader(this.getClassLoader());
            final Class groovyClass =
                grooveyClassLoader.parseClass(
                    this.getContents(new File(this.scriptPath)),
                    scriptPath);
            final GroovyObject groovyObject = (GroovyObject)groovyClass.newInstance();

            this.copyProperties(
                this.stub,
                groovyObject);
            return groovyObject.invokeMethod(
                methodName,
                args);
        }
        catch (final Throwable throwable)
        {
            throw new java.lang.RuntimeException(throwable);
        }
    }
   
    /**
     * Retrieves the appropriate class loader instance as the parent of the groovyClassLoader.
     *
     * @return the class loader instance.
     */
    private ClassLoader getClassLoader()
    {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        if (classLoader == null)
        {
            classLoader = this.getClass().getClassLoader();
        }
        return classLoader;
    }

    /**
     * The line separator.
     */
    private static final char LINE_SEPARATOR = '\n';

    /**
     * Loads the resource and returns the contents as a String.
     *
     * @param resource the name of the resource.
     * @return the contents of the resource as a string.
     * @throws FileNotFoundException
     */
    private String getContents(final File file)
        throws FileNotFoundException
    {
        Reader resource = new FileReader(file);
        final StringBuffer contents = new StringBuffer();
        try
        {
            if (resource != null)
            {
                BufferedReader resourceInput = new BufferedReader(resource);
                for (String line = resourceInput.readLine(); line != null; line = resourceInput.readLine())
                {
                    contents.append(line + LINE_SEPARATOR);
                }
                resourceInput.close();
                resourceInput = null;
            }
        }
        catch (final Throwable throwable)
        {
            throw new RuntimeException(throwable);
        }

        // - return the contents and remove any throws clauses (since groovy doesn't support those)
        return contents.toString().trim().replaceAll(
            "\\s+throws\\s+.+\\s+",
            " ");
    }

    /**
     * Copies all properties from the given <code>from</code> instance to the given
     * <code>to</code> instance.
     *
     * @param from the instance from which to copy all properties.
     * @param to the instance of which to copy all properties.
     * @throws Exception
     */
    private void copyProperties(
        final Object from,
        final GroovyObject to)
        throws Exception
    {
        final Set methods = new LinkedHashSet();
        loadSuperMethods(
            from.getClass(),
            methods);
        for (final Iterator iterator = methods.iterator(); iterator.hasNext();)
        {
            final Method method = (Method)iterator.next();

            final String methodName = method.getName();
            final String getPrefix = "get";
            if (methodName.startsWith(getPrefix) && method.getParameterTypes().length == 0)
            {
                String propertyName = methodName.replaceAll(
                        getPrefix,
                        "");

                Method setterMethod = null;
                try
                {
                    setterMethod =
                        from.getClass().getMethod(
                            "set" + propertyName,
                            new Class[] {method.getReturnType()});
                }
                catch (final Exception exception)
                {
                    // - ignore
                }
                if (setterMethod != null)
                {
                    method.setAccessible(true);
                    final Object value = method.invoke(
                            from,
                            null);
                    to.invokeMethod(
                        setterMethod.getName(),
                        new Object[] {value});
                }
            }
        }
    }

    /**
     * Loads all methods from the clazz's super classes.
     *
     * @param methods the list to load full of methods.
     * @param clazz the class to retrieve the methods.
     * @return the loaded methods.
     */
    private static Set loadSuperMethods(
        final Class clazz,
        final Set methods)
    {
        if (clazz.getSuperclass() != null)
        {
            methods.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredMethods()));
            methods.addAll(loadSuperMethods(
                    clazz.getSuperclass(),
                    methods));
        }
        return methods;
    }
}
TOP

Related Classes of org.andromda.scriptwrappers.GroovyScriptWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.