Search in sources :

Example 6 with GroovityClassLoader

use of com.disney.groovity.compile.GroovityClassLoader in project groovity by disney.

the class Groovity method initClass.

protected void initClass(Class<?> clz) {
    if (clz != null) {
        final GroovityClassLoader gcl = (GroovityClassLoader) clz.getClassLoader();
        gcl.init(traits);
        // here is where we call upon our Configurator
        if (configurator != null) {
            try {
                gcl.configure(configurator);
            } catch (Exception e) {
                log.log(Level.SEVERE, "Error configuring " + clz.getName(), e);
            }
        }
        // Now let's register the ArgsBindingVisitor with the classloader
        try {
            java.lang.reflect.Field argsField = clz.getDeclaredField(ARGS);
            if (Modifier.isStatic(argsField.getModifiers())) {
                argsField.setAccessible(true);
                Object argsValue = argsField.get(null);
                if (argsValue != null && argsValue instanceof Map) {
                    @SuppressWarnings("unchecked") Map<String, Object> av = (Map<String, Object>) argsValue;
                    gcl.setArgsResolver(new ArgsResolver(av, getSourcePath(clz)));
                }
            }
        } catch (NoSuchFieldException e) {
        } catch (Exception e) {
            log.log(Level.SEVERE, "Error intializing script arguments for " + clz.getName(), e);
        }
        Class<?>[] cls = gcl.getLoadedClasses();
        for (Class<?> cl : cls) {
            try {
                // inject GroovityScriptFactory
                java.lang.reflect.Field factoryField = cl.getDeclaredField(GROOVITY_SCRIPT_HELPER_FIELD);
                factoryField.setAccessible(true);
                factoryField.set(null, gcl.getScriptHelper());
            } catch (Throwable e) {
            }
            Method m = null;
            try {
                m = cl.getDeclaredMethod(INIT);
            } catch (Throwable e) {
            }
            if (m != null) {
                try {
                    if (Modifier.isStatic(m.getModifiers()) && m.getParameterTypes().length == 0) {
                        LinkedHashMap<String, Object> variables = new LinkedHashMap<>();
                        Binding binding = new Binding(variables);
                        if (bindingDecorator != null) {
                            bindingDecorator.decorateRecursive(variables);
                        }
                        ScriptHelper.THREAD_BINDING.set(binding);
                        try {
                            m.invoke(null);
                        } finally {
                            ScriptHelper.THREAD_BINDING.remove();
                        }
                        log.info("Initialized " + cl);
                    }
                } catch (InvocationTargetException e) {
                    Throwable t = e.getCause();
                    if (t instanceof Error) {
                        throw (Error) t;
                    }
                    log.log(Level.SEVERE, "Error initing " + cl, t);
                } catch (Exception e) {
                    log.log(Level.SEVERE, "Error initing " + cl, e);
                }
            }
        }
    }
}
Also used : Binding(groovy.lang.Binding) GroovityClassLoader(com.disney.groovity.compile.GroovityClassLoader) Method(java.lang.reflect.Method) Field(java.lang.reflect.Field) InvocationTargetException(java.lang.reflect.InvocationTargetException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) InvocationTargetException(java.lang.reflect.InvocationTargetException) LinkedHashMap(java.util.LinkedHashMap) GroovyClass(org.codehaus.groovy.tools.GroovyClass) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 7 with GroovityClassLoader

use of com.disney.groovity.compile.GroovityClassLoader in project groovity by disney.

the class Cache method getCache.

@SuppressWarnings("rawtypes")
protected com.disney.groovity.cache.Cache getCache(Map attributes, Closure body, int ttl, int max, boolean isLoader) throws NoSuchMethodException, SecurityException, URISyntaxException {
    Object namea = resolve(attributes, "name");
    GroovityClassLoader classLoader = getScriptHelper(body).getClassLoader();
    String name = "defaultCache";
    if (namea != null) {
        name = namea.toString();
    }
    return classLoader.getCache(name, isLoader ? body : null, ttl, max);
}
Also used : GroovityClassLoader(com.disney.groovity.compile.GroovityClassLoader)

Example 8 with GroovityClassLoader

use of com.disney.groovity.compile.GroovityClassLoader in project groovity by disney.

the class Groovity method loadClasses.

