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());
}
}
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;
}
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;
}
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]));
}
}
}
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);
}
}
}
}
}
Aggregations