polishing

This commit is contained in:
Mark Fisher
2010-11-04 16:10:55 -04:00
parent 2695566a8b
commit 24b08f2602
10 changed files with 79 additions and 53 deletions

View File

@@ -31,11 +31,13 @@ public abstract class AbstractScriptExecutingMessageProcessor<T> implements Mess
public final T processMessage(Message<?> message) {
try {
return this.executeScript(getScriptSource(message), message);
} catch (Exception e) {
}
catch (Exception e) {
throw new MessageHandlingException(message, "failed to execute script", e);
}
}
/**
* Subclasses must implement this method to create a script source, optionally using the message to locate or
* create the script.

View File

@@ -22,10 +22,15 @@ import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.scripting.groovy.GroovyObjectCustomizer;
/**
* @author Dave Syer
* @since 2.0
*/
public class BeanFactoryContextBindingCustomizer implements GroovyObjectCustomizer, BeanFactoryAware {
private ListableBeanFactory beanFactory;
public BeanFactoryContextBindingCustomizer() {
this(null);
}
@@ -34,17 +39,18 @@ public class BeanFactoryContextBindingCustomizer implements GroovyObjectCustomiz
setBeanFactory(beanFactory);
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory instanceof ListableBeanFactory ? (ListableBeanFactory) beanFactory : null;
this.beanFactory = (beanFactory instanceof ListableBeanFactory) ? (ListableBeanFactory) beanFactory : null;
}
public void customize(GroovyObject goo) {
if (beanFactory != null) {
if (this.beanFactory != null) {
Binding binding = ((Script) goo).getBinding();
for (String name : beanFactory.getBeanDefinitionNames()) {
binding.setVariable(name, beanFactory.getBean(name));
for (String name : this.beanFactory.getBeanDefinitionNames()) {
binding.setVariable(name, this.beanFactory.getBean(name));
}
}
}
}
}

View File

@@ -48,6 +48,11 @@ public class GroovyScriptExecutingMessageProcessor extends AbstractScriptExecuti
}
@Override
protected ScriptSource getScriptSource(Message<?> message) {
return this.scriptSource;
}
@Override
protected Object executeScript(ScriptSource scriptSource, Message<?> message) throws Exception {
synchronized (this) {
@@ -57,9 +62,4 @@ public class GroovyScriptExecutingMessageProcessor extends AbstractScriptExecuti
}
}
@Override
protected ScriptSource getScriptSource(Message<?> message) {
return scriptSource;
}
}

View File

