Search in sources :

Example 1 with GroovityClassLoader

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

the class GroovityTestMojo method execute.

public void execute() throws MojoExecutionException, MojoFailureException {
    try {
        if (skip) {
            return;
        }
        getLog().info("STARTING Groovity test");
        populateSystemProperties();
        ClassLoader testLoader = createClassLoader(ClassLoaderScope.TEST);
        GroovityServletContainerBuilder builder = new GroovityServletContainerBuilder().setPort(Integer.valueOf(port)).setWebappDirectory(new File(project.getBasedir(), "src/main/webapp")).setClassLoader(testLoader);
        if (groovitySourceDirectory != null && groovitySourceDirectory.exists()) {
            builder.addSourceLocation(groovitySourceDirectory.toURI(), true);
        }
        if (groovityTestDirectory != null && groovityTestDirectory.exists()) {
            builder.addSourceLocation(groovityTestDirectory.toURI(), true);
        }
        if (sources != null) {
            for (File source : sources) {
                builder.addSourceLocation(source.toURI(), true);
            }
        }
        GroovityStatistics.reset();
        GroovityServletContainer container = builder.build();
        container.start();
        Groovity groovity = container.getGroovity();
        ArrayList<String> appSources = new ArrayList<String>();
        try {
            if (failOnError) {
                validateFactory(groovity);
            }
            if (skipTests) {
                return;
            }
            GroovitySourceLocator[] sourceLocators = groovity.getSourceLocators();
            for (GroovitySourceLocator locator : sourceLocators) {
                if (!interactive && ((FileGroovitySourceLocator) locator).getDirectory().equals(groovityTestDirectory)) {
                    if (path != null) {
                        String[] pathParts = path.split("\\s*,\\s*");
                        for (String pathPart : pathParts) {
                            container.run(pathPart);
                        }
                    } else {
                        for (GroovitySource source : locator) {
                            String scriptPath = source.getPath();
                            scriptPath = scriptPath.substring(0, scriptPath.lastIndexOf("."));
                            String scriptName = scriptPath.substring(scriptPath.lastIndexOf('/') + 1);
                            if (scriptName.startsWith("test")) {
                                container.run(scriptPath);
                            }
                        }
                    }
                }
                if (((FileGroovitySourceLocator) locator).getDirectory().equals(groovitySourceDirectory)) {
                    for (GroovitySource source : locator) {
                        appSources.add(source.getPath());
                    }
                }
            }
            if (interactive) {
                // in interactive mode we wait for instructions and compile each time to allow
                // real-time development
                container.enterConsole();
            }
        } finally {
            container.stop();
        }
        Map<String, CodeCoverage> coverageMap = new TreeMap<String, GroovityTestMojo.CodeCoverage>();
        Collection<Class<Script>> scriptClasses = groovity.getGroovityScriptClasses();
        for (Class<Script> sc : scriptClasses) {
            String sourcePath = groovity.getSourcePath(sc);
            if (appSources.contains(sourcePath)) {
                String scriptLabel = sourcePath.substring(0, sourcePath.length() - 5);
                CodeCoverage cc = new CodeCoverage(sc, scriptLabel);
                if (cc.isCoverable()) {
                    coverageMap.put(scriptLabel, cc);
                }
                for (Class<?> c : ((GroovityClassLoader) sc.getClassLoader()).getLoadedClasses()) {
                    if (!c.equals(sc) && !(Closure.class.isAssignableFrom(c)) && !c.isInterface()) {
                        String cname = getClassLabel(c);
                        int p = 0;
                        if ((p = cname.indexOf("$Trait")) > 0) {
                            cname = cname.substring(0, p);
                        }
                        String classLabel = scriptLabel + "->" + cname;
                        CodeCoverage icc = new CodeCoverage(c, classLabel);
                        if (icc.isCoverable()) {
                            coverageMap.put(classLabel, icc);
                        }
                    }
                }
            }
        }
        List<Statistics> stats = GroovityStatistics.getStatistics();
        for (Statistics stat : stats) {
            String sks = stat.key.toString();
            int dot = sks.indexOf(".");
            if (dot > 0) {
                String className = sks.substring(0, dot);
                String method = sks.substring(dot + 1);
                CodeCoverage cc = coverageMap.get(className);
                if (cc != null) {
                    if (method.equals("run()") && cc.runnable) {
                        cc.ran = true;
                    } else {
                        if (cc.methods.containsKey(method)) {
                            cc.methods.put(method, true);
                        }
                    }
                }
            }
        }
        Collection<CodeCoverage> ccs = coverageMap.values();
        double total = 0;
        for (CodeCoverage cc : ccs) {
            total += cc.getCoverage();
        }
        total /= ccs.size();
        getLog().info("TEST COVERAGE " + ((int) (100 * total)) + "% TOTAL");
        for (Entry<String, CodeCoverage> entry : coverageMap.entrySet()) {
            CodeCoverage cc = entry.getValue();
            double covered = cc.getCoverage();
            getLog().info(" " + ((int) (100 * covered)) + "% coverage for " + cc.label);
            if (covered < 1.0) {
                if (cc.runnable && !cc.ran) {
                    getLog().warn("   Script body did not run during tests");
                }
                List<String> uncovered = cc.getUncoveredMethods();
                if (!uncovered.isEmpty()) {
                    for (String m : cc.getUncoveredMethods()) {
                        getLog().warn("   " + m + " did not execute during tests");
                    }
                }
            }
        /*
				for(String m: cc.getCoveredMethods()) {
					getLog().info("   " + m + " executed during tests");
				}
				*/
        }
    } catch (MojoFailureException e) {
        throw e;
    } catch (Throwable e) {
        getLog().error("ERROR in Groovity test", e);
        throw new MojoFailureException(e.getMessage());
    }
}
Also used : ArrayList(java.util.ArrayList) FileGroovitySourceLocator(com.disney.groovity.source.FileGroovitySourceLocator) Groovity(com.disney.groovity.Groovity) GroovityClassLoader(com.disney.groovity.compile.GroovityClassLoader) GroovitySource(com.disney.groovity.source.GroovitySource) GroovityServletContainer(com.disney.groovity.servlet.container.GroovityServletContainer) Script(groovy.lang.Script) GroovityServletContainerBuilder(com.disney.groovity.servlet.container.GroovityServletContainerBuilder) MojoFailureException(org.apache.maven.plugin.MojoFailureException) GroovityClassLoader(com.disney.groovity.compile.GroovityClassLoader) TreeMap(java.util.TreeMap) GroovityStatistics(com.disney.groovity.stats.GroovityStatistics) Statistics(com.disney.groovity.stats.GroovityStatistics.Statistics) GatherStatistics(com.disney.groovity.compile.GatherStatistics) GroovitySourceLocator(com.disney.groovity.source.GroovitySourceLocator) FileGroovitySourceLocator(com.disney.groovity.source.FileGroovitySourceLocator) File(java.io.File)