protected void loadClasses(String sourcePath, InputStream jarStream, long modTime, boolean embedded, HashMap<String, Collection<String>> newScriptDependencies, Map<String, Boolean> newScriptInits) throws IOException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    ArrayList<String> dependencies = new ArrayList<String>();
    CompilerConfiguration compilerConfiguration = createCompilerConfiguration(null, dependencies);
    GroovyClass[] classes = loadGroovyClasses(jarStream);
    // a classloader only gets the traits that are available when it is created, so we make a copy
    @SuppressWarnings("rawtypes") ConcurrentHashMap<String, Class> traitsCopy = new ConcurrentHashMap<>(traits);
    GroovityClassLoader loader = parentLoader != null ? new GroovityClassLoader(sourcePath, parentLoader, compilerConfiguration, this, cacheRefreshExecutor, traitsCopy) : new GroovityClassLoader(sourcePath, Thread.currentThread().getContextClassLoader(), compilerConfiguration, this, cacheRefreshExecutor, traitsCopy);
    if (classes != null) {
        Class<Script> scriptClass = loadGroovyClassesAndFindScript(loader, classes, traits, traitsCopy);
        if (scriptClass != null) {
            // this seemingly useless call will force failure if there are referenced traits missing so we can retry ...
            for (@SuppressWarnings("rawtypes") Class c : loader.getLoadedClasses()) {
                Field[] fields = c.getDeclaredFields();
                for (Field f : fields) {
                    f.getGenericType();
                }
                Method[] dm = c.getDeclaredMethods();
                for (Method m : dm) {
                    m.getGenericParameterTypes();
                    m.getGenericReturnType();
                    m.getGenericExceptionTypes();
                }
            }
            String path = getSourcePath(scriptClass);
            String script = getScriptName(path);
            String fixed = fixCase(script);
            // System.out.println("Loaded script "+script+" for name "+path+" "+scriptClass);
            newScriptDependencies.put(script, getDependencies(scriptClass));
            newScriptInits.put(script, hasInit((GroovityClassLoader) scriptClass.getClassLoader()));
            if (embedded) {
                embeddedScripts.put(fixed, scriptClass);
            } else {
                scripts.put(fixed, scriptClass);
                scriptDates.put(fixed, modTime);
            }
        } else {
            log.severe("NO SCRIPT CLASS FOUND!! " + sourcePath);
        }
    }
}
Also used : Script(groovy.lang.Script) GroovyClass(org.codehaus.groovy.tools.GroovyClass) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) GroovityClassLoader(com.disney.groovity.compile.GroovityClassLoader) Method(java.lang.reflect.Method) Field(java.lang.reflect.Field) CompilerConfiguration(org.codehaus.groovy.control.CompilerConfiguration) GroovyClass(org.codehaus.groovy.tools.GroovyClass) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 9 with GroovityClassLoader

use of com.disney.groovity.compile.GroovityClassLoader in project groovity by disney.

the class Groovity method compile.

/**
 * Compare the timestamp of the source against an existing compiled version, only recompiling
 * if they do not match.  The force parameter is used to force a recompile regardless of dates.
 *
 * @param sources
 * @param force
 */
