polishing
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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("-", "");
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user