Example 2 with GroovityClassLoader

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

the class Log method tag.

@SuppressWarnings("rawtypes")
@Override
public Object tag(Map attributes, Closure body) throws Exception {
    ScriptHelper helper = getScriptHelper(body);
    GroovityClassLoader classLoader = helper.getClassLoader();
    Logger logger = classLoader.getLogger();
    Throwable thrown = resolve(attributes, "thrown", Throwable.class);
    doLog(attributes, logger, Level.FINE, "debug", thrown);
    doLog(attributes, logger, Level.INFO, "info", thrown);
    doLog(attributes, logger, Level.WARNING, "warn", thrown);
    doLog(attributes, logger, Level.SEVERE, "error", thrown);
    return null;
}
Also used : GroovityClassLoader(com.disney.groovity.compile.GroovityClassLoader) ScriptHelper(com.disney.groovity.util.ScriptHelper) Logger(java.util.logging.Logger)

Example 3 with GroovityClassLoader

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

the class Groovity method load.

/**
 * This method is used to load an instance of a script without executing it, for example in order to use it as a library,
 * or to defer running it until a later time; instances are always Singletons within a binding scope, so repeated
 * calls to load the same script name with the same binding will return the same instance of the script.
 *
 * @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 an instance of a script tied to the provided binding
 * @throws InstantiationException
 * @throws IllegalAccessException
 * @throws ClassNotFoundException
 */
