/*
* Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
* $Id: ScriptLoaderGroovy.java 3918 2008-04-14 17:35:35Z gbevin $
*/
package com.uwyn.rife.engine;
import com.uwyn.rife.engine.exceptions.ElementImplementationInstantiationException;
import com.uwyn.rife.engine.exceptions.ElementImplementationNotFoundException;
import com.uwyn.rife.engine.exceptions.EngineException;
import com.uwyn.rife.resources.ResourceFinder;
import com.uwyn.rife.tools.exceptions.InnerClassException;
import com.uwyn.rife.tools.InputStreamUser;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;
import java.io.InputStream;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
class ScriptLoaderGroovy
{
private ResourceFinder mResourceFinder = null;
private Map<String, Long> mScriptsModification = new HashMap<String, Long>();
private GroovyClassLoader mGroovyClassloader = null;
ScriptLoaderGroovy(ResourceFinder resourceFinder)
{
mResourceFinder = resourceFinder;
}
ElementAware getInstance(final ElementInfo elementInfo)
throws EngineException
{
ClassLoader parent = getClass().getClassLoader();
try
{
if (null == mGroovyClassloader)
{
mGroovyClassloader = new GroovyClassLoader(parent);
}
URL resource = mResourceFinder.getResource(elementInfo.getImplementation());
long current_modification = -1;
if (resource != null)
{
current_modification = mResourceFinder.getModificationTime(elementInfo.getImplementation());
}
else
{
resource = mResourceFinder.getResource(EngineClassLoader.DEFAULT_IMPLEMENTATIONS_PATH+elementInfo.getImplementation());
current_modification = mResourceFinder.getModificationTime(EngineClassLoader.DEFAULT_IMPLEMENTATIONS_PATH+elementInfo.getImplementation());
}
if (null == resource)
{
throw new ElementImplementationNotFoundException(elementInfo.getDeclarationName(), elementInfo.getImplementation(), null);
}
Long previous_modification = mScriptsModification.get(elementInfo.getImplementation());
if (previous_modification != null &&
previous_modification.longValue() != current_modification)
{
mGroovyClassloader = new GroovyClassLoader(parent);
}
Class groovyClass = mResourceFinder.useStream(resource, new InputStreamUser() {
public Class useInputStream(final InputStream stream)
throws InnerClassException
{
try
{
GroovyCodeSource gcs = (GroovyCodeSource) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return new GroovyCodeSource(stream, elementInfo.getImplementation(), "/groovy/script");
}
});
gcs.setCachable(true);
return mGroovyClassloader.parseClass(gcs);
}
catch (Throwable e)
{
throw new ElementImplementationInstantiationException(elementInfo.getDeclarationName(), elementInfo.getImplementation(), e);
}
}
});
if (null == previous_modification ||
previous_modification.longValue() != current_modification)
{
mScriptsModification.put(elementInfo.getImplementation(), current_modification);
}
return (ElementAware)groovyClass.newInstance();
}
catch (Throwable e)
{
throw new ElementImplementationInstantiationException(elementInfo.getDeclarationName(), elementInfo.getImplementation(), e);
}
}
}