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