@SuppressWarnings("unchecked")
public Script load(final String scriptName, final Binding binding) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    final String varName = GROOVITY_SCRIPT_BINDING_PREFIX.concat(fixCase(scriptName));
    @SuppressWarnings("rawtypes") final Map variables = binding.getVariables();
    Script script = (Script) variables.get(varName);
    if (script == null) {
        decorate(variables);
        // register place holder to catch circular dependencies
        variables.put(varName, PLACEHOLDER_SCRIPT);
        try {
            final Binding oldThreadBinding = ScriptHelper.THREAD_BINDING.get();
            if (oldThreadBinding != binding) {
                // register our binding during field init so it propgates
                ScriptHelper.THREAD_BINDING.set(binding);
            }
            try {
                final Class<Script> gsc = getScriptClass(scriptName);
                if (gsc != null) {
                    // before we create a new instance, let's look for args
                    ArgsResolver abd = ((GroovityClassLoader) gsc.getClassLoader()).getArgsResolver();
                    if (abd != null) {
                        // now is the time to enforce any defaults, coercion, validation, BEFORE we create a new instance
                        // whose field loading might depend on the arg binding decorator
                        abd.resolve(variables, argsLookup);
                    }
                    script = gsc.newInstance();
                    if (script != null) {
                        script.setBinding(binding);
                        variables.put(varName, script);
                        if (script instanceof Loadable) {
                            ((Loadable) script).load();
                        }
                    }
                }
            } finally {
                if (oldThreadBinding == null) {
                    ScriptHelper.THREAD_BINDING.remove();
                } else if (oldThreadBinding != binding) {
                    ScriptHelper.THREAD_BINDING.set(oldThreadBinding);
                }
            }
        } finally {
            if (script == null) {
                variables.remove(varName);
            }
        }
    }
    if (script == null) {
        throw new ClassNotFoundException("No grvt found for " + scriptName);
    }
    if (script == PLACEHOLDER_SCRIPT) {
        throw new InstantiationException("Circular load dependency found leading back to " + scriptName);
    }
    return script;
}
Also used : Binding(groovy.lang.Binding) Script(groovy.lang.Script) GroovityClassLoader(com.disney.groovity.compile.GroovityClassLoader) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 4 with GroovityClassLoader

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

the class Groovity method compileLoop.

