001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: ScriptLoaderGroovy.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.engine;
009:
010: import com.uwyn.rife.engine.exceptions.ElementImplementationInstantiationException;
011: import com.uwyn.rife.engine.exceptions.ElementImplementationNotFoundException;
012: import com.uwyn.rife.engine.exceptions.EngineException;
013: import com.uwyn.rife.resources.ResourceFinder;
014: import com.uwyn.rife.tools.InnerClassException;
015: import com.uwyn.rife.tools.InputStreamUser;
016: import groovy.lang.GroovyClassLoader;
017: import groovy.lang.GroovyCodeSource;
018: import java.io.InputStream;
019: import java.net.URL;
020: import java.security.AccessController;
021: import java.security.PrivilegedAction;
022: import java.util.HashMap;
023: import java.util.Map;
024:
025: class ScriptLoaderGroovy {
026: private ResourceFinder mResourceFinder = null;
027: private Map<String, Long> mScriptsModification = new HashMap<String, Long>();
028: private GroovyClassLoader mGroovyClassloader = null;
029:
030: ScriptLoaderGroovy(ResourceFinder resourceFinder) {
031: mResourceFinder = resourceFinder;
032: }
033:
034: ElementAware getInstance(final ElementInfo elementInfo)
035: throws EngineException {
036: ClassLoader parent = getClass().getClassLoader();
037: try {
038: if (null == mGroovyClassloader) {
039: mGroovyClassloader = new GroovyClassLoader(parent);
040: }
041:
042: URL resource = mResourceFinder.getResource(elementInfo
043: .getImplementation());
044: long current_modification = -1;
045: if (resource != null) {
046: current_modification = mResourceFinder
047: .getModificationTime(elementInfo
048: .getImplementation());
049: } else {
050: resource = mResourceFinder
051: .getResource(EngineClassLoader.DEFAULT_IMPLEMENTATIONS_PATH
052: + elementInfo.getImplementation());
053: current_modification = mResourceFinder
054: .getModificationTime(EngineClassLoader.DEFAULT_IMPLEMENTATIONS_PATH
055: + elementInfo.getImplementation());
056: }
057: if (null == resource) {
058: throw new ElementImplementationNotFoundException(
059: elementInfo.getDeclarationName(), elementInfo
060: .getImplementation(), null);
061: }
062:
063: Long previous_modification = mScriptsModification
064: .get(elementInfo.getImplementation());
065:
066: if (previous_modification != null
067: && previous_modification.longValue() != current_modification) {
068: mGroovyClassloader = new GroovyClassLoader(parent);
069: }
070:
071: Class groovyClass = mResourceFinder.useStream(resource,
072: new InputStreamUser() {
073: public Class useInputStream(
074: final InputStream stream)
075: throws InnerClassException {
076: try {
077: GroovyCodeSource gcs = (GroovyCodeSource) AccessController
078: .doPrivileged(new PrivilegedAction() {
079: public Object run() {
080: return new GroovyCodeSource(
081: stream,
082: elementInfo
083: .getImplementation(),
084: "/groovy/script");
085: }
086: });
087: gcs.setCachable(true);
088: return mGroovyClassloader
089: .parseClass(gcs);
090: } catch (Throwable e) {
091: throw new ElementImplementationInstantiationException(
092: elementInfo
093: .getDeclarationName(),
094: elementInfo.getImplementation(),
095: e);
096: }
097: }
098: });
099:
100: if (null == previous_modification
101: || previous_modification.longValue() != current_modification) {
102: mScriptsModification.put(elementInfo
103: .getImplementation(), current_modification);
104: }
105:
106: return (ElementAware) groovyClass.newInstance();
107: } catch (Throwable e) {
108: throw new ElementImplementationInstantiationException(
109: elementInfo.getDeclarationName(), elementInfo
110: .getImplementation(), e);
111: }
112: }
113: }
|