@@ -34,22 +34,24 @@ public class GroovyScriptPayloadMessageProcessor extends AbstractScriptExecuting
private final GroovyObjectCustomizer customizer;
public GroovyScriptPayloadMessageProcessor() {
this((GroovyObjectCustomizer)null);
this((GroovyObjectCustomizer) null);
}
public GroovyScriptPayloadMessageProcessor(Map<String, ?> map) {
this(new MapContextBindingCustomizer(map));
}
public GroovyScriptPayloadMessageProcessor(GroovyObjectCustomizer customizer) {
this.customizer = customizer;
}
@Override
protected ScriptSource getScriptSource(Message<?> message) {
Object payload = message.getPayload();
Assert.isInstanceOf(String.class, payload, "Payload must be String containing Groovy script.");
Assert.isInstanceOf(String.class, payload, "Payload must be a String containing a Groovy script.");
String className = generateScriptName(message);
return new StaticScriptSource((String) payload, className);
}
@@ -63,7 +65,7 @@ public class GroovyScriptPayloadMessageProcessor extends AbstractScriptExecuting
Object result = scriptFactory.getScriptedObject(scriptSource, null);
return (result instanceof GString) ? result.toString() : result;
}
protected String generateScriptName(Message<?> message) {
// Don't use the same script (class) name for all invocations by default
return getClass().getSimpleName() + message.getHeaders().getId().toString().replaceAll("-", "");

View File

@@ -22,23 +22,28 @@ import java.util.Map;
import org.springframework.scripting.groovy.GroovyObjectCustomizer;
import org.springframework.util.Assert;
/**
* @author Dave Syer
* @since 2.0
*/
public class MapContextBindingCustomizer implements GroovyObjectCustomizer {
private final Map<String, ?> map;
public MapContextBindingCustomizer(Map<String, ?> map) {
this.map = map;
}
public void customize(GroovyObject goo) {
Assert.state(goo instanceof Script, "Expected a Script");
if (this.map != null) {
Binding binding = ((Script) goo).getBinding();
for (String key : map.keySet()) {
binding.setVariable(key, map.get(key));
for (String key : this.map.keySet()) {
binding.setVariable(key, this.map.get(key));
}
}
}
}
}

View File

@@ -24,18 +24,20 @@ import org.springframework.scripting.groovy.GroovyObjectCustomizer;
import org.springframework.util.Assert;
/**
* A groovy object customizer used internally by the groovy message processors. Not public because the customizer is not
* the best API for groovy context binding, but it's what we have in Spring right now.
*
* @since 2.0
* A groovy object customizer used internally by the groovy message processors.
* Not public because the customizer is not the best API for groovy context binding,
* but it's what we have in Spring right now.
*
* @author Dave Syer
*
* @since 2.0
*/
class MessageContextBindingCustomizer implements GroovyObjectCustomizer {
private volatile Message<?> message;
private final GroovyObjectCustomizer customizer;
public MessageContextBindingCustomizer() {
this((GroovyObjectCustomizer) null);
}
@@ -48,14 +50,15 @@ class MessageContextBindingCustomizer implements GroovyObjectCustomizer {
this.customizer = customizer;
}
public void setMessage(Message<?> message) {
this.message = message;
}
public void customize(GroovyObject goo) {
Assert.state(goo instanceof Script, "Expected a Script");
if (customizer != null) {
customizer.customize(goo);
if (this.customizer != null) {
this.customizer.customize(goo);
}
if (this.message != null) {
Binding binding = ((Script) goo).getBinding();
@@ -63,4 +66,5 @@ class MessageContextBindingCustomizer implements GroovyObjectCustomizer {
binding.setVariable("headers", this.message.getHeaders());
}
}
}
}

View File

@@ -22,24 +22,27 @@ import org.springframework.integration.handler.ServiceActivatingHandler;
* FactoryBean for creating {@link MessageHandler} instances to handle a message as a Groovy Script.
*
* @author Dave Syer
*
* @since 2.0
*/
public class GroovyControlBusFactoryBean extends AbstractSimpleMessageHandlerFactoryBean {
private volatile Long sendTimeout;
private final GroovyScriptPayloadMessageProcessor processor;
public GroovyControlBusFactoryBean(GroovyScriptPayloadMessageProcessor processor) {
this.processor = processor;
}
public void setSendTimeout(Long sendTimeout) {
this.sendTimeout = sendTimeout;
}
@Override
protected MessageHandler createHandler() {
return this.configureHandler(new ServiceActivatingHandler(processor));
return this.configureHandler(new ServiceActivatingHandler(this.processor));
}
private ServiceActivatingHandler configureHandler(ServiceActivatingHandler handler) {

View File

@@ -13,16 +13,15 @@
package org.springframework.integration.groovy.config;
import org.w3c.dom.Element;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractConsumerEndpointParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.groovy.BeanFactoryContextBindingCustomizer;
import org.springframework.integration.groovy.GroovyScriptPayloadMessageProcessor;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author Dave Syer
@@ -42,13 +41,15 @@ public class GroovyControlBusParser extends AbstractConsumerEndpointParser {
}
protected BeanMetadataElement getMessageProcessorBeanDefinition(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(GroovyScriptPayloadMessageProcessor.class);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
"org.springframework.integration.groovy.GroovyScriptPayloadMessageProcessor");
String customizerAttr = element.getAttribute(CUSTOMIZER_ATTRIBUTE);
if (StringUtils.hasText(customizerAttr)) {
builder.addConstructorArgReference(customizerAttr.trim());
} else {
builder.addConstructorArgValue(new RootBeanDefinition(BeanFactoryContextBindingCustomizer.class));
}
else {
builder.addConstructorArgValue(new RootBeanDefinition(
"org.springframework.integration.groovy.BeanFactoryContextBindingCustomizer"));
}
return builder.getBeanDefinition();
}

View File

@@ -33,6 +33,7 @@ import org.springframework.util.xml.DomUtils;
public class GroovyScriptParser extends AbstractSingleBeanDefinitionParser {
private static final String LOCATION_ATTRIBUTE = "location";
private static final String REFRESH_CHECK_DELAY_ATTRIBUTE = "refresh-check-delay";
@@ -61,7 +62,8 @@ public class GroovyScriptParser extends AbstractSingleBeanDefinitionParser {
resourceScriptSourceBuilder.addConstructorArgValue(element.getAttribute(LOCATION_ATTRIBUTE));
if (StringUtils.hasText(refreshDelayText)) {
resourceScriptSourceBuilder.addConstructorArgValue(refreshDelayText);
} else {
}
else {
resourceScriptSourceBuilder.addConstructorArgValue(-1L);
}
return resourceScriptSourceBuilder.getBeanDefinition();

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.groovy.config;
import java.io.IOException;
@@ -26,7 +27,6 @@ import org.springframework.scripting.support.ResourceScriptSource;
* @author Dave Syer
* @author Oleg Zhurakousky
* @since 2.0
*
*/
public class RefreshableResourceScriptSource implements ScriptSource {
@@ -34,40 +34,41 @@ public class RefreshableResourceScriptSource implements ScriptSource {
private final ResourceScriptSource source;
private AtomicLong lastModifiedChecked = new AtomicLong(System.currentTimeMillis());
private final AtomicLong lastModifiedChecked = new AtomicLong(System.currentTimeMillis());
private volatile String script;
private String script;
public RefreshableResourceScriptSource(Resource resource, long refreshDelay) {
this.refreshDelay = refreshDelay;
this.source = new ResourceScriptSource(resource);
try {
this.script = source.getScriptAsString();
this.script = this.source.getScriptAsString();
}
catch (IOException e) {
lastModifiedChecked.set(0);
this.lastModifiedChecked.set(0);
}
}
public String getScriptAsString() throws IOException {
this.script = source.getScriptAsString();
return script;
return this.script;
}
public String suggestedClassName() {
return this.source.suggestedClassName();
}
public boolean isModified() {
if (refreshDelay < 0) {
if (this.refreshDelay < 0) {
return false;
}
long time = System.currentTimeMillis();
if (refreshDelay == 0 || (time - lastModifiedChecked.get()) > refreshDelay) {
lastModifiedChecked.set(time);
return source.isModified();
if (this.refreshDelay == 0 || (time - this.lastModifiedChecked.get()) > this.refreshDelay) {
this.lastModifiedChecked.set(time);
return this.source.isModified();
}
return false;
}
public String suggestedClassName() {
return source.suggestedClassName();
}
}