@SuppressWarnings("rawtypes")
private void compileLoop(Map<String, Class<Script>> newScripts, Map<String, Long> newScriptDates, Map<String, File> deletedScripts, Map<String, Collection<String>> scriptDependencies, Map<String, Boolean> scriptInits, boolean force, boolean init, int numErrors, ConcurrentHashMap<String, Class> compilerTraits, GroovitySource... sources) {
    HashMap<String, GroovitySource> errorSources = new HashMap<>();
    for (GroovitySource source : sources) {
        try {
            GroovityCompilerEvent event = new GroovityCompilerEvent();
            event.setPath(source.getPath());
            event.setTime(System.currentTimeMillis());
            String name = getScriptName(source.getPath());
            String nameCaseFixed = fixCase(name);
            String className = name.replaceAll("_", "___").replaceAll("/", "_");
            // System.out.println("Compiling source "+source.getPath()+" "+name+" "+className);
            if (source.exists()) {
                if (scripts.containsKey(nameCaseFixed)) {
                    event.setChange(Change.update);
                } else {
                    event.setChange(Change.add);
                }
                if (!force) {
                    Long cur = scriptDates.get(nameCaseFixed);
                    // System.out.println("comparing "+cur+" to "+source.getLastModified()+" for "+name);
                    if (cur != null && cur.longValue() == source.getLastModified()) {
                        continue;
                    }
                }
                String sourceCode = null;
                try {
                    sourceCode = source.getSourceCode();
                    // code transformations pre-compile
                    TransformedSource transformed = GroovitySourceTransformer.transformSource(sourceCode);
                    sourceCode = transformed.source;
                    // groovy script compiler
                    long time1 = System.currentTimeMillis();
                    ArrayList<String> dependencies = new ArrayList<String>();
                    CompilerConfiguration compilerConfiguration = createCompilerConfiguration(transformed != null ? transformed.sourceLineNumbers : null, dependencies);
                    // a classloader only gets the traits that are available when it is created, so we make a copy
                    ConcurrentHashMap<String, Class> traitsCopy = new ConcurrentHashMap<>(compilerTraits);
                    GroovityClassLoader loader = getParentLoader() != null ? new GroovityClassLoader(source.getPath(), getParentLoader(), compilerConfiguration, this, cacheRefreshExecutor, traitsCopy) : new GroovityClassLoader(source.getPath(), Thread.currentThread().getContextClassLoader(), compilerConfiguration, this, cacheRefreshExecutor, traitsCopy);
                    CompilationUnit cu = new CompilationUnit(compilerConfiguration, null, loader);
                    SourceUnit su = new TransformedSourceUnit(className.concat(GROOVITY_SOURCE_EXTENSION), transformed, compilerConfiguration, loader, new ErrorCollector(compilerConfiguration));
                    // errorCollector.sourceUnit = su;
                    cu.addSource(su);
                    // Don't compile all or extra class files get generated!
                    cu.compile(Phases.CLASS_GENERATION);
                    @SuppressWarnings("unchecked") GroovyClass[] gcs = (GroovyClass[]) cu.getClasses().toArray(new GroovyClass[0]);
                    Class<Script> scriptClass = loadGroovyClassesAndFindScript(loader, gcs, compilerTraits, traitsCopy, traits);
                    if (scriptClass != null) {
                        long time2 = System.currentTimeMillis();
                        log.info("Compiled Groovy Script: ".concat(source.getPath()) + " in " + (time2 - time1));
                    } else {
                        log.severe("UHOH!!  Unable to find main class for " + source.getPath());
                    }
                    if (jarPhases != null && jarPhases.contains(GroovityPhase.RUNTIME)) {
                        storeClasses(source, gcs);
                    }
                    if (log.isLoggable(Level.FINE)) {
                        log.fine("Registering script class " + scriptClass.getName() + " for name " + name);
                    }
                    newScripts.put(name, scriptClass);
                    newScriptDates.put(name, source.getLastModified());
                    scriptDependencies.put(name, dependencies);
                    scriptInits.put(name, hasInit((GroovityClassLoader) scriptClass.getClassLoader()));
                    if (log.isLoggable(Level.FINE)) {
                        log.fine("Found dependencies " + dependencies + " for script " + name);
                    }
                } catch (Throwable th) {
                    errorSources.put(nameCaseFixed, source);
                    log.log(Level.FINE, "Error compiling " + source.getPath(), th);
                    if (sourceCode != null && log.isLoggable(Level.FINE)) {
                        log.fine("Source code in trouble: \n" + sourceCode);
                    }
                    event.setError(th);
                } finally {
                    compileEvents.put(nameCaseFixed, event);
                }
            } else {
                // remove from memory and disk
                if (jarDirectory != null) {
                    deletedScripts.put(name, getClassesFile(source));
                } else {
                    deletedScripts.put(name, null);
                }
                if (scripts.containsKey(nameCaseFixed)) {
                    event.setChange(Change.remove);
                    compileEvents.put(fixCase(name), event);
                }
            }
        } catch (Exception e) {
            log.log(Level.SEVERE, "Error compiling groovy " + source.getPath(), e);
        }
    }
    if (!errorSources.isEmpty()) {
        boolean retry = (numErrors == 0 || errorSources.size() < numErrors);
        if (!retry) {
            // let's check if the compiling set of traits is missing anything
            for (Map.Entry<String, Class> entry : traits.entrySet()) {
                if (!compilerTraits.containsKey(entry.getKey())) {
                    retry = true;
                    compilerTraits.put(entry.getKey(), entry.getValue());
                }
            }
        }
        if (retry) {
            if (log.isLoggable(Level.FINE)) {
                log.fine("Retrying error compile on " + errorSources.size());
            }
            // retry failed compiles after all the rest in case they just need to pick up traits
            compileLoop(newScripts, newScriptDates, deletedScripts, scriptDependencies, scriptInits, force, init, errorSources.size(), compilerTraits, errorSources.values().toArray(new GroovitySource[0]));
        }
    }
}
Also used : LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) GroovyClass(org.codehaus.groovy.tools.GroovyClass) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) ErrorCollector(org.codehaus.groovy.control.ErrorCollector) SourceUnit(org.codehaus.groovy.control.SourceUnit) CompilerConfiguration(org.codehaus.groovy.control.CompilerConfiguration) GroovitySource(com.disney.groovity.source.GroovitySource) GroovityCompilerEvent(com.disney.groovity.compile.GroovityCompilerEvent) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) CompilationUnit(org.codehaus.groovy.control.CompilationUnit) Script(groovy.lang.Script) TransformedSource(com.disney.groovity.compile.GroovitySourceTransformer.TransformedSource) GroovityClassLoader(com.disney.groovity.compile.GroovityClassLoader) InvocationTargetException(java.lang.reflect.InvocationTargetException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) GroovyClass(org.codehaus.groovy.tools.GroovyClass) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 5 with GroovityClassLoader

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

the class Groovity method startClass.

protected void startClass(Class<?> clz) {
    if (clz != null) {
        final GroovityClassLoader gcl = (GroovityClassLoader) clz.getClassLoader();
        Class<?>[] cls = gcl.getLoadedClasses();
        for (Class<?> cl : cls) {
            Method m = null;
            try {
                m = cl.getDeclaredMethod(START);
            } 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("Started " + cl);
                    }
                } catch (InvocationTargetException e) {
                    Throwable t = e.getCause();
                    if (t instanceof Error) {
                        throw (Error) t;
                    }
                    log.log(Level.SEVERE, "Error starting " + cl, t);
                } catch (Exception e) {
                    log.log(Level.SEVERE, "Error starting " + cl, e);
                }
            }
        }
    }
}
Also used : Binding(groovy.lang.Binding) GroovityClassLoader(com.disney.groovity.compile.GroovityClassLoader) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) InvocationTargetException(java.lang.reflect.InvocationTargetException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) LinkedHashMap(java.util.LinkedHashMap) GroovyClass(org.codehaus.groovy.tools.GroovyClass)

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