@SuppressWarnings("rawtypes")
protected void compile(boolean force, boolean init, ConcurrentHashMap<String, Class> compilerTraits, GroovitySource... sources) {
    // take multiple sources and compile as a set, only initing() classes once all are loaded
    HashMap<String, Class<Script>> newScripts = new HashMap<String, Class<Script>>();
    HashMap<String, Long> newScriptDates = new HashMap<String, Long>();
    HashMap<String, File> deletedScripts = new HashMap<String, File>();
    HashMap<String, Collection<String>> scriptDependencies = new HashMap<String, Collection<String>>();
    HashMap<String, Boolean> scriptInits = new HashMap<String, Boolean>();
    compileLoop(newScripts, newScriptDates, deletedScripts, scriptDependencies, scriptInits, force, init, 0, compilerTraits, sources);
    List<Class<Script>> toDestroy = new ArrayList<Class<Script>>();
    HashSet<String> sourceNames = new HashSet<>();
    for (GroovitySource source : sources) {
        sourceNames.add(getScriptName(source.getPath()));
    }
    List<String> sortedScripts = sortDependencies(scriptDependencies, scriptInits);
    // load order for dependencies!
    for (String scriptName : sortedScripts) {
        String scriptNameFixed = fixCase(scriptName);
        Class<Script> theClass = newScripts.get(scriptName);
        if (init) {
            initClass(theClass);
        }
        scriptDates.put(scriptNameFixed, newScriptDates.get(scriptName));
        Class<Script> oldClass = scripts.put(scriptNameFixed, theClass);
        if (listeners != null) {
            for (GroovityClassListener listener : listeners) {
                listener.scriptUpdated(this, scriptName, theClass);
            }
        }
        if (oldClass != null) {
            toDestroy.add(oldClass);
        } else if (embeddedScripts.containsKey(scriptNameFixed)) {
            toDestroy.add(embeddedScripts.get(scriptNameFixed));
        }
    }
    for (Map.Entry<String, File> deleted : deletedScripts.entrySet()) {
        String name = deleted.getKey();
        String nameCaseFixed = fixCase(name);
        Class<Script> oldClass = scripts.remove(nameCaseFixed);
        scriptDates.remove(nameCaseFixed);
        // notify listeners
        if (listeners != null) {
            for (GroovityClassListener listener : listeners) {
                listener.scriptDeleted(name);
            }
        }
        if (oldClass != null) {
            log.info("Deleting removed source " + name + " / class " + oldClass.getName());
            toDestroy.add(oldClass);
            Class<Script> embeddedClass = embeddedScripts.get(nameCaseFixed);
            if (embeddedClass != null && init) {
                initClass(embeddedClass);
                newScripts.put(nameCaseFixed, embeddedClass);
            }
        }
        if (deleted.getValue() != null) {
            deleted.getValue().delete();
        }
    }
    if (init) {
        // now destroy
        for (Class<Script> del : toDestroy) {
            ((GroovityClassLoader) del.getClassLoader()).destroy();
        }
        if (started.get()) {
            // now start new scripts
            newScripts.values().forEach(cls -> {
                startClass(cls);
            });
        }
    }
    Map<String, Throwable> errors = new LinkedHashMap<String, Throwable>();
    for (Entry<String, GroovityCompilerEvent> entry : getCompilerEvents().entrySet()) {
        if (entry.getValue().getError() != null) {
            if (sourceNames.contains(entry.getKey())) {
                errors.put(entry.getKey(), entry.getValue().getError());
            }
        }
    }
    if (errors.size() > 0) {
        StringBuilder messageBuilder = new StringBuilder(String.valueOf(errors.size())).append(" script");
        if (errors.size() > 1) {
            messageBuilder.append("s");
        }
        messageBuilder.append(" failed to compile");
        for (Entry<String, Throwable> entry : errors.entrySet()) {
            messageBuilder.append(LINE_SEPARATOR);
            messageBuilder.append(LINE_SEPARATOR);
            messageBuilder.append("Error compiling ").append(entry.getKey()).append(".grvt :");
            messageBuilder.append(LINE_SEPARATOR);
            messageBuilder.append(LINE_SEPARATOR);
            messageBuilder.append(entry.getValue().getMessage());
        }
        log.severe(messageBuilder.toString());
    }
}
Also used : LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) GroovitySource(com.disney.groovity.source.GroovitySource) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) GroovityCompilerEvent(com.disney.groovity.compile.GroovityCompilerEvent) HashSet(java.util.HashSet) GroovityClassListener(com.disney.groovity.compile.GroovityClassListener) Script(groovy.lang.Script) GroovityClassLoader(com.disney.groovity.compile.GroovityClassLoader) Collection(java.util.Collection) GroovyClass(org.codehaus.groovy.tools.GroovyClass) File(java.io.File) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 10 with GroovityClassLoader

use of com.disney.groovity.compile.GroovityClassLoader in project groovity by disney.

the class Groovity method run.

/**
 * This is the primary method of interest - execute an individual groovity script by path using a given binding.
 * If the script returns a Writable (streaming template or GString) and a Writer is bound to "out", the value will be streamed to out,
 * otherwise the return value is passed through to the caller.
 *
 * @param scriptName the path of the script to execute, e.g. /myFolder/myScript
 * @param binding the groovy binding to use as global variable scope
 * @return the return value of the script, if any
 * @throws InstantiationException
 * @throws IllegalAccessException
 * @throws ClassNotFoundException
 * @throws IOException
 */
public Object run(final String scriptName, final Binding binding) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException {
    Script script = load(scriptName, binding);
    if (script != null) {
        Object rval = script.run();
        ScriptHelper scriptHelper = ((GroovityClassLoader) script.getClass().getClassLoader()).getScriptHelper();
        if (!scriptHelper.processReturn(script, rval)) {
            return rval;
        }
    }
    return null;
}
Also used : Script(groovy.lang.Script) GroovityClassLoader(com.disney.groovity.compile.GroovityClassLoader) ScriptHelper(com.disney.groovity.util.ScriptHelper)

Aggregations

GroovityClassLoader (com.disney.groovity.compile.GroovityClassLoader)11 Script (groovy.lang.Script)7 LinkedHashMap (java.util.LinkedHashMap)5 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)5 GroovyClass (org.codehaus.groovy.tools.GroovyClass)5 Binding (groovy.lang.Binding)4 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 Map (java.util.Map)4 GroovitySource (com.disney.groovity.source.GroovitySource)3 FileNotFoundException (java.io.FileNotFoundException)3 IOException (java.io.IOException)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)3 Method (java.lang.reflect.Method)3 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)3 GroovityCompilerEvent (com.disney.groovity.compile.GroovityCompilerEvent)2 ScriptHelper (com.disney.groovity.util.ScriptHelper)2 File (java.io.File)2 Field (java.lang.reflect.Field)2 CompilerConfiguration (org.codehaus.groovy.control.CompilerConfiguration)2