001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.scripting.jruby;
018:
019: import java.io.IOException;
020:
021: import org.jruby.RubyException;
022: import org.jruby.exceptions.JumpException;
023: import org.jruby.exceptions.RaiseException;
024:
025: import org.springframework.beans.factory.BeanClassLoaderAware;
026: import org.springframework.scripting.ScriptCompilationException;
027: import org.springframework.scripting.ScriptFactory;
028: import org.springframework.scripting.ScriptSource;
029: import org.springframework.util.Assert;
030: import org.springframework.util.ClassUtils;
031:
032: /**
033: * {@link org.springframework.scripting.ScriptFactory} implementation
034: * for a JRuby script.
035: *
036: * <p>Typically used in combination with a
037: * {@link org.springframework.scripting.support.ScriptFactoryPostProcessor};
038: * see the latter's javadoc for a configuration example.
039: *
040: * @author Juergen Hoeller
041: * @author Rob Harrop
042: * @since 2.0
043: * @see JRubyScriptUtils
044: * @see org.springframework.scripting.support.ScriptFactoryPostProcessor
045: */
046: public class JRubyScriptFactory implements ScriptFactory,
047: BeanClassLoaderAware {
048:
049: private final String scriptSourceLocator;
050:
051: private final Class[] scriptInterfaces;
052:
053: private ClassLoader beanClassLoader = ClassUtils
054: .getDefaultClassLoader();
055:
056: /**
057: * Create a new JRubyScriptFactory for the given script source.
058: * @param scriptSourceLocator a locator that points to the source of the script.
059: * Interpreted by the post-processor that actually creates the script.
060: * @param scriptInterfaces the Java interfaces that the scripted object
061: * is supposed to implement
062: */
063: public JRubyScriptFactory(String scriptSourceLocator,
064: Class[] scriptInterfaces) {
065: Assert.hasText(scriptSourceLocator,
066: "'scriptSourceLocator' must not be empty");
067: Assert.notEmpty(scriptInterfaces,
068: "'scriptInterfaces' must not be empty");
069: this .scriptSourceLocator = scriptSourceLocator;
070: this .scriptInterfaces = scriptInterfaces;
071: }
072:
073: public void setBeanClassLoader(ClassLoader classLoader) {
074: this .beanClassLoader = classLoader;
075: }
076:
077: public String getScriptSourceLocator() {
078: return this .scriptSourceLocator;
079: }
080:
081: public Class[] getScriptInterfaces() {
082: return this .scriptInterfaces;
083: }
084:
085: /**
086: * JRuby scripts do require a config interface.
087: */
088: public boolean requiresConfigInterface() {
089: return true;
090: }
091:
092: /**
093: * Load and parse the JRuby script via JRubyScriptUtils.
094: * @see JRubyScriptUtils#createJRubyObject(String, Class[], ClassLoader)
095: */
096: public Object getScriptedObject(ScriptSource scriptSource,
097: Class[] actualInterfaces) throws IOException,
098: ScriptCompilationException {
099: try {
100: return JRubyScriptUtils.createJRubyObject(scriptSource
101: .getScriptAsString(), actualInterfaces,
102: this .beanClassLoader);
103: } catch (RaiseException ex) {
104: RubyException rubyEx = ex.getException();
105: String msg = (rubyEx != null && rubyEx.message != null) ? rubyEx.message
106: .toString()
107: : "Unexpected JRuby error";
108: throw new ScriptCompilationException(scriptSource, msg, ex);
109: } catch (JumpException ex) {
110: throw new ScriptCompilationException(scriptSource, ex);
111: }
112: }
113:
114: public Class getScriptedObjectType(ScriptSource scriptSource)
115: throws IOException, ScriptCompilationException {
116:
117: return null;
118: }
119:
120: public String toString() {
121: return "JRubyScriptFactory: script source locator ["
122: + this .scriptSourceLocator + "]";
123: }
124:
125: }
|