You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2012/12/20 08:05:05 UTC

svn commit: r1424345 - in /camel/trunk/components/camel-groovy/src: main/java/org/apache/camel/groovy/ main/java/org/apache/camel/groovy/converter/ main/java/org/apache/camel/groovy/dataformat/ main/java/org/apache/camel/groovy/extend/ main/java/org/ap...

Author: ningjiang
Date: Thu Dec 20 07:05:05 2012
New Revision: 1424345

URL: http://svn.apache.org/viewvc?rev=1424345&view=rev
Log:
CAMEL-5898 Extend Java DSL for Groovy routes, with thanks to christian

Added:
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/converter/
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/converter/TypeConverter.java
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/AbstractXmlDataFormat.java
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/XmlParserDataFormat.java
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/XmlSlurperDataFormat.java
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/CamelGroovyMethods.java
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureAggregationStrategy.java
      - copied, changed from r1424261, camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureExpression.java
      - copied, changed from r1424261, camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureProcessor.java
      - copied, changed from r1424261, camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureSupport.java
      - copied, changed from r1424261, camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java
    camel/trunk/components/camel-groovy/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
    camel/trunk/components/camel-groovy/src/main/resources/META-INF/services/org/apache/camel/TypeConverter
    camel/trunk/components/camel-groovy/src/main/resources/dsld/
    camel/trunk/components/camel-groovy/src/main/resources/dsld/CamelGroovyMethods.dsld
    camel/trunk/components/camel-groovy/src/main/resources/gdsl/
    camel/trunk/components/camel-groovy/src/main/resources/gdsl/CamelGroovyMethods.gdsl
    camel/trunk/components/camel-groovy/src/test/groovy/
    camel/trunk/components/camel-groovy/src/test/groovy/org/
    camel/trunk/components/camel-groovy/src/test/groovy/org/apache/
    camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/
    camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/
    camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/
    camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/CamelGroovyMethodsTest.groovy
    camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureAggregationStrategyTest.groovy
    camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureExpressionTest.groovy
    camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureProcessorTest.groovy
Modified:
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/CamelGroovyMethods.java
    camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java

Added: camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/converter/TypeConverter.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/converter/TypeConverter.java?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/converter/TypeConverter.java (added)
+++ camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/converter/TypeConverter.java Thu Dec 20 07:05:05 2012
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.groovy.converter;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+
+import groovy.lang.GString;
+import org.apache.camel.Converter;
+import org.apache.camel.Exchange;
+import org.apache.camel.converter.IOConverter;
+import org.apache.camel.converter.ObjectConverter;
+
+/**
+ * TypeConverter for Groovy GStrings.
+ */
+@Converter
+public final class TypeConverter {
+
+    private TypeConverter() {
+
+    }
+
+    @Converter
+    public static InputStream toInputStream(GString value, Exchange exchange) throws IOException {
+        return IOConverter.toInputStream(value.toString(), exchange);
+    }
+
+    @Converter
+    public static byte[] toByteArray(GString value, Exchange exchange) throws IOException {
+        return IOConverter.toByteArray(value.toString(), exchange);
+    }
+
+    @Converter
+    public static StringReader toReader(GString value) {
+        return IOConverter.toReader(value.toString());
+    }
+
+    @Converter
+    public static char toChar(GString value) {
+        return ObjectConverter.toChar(value.toString());
+    }
+
+    @Converter
+    public static Integer toInteger(GString value) {
+        return ObjectConverter.toInteger(value.toString());
+    }
+
+    @Converter
+    public static Long toLong(GString value) {
+        return ObjectConverter.toLong(value.toString());
+    }
+
+    @Converter
+    public static Float toFloat(GString value) {
+        return ObjectConverter.toFloat(value.toString());
+    }
+
+    @Converter
+    public static Double toDouble(GString value) {
+        return ObjectConverter.toDouble(value.toString());
+    }
+
+    @Converter
+    public static Boolean toBoolean(GString value) {
+        return ObjectConverter.toBoolean(value.toString());
+    }
+}

Added: camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/AbstractXmlDataFormat.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/AbstractXmlDataFormat.java?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/AbstractXmlDataFormat.java (added)
+++ camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/AbstractXmlDataFormat.java Thu Dec 20 07:05:05 2012
@@ -0,0 +1,93 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.groovy.dataformat;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import groovy.xml.FactorySupport;
+import org.apache.camel.spi.DataFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Common attributes and methods for XmlParser and XmlSlurper usage.
+ */
+public abstract class AbstractXmlDataFormat implements DataFormat {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractXmlDataFormat.class);
+    private static final ErrorHandler DEFAULT_HANDLER = new DefaultErrorHandler();
+
+    private boolean namespaceAware = true;
+    private boolean keepWhitespace;
+    private ErrorHandler errorHandler = DEFAULT_HANDLER;
+
+    public AbstractXmlDataFormat(boolean namespaceAware) {
+        this.namespaceAware = namespaceAware;
+    }
+
+    protected SAXParser newSaxParser() throws Exception {
+        SAXParserFactory factory = FactorySupport.createSaxParserFactory();
+        factory.setNamespaceAware(namespaceAware);
+        factory.setValidating(false);
+        return factory.newSAXParser();
+    }
+
+    public ErrorHandler getErrorHandler() {
+        return errorHandler;
+    }
+
+    public boolean isNamespaceAware() {
+        return namespaceAware;
+    }
+
+    public void setNamespaceAware(boolean namespaceAware) {
+        this.namespaceAware = namespaceAware;
+    }
+
+    public boolean isKeepWhitespace() {
+        return keepWhitespace;
+    }
+
+    public void setKeepWhitespace(boolean keepWhitespace) {
+        this.keepWhitespace = keepWhitespace;
+    }
+
+    private static class DefaultErrorHandler implements ErrorHandler {
+
+        @Override
+        public void warning(SAXParseException exception) throws SAXException {
+            LOG.warn("Warning occured during parsing", exception);
+        }
+
+        @Override
+        public void error(SAXParseException exception) throws SAXException {
+            throw new SAXException(exception);
+        }
+
+        @Override
+        public void fatalError(SAXParseException exception) throws SAXException {
+            throw new SAXException(exception);
+        }
+
+    }
+
+}

Added: camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/XmlParserDataFormat.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/XmlParserDataFormat.java?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/XmlParserDataFormat.java (added)
+++ camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/XmlParserDataFormat.java Thu Dec 20 07:05:05 2012
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.groovy.dataformat;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+import groovy.util.Node;
+import groovy.util.XmlNodePrinter;
+import groovy.util.XmlParser;
+import org.apache.camel.Exchange;
+
+/**
+ * DataFormat for using groovy.util.XmlParser as parser and renderer for XML
+ * data
+ */
+public class XmlParserDataFormat extends AbstractXmlDataFormat {
+
+    public XmlParserDataFormat() {
+        this(true);
+    }
+
+    public XmlParserDataFormat(boolean namespaceAware) {
+        super(namespaceAware);
+    }
+
+    @Override
+    public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception {
+        newPrinter(stream).print((Node) graph);
+    }
+
+    @Override
+    public Object unmarshal(Exchange exchange, InputStream stream) throws Exception {
+        return newParser().parse(stream);
+    }
+
+    private XmlParser newParser() throws Exception {
+        XmlParser xmlParser = new XmlParser(newSaxParser());
+        xmlParser.setErrorHandler(getErrorHandler());
+        xmlParser.setTrimWhitespace(!isKeepWhitespace());
+        return xmlParser;
+    }
+
+    private XmlNodePrinter newPrinter(OutputStream stream) {
+        XmlNodePrinter xmlNodePrinter = new XmlNodePrinter(new PrintWriter(stream));
+        xmlNodePrinter.setNamespaceAware(isNamespaceAware());
+        return xmlNodePrinter;
+    }
+
+}

Added: camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/XmlSlurperDataFormat.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/XmlSlurperDataFormat.java?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/XmlSlurperDataFormat.java (added)
+++ camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/dataformat/XmlSlurperDataFormat.java Thu Dec 20 07:05:05 2012
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.groovy.dataformat;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import groovy.util.XmlSlurper;
+import org.apache.camel.Exchange;
+
+/**
+ * DataFormat for using groovy.util.XmlSlurper as parser for XML data
+ */
+public class XmlSlurperDataFormat extends AbstractXmlDataFormat {
+
+    public XmlSlurperDataFormat() {
+        this(true);
+    }
+
+    public XmlSlurperDataFormat(boolean namespaceAware) {
+        super(namespaceAware);
+    }
+
+    @Override
+    public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception {
+        throw new UnsupportedOperationException("XmlSlurper does not support marshalling");
+    }
+
+    @Override
+    public Object unmarshal(Exchange exchange, InputStream stream) throws Exception {
+        return newSlurper().parse(stream);
+    }
+
+    private XmlSlurper newSlurper() throws Exception {
+        XmlSlurper slurper = new XmlSlurper(newSaxParser());
+        slurper.setErrorHandler(getErrorHandler());
+        slurper.setKeepWhitespace(isKeepWhitespace());
+        return slurper;
+    }
+
+}

Added: camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/CamelGroovyMethods.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/CamelGroovyMethods.java?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/CamelGroovyMethods.java (added)
+++ camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/CamelGroovyMethods.java Thu Dec 20 07:05:05 2012
@@ -0,0 +1,379 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.groovy.extend;
+
+import java.lang.reflect.Method;
+
+import groovy.lang.Closure;
+import org.apache.camel.Exchange;
+import org.apache.camel.Expression;
+import org.apache.camel.Predicate;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.DataFormatClause;
+import org.apache.camel.builder.ExpressionClause;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.groovy.dataformat.XmlParserDataFormat;
+import org.apache.camel.groovy.dataformat.XmlSlurperDataFormat;
+import org.apache.camel.model.AggregateDefinition;
+import org.apache.camel.model.CatchDefinition;
+import org.apache.camel.model.ChoiceDefinition;
+import org.apache.camel.model.DataFormatDefinition;
+import org.apache.camel.model.DelayDefinition;
+import org.apache.camel.model.DynamicRouterDefinition;
+import org.apache.camel.model.FilterDefinition;
+import org.apache.camel.model.IdempotentConsumerDefinition;
+import org.apache.camel.model.InterceptDefinition;
+import org.apache.camel.model.InterceptSendToEndpointDefinition;
+import org.apache.camel.model.LoopDefinition;
+import org.apache.camel.model.MulticastDefinition;
+import org.apache.camel.model.OnCompletionDefinition;
+import org.apache.camel.model.OnExceptionDefinition;
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.model.RecipientListDefinition;
+import org.apache.camel.model.ResequenceDefinition;
+import org.apache.camel.model.RoutingSlipDefinition;
+import org.apache.camel.model.SplitDefinition;
+import org.apache.camel.model.ThrottleDefinition;
+import org.apache.camel.model.TryDefinition;
+import org.apache.camel.model.WireTapDefinition;
+import org.apache.camel.processor.aggregate.AggregationStrategy;
+import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.support.ExpressionSupport;
+
+
+
+/**
+ * Extension class containing static methods that mainly allow to use Closures
+ * instead of Predicates, Expressions, Processors, or AggregationStrategies
+ */
+public final class CamelGroovyMethods {
+    private CamelGroovyMethods() {
+        // Utility Class
+    }
+
+    // Extension Methods that use Closures to encapsulate logic
+
+    public static ProcessorDefinition<?> process(ProcessorDefinition<?> self,
+            Closure<?> processorLogic) {
+        return self.process(toProcessor(processorLogic));
+    }
+
+    public WireTapDefinition<?> newExchange(WireTapDefinition<?> self,
+            Closure<?> processorLogic) {
+        return self.newExchange(toProcessor(processorLogic));
+    }
+
+    public static OnExceptionDefinition onRedelivery(OnExceptionDefinition self,
+            Closure<Exchange> processorLogic) {
+        return self.onRedelivery(toProcessor(processorLogic));
+    }
+
+    public static ProcessorDefinition<?> enrich(ProcessorDefinition<?> self, String resourceUri,
+            Closure<Exchange> aggregationLogic) {
+        return self.enrich(resourceUri, toAggregationStrategy(aggregationLogic));
+    }
+
+    public static ProcessorDefinition<?> pollEnrich(ProcessorDefinition<?> self,
+            String resourceUri, Closure<Exchange> aggregationLogic) {
+        return self.pollEnrich(resourceUri, toAggregationStrategy(aggregationLogic));
+    }
+
+    public static ProcessorDefinition<?> pollEnrich(ProcessorDefinition<?> self,
+            String resourceUri, long timeout, Closure<Exchange> aggregationLogic) {
+        return self.pollEnrich(resourceUri, timeout, toAggregationStrategy(aggregationLogic));
+    }
+
+    public static MulticastDefinition aggregationStrategy(MulticastDefinition self,
+            Closure<Exchange> aggregationLogic) {
+        return self.aggregationStrategy(toAggregationStrategy(aggregationLogic));
+    }
+
+    public static RecipientListDefinition<?> aggregationStrategy(RecipientListDefinition<?> self,
+            Closure<Exchange> aggregationLogic) {
+        return self.aggregationStrategy(toAggregationStrategy(aggregationLogic));
+    }
+
+    public static SplitDefinition aggregationStrategy(SplitDefinition self,
+            Closure<Exchange> aggregationLogic) {
+        return self.aggregationStrategy(toAggregationStrategy(aggregationLogic));
+    }
+
+    public static AggregateDefinition aggregationStrategy(AggregateDefinition self,
+            Closure<Exchange> aggregationLogic) {
+        return self.aggregationStrategy(toAggregationStrategy(aggregationLogic));
+    }
+
+    public static MulticastDefinition onPrepare(MulticastDefinition self,
+            Closure<Exchange> processorLogic) {
+        return self.onPrepare(toProcessor(processorLogic));
+    }
+
+    public static RecipientListDefinition<?> onPrepare(RecipientListDefinition<?> self,
+            Closure<Exchange> processorLogic) {
+        return self.onPrepare(toProcessor(processorLogic));
+    }
+
+    public static SplitDefinition onPrepare(SplitDefinition self, Closure<Exchange> processorLogic) {
+        return self.onPrepare(toProcessor(processorLogic));
+    }
+
+    public static WireTapDefinition<?> onPrepare(WireTapDefinition<?> self,
+            Closure<Exchange> processorLogic) {
+        return self.onPrepare(toProcessor(processorLogic));
+    }
+
+    // Extension Methods that use Closures as expressions
+
+    public static ProcessorDefinition<?> transform(ProcessorDefinition<?> self,
+            Closure<?> expression) {
+        return self.transform(toExpression(expression));
+    }
+
+    public static ProcessorDefinition<?> setProperty(ProcessorDefinition<?> self, String name,
+            Closure<?> expression) {
+        return self.setProperty(name, toExpression(expression));
+    }
+
+    public static ProcessorDefinition<?> setHeader(ProcessorDefinition<?> self, String name,
+            Closure<?> expression) {
+        return self.setHeader(name, toExpression(expression));
+    }
+
+    public static ProcessorDefinition<?> setBody(ProcessorDefinition<?> self, Closure<?> expression) {
+        return self.setBody(toExpression(expression));
+    }
+
+    public static ProcessorDefinition<?> setFaultBody(ProcessorDefinition<?> self,
+            Closure<?> expression) {
+        return self.setFaultBody(toExpression(expression));
+    }
+
+    public static ProcessorDefinition<?> sort(ProcessorDefinition<?> self, Closure<?> expression) {
+        return self.sort(toExpression(expression));
+    }
+
+    public static IdempotentConsumerDefinition idempotentConsumer(ProcessorDefinition<?> self,
+            Closure<?> expression) {
+        return self.idempotentConsumer(toExpression(expression));
+    }
+
+    public static IdempotentConsumerDefinition idempotentConsumer(ProcessorDefinition<?> self,
+            IdempotentRepository<?> rep, Closure<?> expression) {
+        return self.idempotentConsumer(toExpression(expression), rep);
+    }
+
+    public static RecipientListDefinition<?> recipientList(ProcessorDefinition<?> self,
+            Closure<?> recipients) {
+        return self.recipientList(toExpression(recipients));
+    }
+
+    public static RecipientListDefinition<?> recipientList(ProcessorDefinition<?> self,
+            String delimiter, Closure<?> recipients) {
+        return self.recipientList(toExpression(recipients), delimiter);
+    }
+
+    public static RoutingSlipDefinition<?> routingSlip(ProcessorDefinition<?> self,
+            Closure<?> recipients) {
+        return self.routingSlip(toExpression(recipients));
+    }
+
+    public static RoutingSlipDefinition<?> routingSlip(ProcessorDefinition<?> self,
+            String delimiter, Closure<?> recipients) {
+        return self.routingSlip(toExpression(recipients), delimiter);
+    }
+
+    public static DynamicRouterDefinition<?> dynamicRouter(ProcessorDefinition<?> self,
+            Closure<?> expression) {
+        return self.dynamicRouter(toExpression(expression));
+    }
+
+    public static SplitDefinition split(ProcessorDefinition<?> self, Closure<?> expression) {
+        return self.split(toExpression(expression));
+    }
+
+    public static ResequenceDefinition resequence(ProcessorDefinition<?> self, Closure<?> expression) {
+        return self.resequence(toExpression(expression));
+    }
+
+    public static AggregateDefinition aggregate(ProcessorDefinition<?> self,
+            Closure<?> correlationExpression) {
+        return self.aggregate(toExpression(correlationExpression));
+    }
+
+    public static AggregateDefinition completionSize(AggregateDefinition self, Closure<?> expression) {
+        return self.completionSize(toExpression(expression));
+    }
+
+    public static AggregateDefinition completionTimeout(AggregateDefinition self,
+            Closure<?> expression) {
+        return self.completionTimeout(toExpression(expression));
+    }
+
+    public static DelayDefinition delay(ProcessorDefinition<?> self, Closure<?> expression) {
+        return self.delay(toExpression(expression));
+    }
+
+    public static ThrottleDefinition throttle(ProcessorDefinition<?> self, Closure<?> expression) {
+        return self.throttle(toExpression(expression));
+    }
+
+    public static LoopDefinition loop(ProcessorDefinition<?> self, Closure<?> expression) {
+        return self.loop(toExpression(expression));
+    }
+
+    public static WireTapDefinition<?> newExchangeBody(WireTapDefinition<?> self,
+            Closure<?> expression) {
+        return self.newExchangeBody(toExpression(expression));
+    }
+
+    public static WireTapDefinition<?> newExchangeHeader(WireTapDefinition<?> self, String header,
+            Closure<?> expression) {
+        return self.newExchangeHeader(header, toExpression(expression));
+    }
+
+    // Extension Methods that use Closures as predicates
+
+    public static FilterDefinition filter(ProcessorDefinition<?> self, Closure<?> predicate) {
+        return self.filter(toExpression(predicate));
+    }
+
+    public static ProcessorDefinition<?> validate(ProcessorDefinition<?> self, Closure<?> predicate) {
+        return self.validate((Predicate) toExpression(predicate));
+    }
+
+    public static ChoiceDefinition when(ChoiceDefinition self, Closure<?> predicate) {
+        return self.when(toExpression(predicate));
+    }
+
+    public static TryDefinition onWhen(TryDefinition self, Closure<?> predicate) {
+        return self.onWhen(toExpression(predicate));
+    }
+
+    public static OnExceptionDefinition onWhen(OnExceptionDefinition self, Closure<?> predicate) {
+        return self.onWhen(toExpression(predicate));
+    }
+
+    public static OnExceptionDefinition handled(OnExceptionDefinition self, Closure<?> predicate) {
+        return self.handled((Predicate) toExpression(predicate));
+    }
+
+    public static OnExceptionDefinition continued(OnExceptionDefinition self, Closure<?> predicate) {
+        return self.continued((Predicate) toExpression(predicate));
+    }
+
+    public static OnExceptionDefinition retryWhile(OnExceptionDefinition self, Closure<?> predicate) {
+        return self.retryWhile(toExpression(predicate));
+    }
+
+    public static OnCompletionDefinition onWhen(OnCompletionDefinition self, Closure<?> predicate) {
+        return self.onWhen(toExpression(predicate));
+    }
+
+    public static CatchDefinition onWhen(CatchDefinition self, Closure<?> predicate) {
+        return self.onWhen(toExpression(predicate));
+    }
+
+    public static AggregateDefinition completionPredicate(AggregateDefinition self,
+            Closure<?> predicate) {
+        return self.completionPredicate(toExpression(predicate));
+    }
+
+    public static InterceptDefinition when(InterceptDefinition self, Closure<?> predicate) {
+        return self.when(toExpression(predicate));
+    }
+
+    public static InterceptSendToEndpointDefinition when(InterceptSendToEndpointDefinition self,
+            Closure<?> predicate) {
+        return self.when(toExpression(predicate));
+    }
+
+    // Bridging generic attribution of expressions, predicates etc.
+
+    public static AggregationStrategy aggregator(RouteBuilder self,
+            Closure<Exchange> aggregationLogic) {
+        return toAggregationStrategy(aggregationLogic);
+    }
+
+    public static Expression expression(RouteBuilder self, Closure<?> expression) {
+        return toExpression(expression);
+    }
+
+    public static Predicate predicate(RouteBuilder self, Closure<?> predicate) {
+        return toExpression(predicate);
+    }
+
+    public static Processor processor(RouteBuilder self, Closure<Exchange> processor) {
+        return toProcessor(processor);
+    }
+
+    public static <T> T expression(ExpressionClause<T> self, Closure<?> expression) {
+        return self.expression(toExpression(expression));
+    }
+
+    // Private Helpers
+
+    static ExpressionSupport toExpression(final Closure<?> closure) {
+        return new ClosureExpression(closure);
+    }
+
+    static Processor toProcessor(final Closure<?> closure) {
+        return new ClosureProcessor(closure);
+    }
+
+    static AggregationStrategy toAggregationStrategy(final Closure<Exchange> closure) {
+        return new ClosureAggregationStrategy(closure);
+    }
+
+    // Groovy-specific data formats
+
+    public static ProcessorDefinition<?> gnode(DataFormatClause<?> self, boolean namespaceAware) {
+        return dataFormat(self, parser(namespaceAware));
+    }
+
+    public static ProcessorDefinition<?> gnode(DataFormatClause<?> self) {
+        return gnode(self, true);
+    }
+
+    public static ProcessorDefinition<?> gpath(DataFormatClause<?> self, boolean namespaceAware) {
+        return dataFormat(self, slurper(namespaceAware));
+    }
+
+    public static ProcessorDefinition<?> gpath(DataFormatClause<?> self) {
+        return gpath(self, true);
+    }
+
+    private static DataFormatDefinition slurper(boolean namespaceAware) {
+        return new DataFormatDefinition(new XmlSlurperDataFormat(namespaceAware));
+    }
+
+    private static DataFormatDefinition parser(boolean namespaceAware) {
+        return new DataFormatDefinition(new XmlParserDataFormat(namespaceAware));
+    }
+
+    // DataFormatClause.dataFormat(DataFormatDefinition) is private...
+    private static ProcessorDefinition<?> dataFormat(DataFormatClause<?> self,
+            DataFormatDefinition format) {
+        try {
+            Method m = self.getClass().getDeclaredMethod("dataFormat", DataFormatDefinition.class);
+            m.setAccessible(true);
+            return (ProcessorDefinition<?>) m.invoke(self, format);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Unknown DataFormat operation", e);
+        }
+    }
+
+}

Copied: camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureAggregationStrategy.java (from r1424261, camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureAggregationStrategy.java?p2=camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureAggregationStrategy.java&p1=camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java&r1=1424261&r2=1424345&rev=1424345&view=diff
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java (original)
+++ camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureAggregationStrategy.java Thu Dec 20 07:05:05 2012
@@ -14,32 +14,26 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.language.groovy;
+package org.apache.camel.groovy.extend;
 
-import java.io.InputStreamReader;
-import groovy.lang.GroovyShell;
-import org.apache.camel.CamelContext;
-import org.apache.camel.builder.RouteBuilder;
+import groovy.lang.Closure;
 
-/**
- * @version 
- */
-public abstract class GroovyRouteBuilder extends RouteBuilder {
-    public GroovyRouteBuilder() {
-        init();
+import org.apache.camel.Exchange;
+import org.apache.camel.processor.aggregate.AggregationStrategy;
+
+class ClosureAggregationStrategy implements AggregationStrategy {
+
+    private Closure<Exchange> closure;
+
+    ClosureAggregationStrategy(Closure<Exchange> closure) {
+        super();
+        this.closure = closure;
     }
 
-    public GroovyRouteBuilder(CamelContext context) {
-        super(context);
-        init();
+    @Override
+    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
+        return ClosureSupport.call(closure, oldExchange, newExchange);
     }
 
-    private void init() {
-        ClassLoader loader = getClass().getClassLoader();
-        GroovyShell shell = new GroovyShell(loader);
-        shell.evaluate(new InputStreamReader(loader.getResourceAsStream("org/apache/camel/language/groovy/ConfigureCamel.groovy")));
 
-        // TODO compile Groovy as part of build!
-        //new ConfigureCamel().run();
-    }
-}
+}
\ No newline at end of file

Copied: camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureExpression.java (from r1424261, camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureExpression.java?p2=camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureExpression.java&p1=camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java&r1=1424261&r2=1424345&rev=1424345&view=diff
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java (original)
+++ camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureExpression.java Thu Dec 20 07:05:05 2012
@@ -14,32 +14,34 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.language.groovy;
+package org.apache.camel.groovy.extend;
 
-import java.io.InputStreamReader;
-import groovy.lang.GroovyShell;
-import org.apache.camel.CamelContext;
-import org.apache.camel.builder.RouteBuilder;
+import groovy.lang.Closure;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.support.ExpressionSupport;
 
 /**
- * @version 
+ * Bridges a closure to ExpressionSupport
  */
-public abstract class GroovyRouteBuilder extends RouteBuilder {
-    public GroovyRouteBuilder() {
-        init();
-    }
+class ClosureExpression extends ExpressionSupport {
+
+    private Closure<?> closure;
 
-    public GroovyRouteBuilder(CamelContext context) {
-        super(context);
-        init();
+    ClosureExpression(Closure<?> closure) {
+        super();
+        this.closure = closure;
     }
 
-    private void init() {
-        ClassLoader loader = getClass().getClassLoader();
-        GroovyShell shell = new GroovyShell(loader);
-        shell.evaluate(new InputStreamReader(loader.getResourceAsStream("org/apache/camel/language/groovy/ConfigureCamel.groovy")));
+    @Override
+    public <T> T evaluate(Exchange exchange, Class<T> type) {
+        Object result = ClosureSupport.call(closure, exchange);
+        return exchange.getContext().getTypeConverter().convertTo(type, result);
+    }
 
-        // TODO compile Groovy as part of build!
-        //new ConfigureCamel().run();
+    @Override
+    protected String assertionFailureMessage(Exchange exchange) {
+        return closure.toString();
     }
-}
+
+}
\ No newline at end of file

Copied: camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureProcessor.java (from r1424261, camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureProcessor.java?p2=camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureProcessor.java&p1=camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java&r1=1424261&r2=1424345&rev=1424345&view=diff
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java (original)
+++ camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureProcessor.java Thu Dec 20 07:05:05 2012
@@ -14,32 +14,27 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.language.groovy;
+package org.apache.camel.groovy.extend;
 
-import java.io.InputStreamReader;
-import groovy.lang.GroovyShell;
-import org.apache.camel.CamelContext;
-import org.apache.camel.builder.RouteBuilder;
+import groovy.lang.Closure;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
 
 /**
- * @version 
+ * Bridges a Closure to a Processor
  */
-public abstract class GroovyRouteBuilder extends RouteBuilder {
-    public GroovyRouteBuilder() {
-        init();
-    }
+class ClosureProcessor implements Processor {
 
-    public GroovyRouteBuilder(CamelContext context) {
-        super(context);
-        init();
-    }
+    private Closure<?> closure;
 
-    private void init() {
-        ClassLoader loader = getClass().getClassLoader();
-        GroovyShell shell = new GroovyShell(loader);
-        shell.evaluate(new InputStreamReader(loader.getResourceAsStream("org/apache/camel/language/groovy/ConfigureCamel.groovy")));
+    ClosureProcessor(Closure<?> closure) {
+        this.closure = closure;
+    }
 
-        // TODO compile Groovy as part of build!
-        //new ConfigureCamel().run();
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        ClosureSupport.call(closure, exchange);
     }
-}
+
+}
\ No newline at end of file

Copied: camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureSupport.java (from r1424261, camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureSupport.java?p2=camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureSupport.java&p1=camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java&r1=1424261&r2=1424345&rev=1424345&view=diff
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java (original)
+++ camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/groovy/extend/ClosureSupport.java Thu Dec 20 07:05:05 2012
@@ -14,32 +14,26 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.language.groovy;
+package org.apache.camel.groovy.extend;
 
-import java.io.InputStreamReader;
-import groovy.lang.GroovyShell;
-import org.apache.camel.CamelContext;
-import org.apache.camel.builder.RouteBuilder;
+import groovy.lang.Closure;
 
-/**
- * @version 
- */
-public abstract class GroovyRouteBuilder extends RouteBuilder {
-    public GroovyRouteBuilder() {
-        init();
-    }
+import org.codehaus.groovy.runtime.InvokerInvocationException;
 
-    public GroovyRouteBuilder(CamelContext context) {
-        super(context);
-        init();
-    }
+final class ClosureSupport {
 
-    private void init() {
-        ClassLoader loader = getClass().getClassLoader();
-        GroovyShell shell = new GroovyShell(loader);
-        shell.evaluate(new InputStreamReader(loader.getResourceAsStream("org/apache/camel/language/groovy/ConfigureCamel.groovy")));
+    private ClosureSupport() {
+    }
 
-        // TODO compile Groovy as part of build!
-        //new ConfigureCamel().run();
+    static <T> T call(Closure<T> closure, Object... args) {
+        try {
+            return closure.call(args);
+        } catch (InvokerInvocationException e) {
+            if (e.getCause() instanceof RuntimeException) {
+                throw (RuntimeException) e.getCause();
+            } else {
+                throw e;
+            }
+        }
     }
 }

Modified: camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/CamelGroovyMethods.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/CamelGroovyMethods.java?rev=1424345&r1=1424344&r2=1424345&view=diff
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/CamelGroovyMethods.java (original)
+++ camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/CamelGroovyMethods.java Thu Dec 20 07:05:05 2012
@@ -25,6 +25,8 @@ import org.apache.camel.support.Expressi
 
 /**
  * @version 
+ * @deprecated see {@link org.apache.camel.groovy.extend.CamelGroovyMethods} which is
+ * used automatically
  */
 public final class CamelGroovyMethods {
     private CamelGroovyMethods() {

Modified: camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java?rev=1424345&r1=1424344&r2=1424345&view=diff
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java (original)
+++ camel/trunk/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyRouteBuilder.java Thu Dec 20 07:05:05 2012
@@ -16,30 +16,20 @@
  */
 package org.apache.camel.language.groovy;
 
-import java.io.InputStreamReader;
-import groovy.lang.GroovyShell;
 import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
 
 /**
- * @version 
+ * @deprecated the standard {@link RouteBuilder} can be used to write
+ * Groovy routes.
  */
 public abstract class GroovyRouteBuilder extends RouteBuilder {
     public GroovyRouteBuilder() {
-        init();
+        super();
     }
 
     public GroovyRouteBuilder(CamelContext context) {
         super(context);
-        init();
     }
 
-    private void init() {
-        ClassLoader loader = getClass().getClassLoader();
-        GroovyShell shell = new GroovyShell(loader);
-        shell.evaluate(new InputStreamReader(loader.getResourceAsStream("org/apache/camel/language/groovy/ConfigureCamel.groovy")));
-
-        // TODO compile Groovy as part of build!
-        //new ConfigureCamel().run();
-    }
 }

Added: camel/trunk/components/camel-groovy/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule (added)
+++ camel/trunk/components/camel-groovy/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule Thu Dec 20 07:05:05 2012
@@ -0,0 +1,4 @@
+moduleName=camel-groovy
+moduleVersion=2.11
+extensionClasses=org.apache.camel.groovy.extend.CamelGroovyMethods
+staticExtensionClasses=
\ No newline at end of file

Added: camel/trunk/components/camel-groovy/src/main/resources/META-INF/services/org/apache/camel/TypeConverter
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/resources/META-INF/services/org/apache/camel/TypeConverter?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/resources/META-INF/services/org/apache/camel/TypeConverter (added)
+++ camel/trunk/components/camel-groovy/src/main/resources/META-INF/services/org/apache/camel/TypeConverter Thu Dec 20 07:05:05 2012
@@ -0,0 +1 @@
+org.apache.camel.groovy.converter.TypeConverter
\ No newline at end of file

Added: camel/trunk/components/camel-groovy/src/main/resources/dsld/CamelGroovyMethods.dsld
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/resources/dsld/CamelGroovyMethods.dsld?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/resources/dsld/CamelGroovyMethods.dsld (added)
+++ camel/trunk/components/camel-groovy/src/main/resources/dsld/CamelGroovyMethods.dsld Thu Dec 20 07:05:05 2012
@@ -0,0 +1,93 @@
+ currentType(subType('org.apache.camel.model.ProcessorDefinition')).accept {
+    method name : 'process', type : 'org.apache.camel.model.ProcessorDefinition', params: [processorLogic : 'groovy.lang.Closure']
+    method name : 'enrich', type : 'org.apache.camel.model.ProcessorDefinition', params: [resourceUri : 'java.lang.String', aggregationLogic : 'groovy.lang.Closure']
+    method name : 'pollEnrich', type : 'org.apache.camel.model.ProcessorDefinition', params: [resourceUri : 'java.lang.String', aggregationLogic : 'groovy.lang.Closure']
+    method name : 'pollEnrich', type : 'org.apache.camel.model.ProcessorDefinition', params: [resourceUri : 'java.lang.String', timeout : 'long', aggregationLogic : 'groovy.lang.Closure']
+    method name : 'transform', type : 'org.apache.camel.model.ProcessorDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'setProperty', type : 'org.apache.camel.model.ProcessorDefinition', params: [name : 'java.lang.String', expression : 'groovy.lang.Closure']
+    method name : 'setHeader', type : 'org.apache.camel.model.ProcessorDefinition', params: [name : 'java.lang.String', expression : 'groovy.lang.Closure']
+    method name : 'setBody', type : 'org.apache.camel.model.ProcessorDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'setFaultBody', type : 'org.apache.camel.model.ProcessorDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'sort', type : 'org.apache.camel.model.ProcessorDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'idempotentConsumer', type : 'org.apache.camel.model.IdempotentConsumerDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'idempotentConsumer', type : 'org.apache.camel.model.IdempotentConsumerDefinition', params: [rep : 'org.apache.camel.spi.IdempotentRepository', expression : 'groovy.lang.Closure']
+    method name : 'recipientList', type : 'org.apache.camel.model.RecipientListDefinition', params: [recipients : 'groovy.lang.Closure']
+    method name : 'recipientList', type : 'org.apache.camel.model.RecipientListDefinition', params: [delimiter : 'java.lang.String', recipients : 'groovy.lang.Closure']
+    method name : 'routingSlip', type : 'org.apache.camel.model.RoutingSlipDefinition', params: [recipients : 'groovy.lang.Closure']
+    method name : 'routingSlip', type : 'org.apache.camel.model.RoutingSlipDefinition', params: [delimiter : 'java.lang.String', recipients : 'groovy.lang.Closure']
+    method name : 'dynamicRouter', type : 'org.apache.camel.model.DynamicRouterDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'split', type : 'org.apache.camel.model.SplitDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'resequence', type : 'org.apache.camel.model.ResequenceDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'aggregate', type : 'org.apache.camel.model.AggregateDefinition', params: [correlationExpression : 'groovy.lang.Closure']
+    method name : 'delay', type : 'org.apache.camel.model.DelayDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'throttle', type : 'org.apache.camel.model.ThrottleDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'loop', type : 'org.apache.camel.model.LoopDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'filter', type : 'org.apache.camel.model.FilterDefinition', params: [predicate : 'groovy.lang.Closure']
+    method name : 'validate', type : 'org.apache.camel.model.ProcessorDefinition', params: [predicate : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.groovy.extend.CamelGroovyMethods')).accept {
+    method name : 'newExchange', type : 'org.apache.camel.model.WireTapDefinition', params: [self : 'org.apache.camel.model.WireTapDefinition', processorLogic : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.OnExceptionDefinition')).accept {
+    method name : 'onRedelivery', type : 'org.apache.camel.model.OnExceptionDefinition', params: [processorLogic : 'groovy.lang.Closure']
+    method name : 'onWhen', type : 'org.apache.camel.model.OnExceptionDefinition', params: [predicate : 'groovy.lang.Closure']
+    method name : 'handled', type : 'org.apache.camel.model.OnExceptionDefinition', params: [predicate : 'groovy.lang.Closure']
+    method name : 'continued', type : 'org.apache.camel.model.OnExceptionDefinition', params: [predicate : 'groovy.lang.Closure']
+    method name : 'retryWhile', type : 'org.apache.camel.model.OnExceptionDefinition', params: [predicate : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.MulticastDefinition')).accept {
+    method name : 'aggregationStrategy', type : 'org.apache.camel.model.MulticastDefinition', params: [aggregationLogic : 'groovy.lang.Closure']
+    method name : 'onPrepare', type : 'org.apache.camel.model.MulticastDefinition', params: [processorLogic : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.RecipientListDefinition')).accept {
+    method name : 'aggregationStrategy', type : 'org.apache.camel.model.RecipientListDefinition', params: [aggregationLogic : 'groovy.lang.Closure']
+    method name : 'onPrepare', type : 'org.apache.camel.model.RecipientListDefinition', params: [processorLogic : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.SplitDefinition')).accept {
+    method name : 'aggregationStrategy', type : 'org.apache.camel.model.SplitDefinition', params: [aggregationLogic : 'groovy.lang.Closure']
+    method name : 'onPrepare', type : 'org.apache.camel.model.SplitDefinition', params: [processorLogic : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.AggregateDefinition')).accept {
+    method name : 'aggregationStrategy', type : 'org.apache.camel.model.AggregateDefinition', params: [aggregationLogic : 'groovy.lang.Closure']
+    method name : 'completionSize', type : 'org.apache.camel.model.AggregateDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'completionTimeout', type : 'org.apache.camel.model.AggregateDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'completionPredicate', type : 'org.apache.camel.model.AggregateDefinition', params: [predicate : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.WireTapDefinition')).accept {
+    method name : 'onPrepare', type : 'org.apache.camel.model.WireTapDefinition', params: [processorLogic : 'groovy.lang.Closure']
+    method name : 'newExchangeBody', type : 'org.apache.camel.model.WireTapDefinition', params: [expression : 'groovy.lang.Closure']
+    method name : 'newExchangeHeader', type : 'org.apache.camel.model.WireTapDefinition', params: [header : 'java.lang.String', expression : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.ChoiceDefinition')).accept {
+    method name : 'when', type : 'org.apache.camel.model.ChoiceDefinition', params: [predicate : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.TryDefinition')).accept {
+    method name : 'onWhen', type : 'org.apache.camel.model.TryDefinition', params: [predicate : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.OnCompletionDefinition')).accept {
+    method name : 'onWhen', type : 'org.apache.camel.model.OnCompletionDefinition', params: [predicate : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.CatchDefinition')).accept {
+    method name : 'onWhen', type : 'org.apache.camel.model.CatchDefinition', params: [predicate : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.InterceptDefinition')).accept {
+    method name : 'when', type : 'org.apache.camel.model.InterceptDefinition', params: [predicate : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.model.InterceptSendToEndpointDefinition')).accept {
+    method name : 'when', type : 'org.apache.camel.model.InterceptSendToEndpointDefinition', params: [predicate : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.builder.RouteBuilder')).accept {
+    method name : 'aggregator', type : 'org.apache.camel.processor.aggregate.AggregationStrategy', params: [aggregationLogic : 'groovy.lang.Closure']
+    method name : 'expression', type : 'org.apache.camel.Expression', params: [expression : 'groovy.lang.Closure']
+    method name : 'predicate', type : 'org.apache.camel.Predicate', params: [predicate : 'groovy.lang.Closure']
+    method name : 'processor', type : 'org.apache.camel.Processor', params: [processor : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.builder.ExpressionClause')).accept {
+    method name : 'expression', type : 'T', params: [expression : 'groovy.lang.Closure']
+}
+ currentType(subType('org.apache.camel.builder.DataFormatClause')).accept {
+    method name : 'gnode', type : 'org.apache.camel.model.ProcessorDefinition', params: [namespaceAware : 'boolean']
+    method name : 'gnode', type : 'org.apache.camel.model.ProcessorDefinition'
+    method name : 'gpath', type : 'org.apache.camel.model.ProcessorDefinition', params: [namespaceAware : 'boolean']
+    method name : 'gpath', type : 'org.apache.camel.model.ProcessorDefinition'
+}

Added: camel/trunk/components/camel-groovy/src/main/resources/gdsl/CamelGroovyMethods.gdsl
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/main/resources/gdsl/CamelGroovyMethods.gdsl?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/main/resources/gdsl/CamelGroovyMethods.gdsl (added)
+++ camel/trunk/components/camel-groovy/src/main/resources/gdsl/CamelGroovyMethods.gdsl Thu Dec 20 07:05:05 2012
@@ -0,0 +1,93 @@
+contributor([context(ctype: 'org.apache.camel.model.ProcessorDefinition')]) {
+    method name: 'process', type: 'org.apache.camel.model.ProcessorDefinition', params: [processorLogic: 'groovy.lang.Closure']
+    method name: 'enrich', type: 'org.apache.camel.model.ProcessorDefinition', params: [resourceUri: 'java.lang.String', aggregationLogic: 'groovy.lang.Closure']
+    method name: 'pollEnrich', type: 'org.apache.camel.model.ProcessorDefinition', params: [resourceUri: 'java.lang.String', aggregationLogic: 'groovy.lang.Closure']
+    method name: 'pollEnrich', type: 'org.apache.camel.model.ProcessorDefinition', params: [resourceUri: 'java.lang.String', timeout: 'long', aggregationLogic: 'groovy.lang.Closure']
+    method name: 'transform', type: 'org.apache.camel.model.ProcessorDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'setProperty', type: 'org.apache.camel.model.ProcessorDefinition', params: [name: 'java.lang.String', expression: 'groovy.lang.Closure']
+    method name: 'setHeader', type: 'org.apache.camel.model.ProcessorDefinition', params: [name: 'java.lang.String', expression: 'groovy.lang.Closure']
+    method name: 'setBody', type: 'org.apache.camel.model.ProcessorDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'setFaultBody', type: 'org.apache.camel.model.ProcessorDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'sort', type: 'org.apache.camel.model.ProcessorDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'idempotentConsumer', type: 'org.apache.camel.model.IdempotentConsumerDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'idempotentConsumer', type: 'org.apache.camel.model.IdempotentConsumerDefinition', params: [rep: 'org.apache.camel.spi.IdempotentRepository', expression: 'groovy.lang.Closure']
+    method name: 'recipientList', type: 'org.apache.camel.model.RecipientListDefinition', params: [recipients: 'groovy.lang.Closure']
+    method name: 'recipientList', type: 'org.apache.camel.model.RecipientListDefinition', params: [delimiter: 'java.lang.String', recipients: 'groovy.lang.Closure']
+    method name: 'routingSlip', type: 'org.apache.camel.model.RoutingSlipDefinition', params: [recipients: 'groovy.lang.Closure']
+    method name: 'routingSlip', type: 'org.apache.camel.model.RoutingSlipDefinition', params: [delimiter: 'java.lang.String', recipients: 'groovy.lang.Closure']
+    method name: 'dynamicRouter', type: 'org.apache.camel.model.DynamicRouterDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'split', type: 'org.apache.camel.model.SplitDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'resequence', type: 'org.apache.camel.model.ResequenceDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'aggregate', type: 'org.apache.camel.model.AggregateDefinition', params: [correlationExpression: 'groovy.lang.Closure']
+    method name: 'delay', type: 'org.apache.camel.model.DelayDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'throttle', type: 'org.apache.camel.model.ThrottleDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'loop', type: 'org.apache.camel.model.LoopDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'filter', type: 'org.apache.camel.model.FilterDefinition', params: [predicate: 'groovy.lang.Closure']
+    method name: 'validate', type: 'org.apache.camel.model.ProcessorDefinition', params: [predicate: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.groovy.extend.CamelGroovyMethods')]) {
+    method name: 'newExchange', type: 'org.apache.camel.model.WireTapDefinition', params: [self: 'org.apache.camel.model.WireTapDefinition', processorLogic: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.OnExceptionDefinition')]) {
+    method name: 'onRedelivery', type: 'org.apache.camel.model.OnExceptionDefinition', params: [processorLogic: 'groovy.lang.Closure']
+    method name: 'onWhen', type: 'org.apache.camel.model.OnExceptionDefinition', params: [predicate: 'groovy.lang.Closure']
+    method name: 'handled', type: 'org.apache.camel.model.OnExceptionDefinition', params: [predicate: 'groovy.lang.Closure']
+    method name: 'continued', type: 'org.apache.camel.model.OnExceptionDefinition', params: [predicate: 'groovy.lang.Closure']
+    method name: 'retryWhile', type: 'org.apache.camel.model.OnExceptionDefinition', params: [predicate: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.MulticastDefinition')]) {
+    method name: 'aggregationStrategy', type: 'org.apache.camel.model.MulticastDefinition', params: [aggregationLogic: 'groovy.lang.Closure']
+    method name: 'onPrepare', type: 'org.apache.camel.model.MulticastDefinition', params: [processorLogic: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.RecipientListDefinition')]) {
+    method name: 'aggregationStrategy', type: 'org.apache.camel.model.RecipientListDefinition', params: [aggregationLogic: 'groovy.lang.Closure']
+    method name: 'onPrepare', type: 'org.apache.camel.model.RecipientListDefinition', params: [processorLogic: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.SplitDefinition')]) {
+    method name: 'aggregationStrategy', type: 'org.apache.camel.model.SplitDefinition', params: [aggregationLogic: 'groovy.lang.Closure']
+    method name: 'onPrepare', type: 'org.apache.camel.model.SplitDefinition', params: [processorLogic: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.AggregateDefinition')]) {
+    method name: 'aggregationStrategy', type: 'org.apache.camel.model.AggregateDefinition', params: [aggregationLogic: 'groovy.lang.Closure']
+    method name: 'completionSize', type: 'org.apache.camel.model.AggregateDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'completionTimeout', type: 'org.apache.camel.model.AggregateDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'completionPredicate', type: 'org.apache.camel.model.AggregateDefinition', params: [predicate: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.WireTapDefinition')]) {
+    method name: 'onPrepare', type: 'org.apache.camel.model.WireTapDefinition', params: [processorLogic: 'groovy.lang.Closure']
+    method name: 'newExchangeBody', type: 'org.apache.camel.model.WireTapDefinition', params: [expression: 'groovy.lang.Closure']
+    method name: 'newExchangeHeader', type: 'org.apache.camel.model.WireTapDefinition', params: [header: 'java.lang.String', expression: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.ChoiceDefinition')]) {
+    method name: 'when', type: 'org.apache.camel.model.ChoiceDefinition', params: [predicate: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.TryDefinition')]) {
+    method name: 'onWhen', type: 'org.apache.camel.model.TryDefinition', params: [predicate: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.OnCompletionDefinition')]) {
+    method name: 'onWhen', type: 'org.apache.camel.model.OnCompletionDefinition', params: [predicate: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.CatchDefinition')]) {
+    method name: 'onWhen', type: 'org.apache.camel.model.CatchDefinition', params: [predicate: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.InterceptDefinition')]) {
+    method name: 'when', type: 'org.apache.camel.model.InterceptDefinition', params: [predicate: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.model.InterceptSendToEndpointDefinition')]) {
+    method name: 'when', type: 'org.apache.camel.model.InterceptSendToEndpointDefinition', params: [predicate: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.builder.RouteBuilder')]) {
+    method name: 'aggregator', type: 'org.apache.camel.processor.aggregate.AggregationStrategy', params: [aggregationLogic: 'groovy.lang.Closure']
+    method name: 'expression', type: 'org.apache.camel.Expression', params: [expression: 'groovy.lang.Closure']
+    method name: 'predicate', type: 'org.apache.camel.Predicate', params: [predicate: 'groovy.lang.Closure']
+    method name: 'processor', type: 'org.apache.camel.Processor', params: [processor: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.builder.ExpressionClause')]) {
+    method name: 'expression', type: 'T', params: [expression: 'groovy.lang.Closure']
+}
+contributor([context(ctype: 'org.apache.camel.builder.DataFormatClause')]) {
+    method name: 'gnode', type: 'org.apache.camel.model.ProcessorDefinition', params: [namespaceAware: 'boolean']
+    method name: 'gnode', type: 'org.apache.camel.model.ProcessorDefinition'
+    method name: 'gpath', type: 'org.apache.camel.model.ProcessorDefinition', params: [namespaceAware: 'boolean']
+    method name: 'gpath', type: 'org.apache.camel.model.ProcessorDefinition'
+}

Added: camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/CamelGroovyMethodsTest.groovy
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/CamelGroovyMethodsTest.groovy?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/CamelGroovyMethodsTest.groovy (added)
+++ camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/CamelGroovyMethodsTest.groovy Thu Dec 20 07:05:05 2012
@@ -0,0 +1,235 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.groovy.extend
+
+import org.apache.camel.EndpointInject
+import org.apache.camel.Exchange
+import org.apache.camel.ProducerTemplate
+import org.apache.camel.builder.RouteBuilder
+import org.apache.camel.component.mock.MockEndpoint
+import org.apache.camel.test.junit4.CamelTestSupport
+import org.junit.Test
+
+
+/**
+ * Test a few DSL extensions. 
+ */
+class CamelGroovyMethodsTest extends CamelTestSupport {
+
+    private static final String HELLO = 'Hello'
+    private static final String WORLD = 'World'
+    
+    @EndpointInject(uri = 'mock:test1')
+    private MockEndpoint resultEndpoint;
+    @EndpointInject(uri = 'mock:test2')
+    private MockEndpoint otherEndpoint;
+    
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        
+        def aggregation = { Exchange original, Exchange resource ->
+                        original.in.body += resource.in.body
+                        original
+                    }
+        
+        return new RouteBuilder() {
+
+            @Override
+            public void configure() throws Exception {
+                
+                from('direct:test1')
+                    .enrich('direct:enrich') { Exchange original, Exchange resource -> 
+                        original.in.body += resource.in.body
+                        original
+                    }
+                    .to('mock:test1')
+                
+                from('direct:enrich')
+                    .transform(constant(WORLD))
+                    
+                from('direct:test2')
+                    .pollEnrich('seda:enrich', aggregation)
+                    .to('mock:test1')
+                    
+                from('direct:test3')
+                    .process { Exchange e ->
+                        e.in.with {
+                            body = HELLO
+                            headers[HELLO] = WORLD
+                        }
+                    }
+                    .to('mock:test1')
+                    
+                from('direct:test4')
+                    .setHeader(HELLO) { Exchange e ->
+                        e.in.body.reverse()
+                    }
+                    .to('mock:test1')
+                    
+                from('direct:test5')
+                    .setProperty(HELLO) { Exchange e ->
+                        e.in.body.reverse()
+                    }
+                    .to('mock:test1')
+                    
+                from('direct:test6')
+                    .transform { Exchange e ->
+                        e.in.body.reverse()
+                    }
+                    .to('mock:test1')
+                    
+                from('direct:test7')
+                    .setBody { Exchange e ->
+                        e.in.body.reverse()
+                    }
+                    .to('mock:test1')
+                    
+                from('direct:test8')
+                    .unmarshal().gpath()
+                    // XmlSlurper proceeds to first node
+                    .transform { it.in.body.World.text() }
+                    .to('mock:test1')
+                    
+                from('direct:test9')
+                    .unmarshal().gnode()
+                    // XmlParser proceeds to first node
+                    .transform { it.in.body.World.text() }
+                    .to('mock:test1')
+                    
+                from('direct:test10')
+                    .marshal().gnode()
+                    .convertBodyTo(String)
+                    .to('mock:test1')
+                    
+                from('direct:test11')
+                    .choice()
+                        .when { it.in.body == HELLO }.to('mock:test1')
+                        .otherwise().to('mock:test2')
+
+                from('direct:test12')
+                    .setHeader(HELLO).expression { Exchange e ->
+                        e.in.body.reverse()
+                    }
+                    .to('mock:test1')
+
+            }
+            
+        }
+    }
+
+    @Test
+    void testClosureEnricherAggregation() {
+        resultEndpoint.expectedBodiesReceived(HELLO + WORLD)
+        template.sendBody('direct:test1', HELLO)
+        resultEndpoint.assertIsSatisfied()
+    }
+    
+    @Test
+    void testClosurePollingEnricherAggregation() {
+        resultEndpoint.expectedBodiesReceived(HELLO + WORLD)
+        template.sendBody('seda:enrich', WORLD)
+        template.sendBody('direct:test2', HELLO)
+        resultEndpoint.assertIsSatisfied()
+    }
+    
+    @Test
+    void testClosureProcessor() {
+        resultEndpoint.expectedBodiesReceived(HELLO)
+        resultEndpoint.expectedHeaderReceived(HELLO, WORLD)
+        template.sendBody('direct:test3', '')
+        resultEndpoint.assertIsSatisfied()
+    }
+    
+    @Test
+    void testClosureSetHeader() {
+        resultEndpoint.expectedHeaderReceived(HELLO, WORLD)
+        template.sendBody('direct:test4', WORLD.reverse())
+        resultEndpoint.assertIsSatisfied()
+    }
+
+    @Test
+    void testClosureSetHeaderWithExpressionClause() {
+        resultEndpoint.expectedHeaderReceived(HELLO, WORLD)
+        template.sendBody('direct:test4', WORLD.reverse())
+        resultEndpoint.assertIsSatisfied()
+    }
+    
+    @Test
+    void testClosureSetProperty() {
+        resultEndpoint.expectedPropertyReceived(HELLO, WORLD)
+        template.sendBody('direct:test5', WORLD.reverse())
+        resultEndpoint.assertIsSatisfied()
+    }
+
+    @Test
+    void testClosureTransformer() {
+        resultEndpoint.expectedBodiesReceived(HELLO)
+        template.sendBody('direct:test6', HELLO.reverse())
+        resultEndpoint.assertIsSatisfied()
+    }
+    
+    @Test
+    void testClosureSetBody() {
+        resultEndpoint.expectedBodiesReceived(HELLO)
+        template.sendBody('direct:test7', HELLO.reverse())
+        resultEndpoint.assertIsSatisfied()
+    }
+    
+    @Test
+    void testClosureChoice1() {
+        resultEndpoint.expectedBodiesReceived(HELLO)
+        otherEndpoint.expectedMessageCount(0)
+        template.sendBody('direct:test11', HELLO)
+        resultEndpoint.assertIsSatisfied()
+        otherEndpoint.assertIsSatisfied()
+    }
+    
+    @Test
+    void testClosureChoice2() {
+        resultEndpoint.expectedMessageCount(0)
+        otherEndpoint.expectedBodiesReceived(WORLD)
+        template.sendBody('direct:test11', WORLD)
+        resultEndpoint.assertIsSatisfied()
+        otherEndpoint.assertIsSatisfied()
+    }
+    
+    @Test
+    void testXmlSlurper() {
+        String text = "How are you?"
+        resultEndpoint.expectedBodiesReceived(text)
+        template.sendBody('direct:test8', "<Hello><World>${text}</World></Hello>")
+        resultEndpoint.assertIsSatisfied()
+    }
+    
+    @Test
+    void testXmlParser() {
+        String text = "How are you?"
+        resultEndpoint.expectedBodiesReceived(text)
+        template.sendBody('direct:test9', "<Hello><World>${text}</World></Hello>")
+        resultEndpoint.assertIsSatisfied()
+    }
+    
+    @Test
+    void testXmlPrinter() {
+        String text = "<Hello><World>How are you?</World></Hello>"
+        Node parsed = new XmlParser().parseText(text)
+        resultEndpoint.expectedMessageCount(1)
+        template.sendBody('direct:test10', parsed)
+        // The created XML differs in terms of white spaces and line feeds.
+        assertEquals(text.replaceAll('\\s+', ''), resultEndpoint.exchanges[0].in.body.replaceAll('\\s+', ''))
+    }
+}

Added: camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureAggregationStrategyTest.groovy
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureAggregationStrategyTest.groovy?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureAggregationStrategyTest.groovy (added)
+++ camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureAggregationStrategyTest.groovy Thu Dec 20 07:05:05 2012
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.groovy.extend
+
+import static org.junit.Assert.*
+import static org.apache.camel.groovy.extend.CamelGroovyMethods.toAggregationStrategy
+
+import org.apache.camel.CamelContext
+import org.apache.camel.Exchange
+import org.apache.camel.impl.DefaultCamelContext
+import org.apache.camel.impl.DefaultExchange
+import org.junit.Before
+import org.junit.Test
+
+
+class ClosureAggregationStrategyTest {
+
+    private Exchange exchange1
+    private Exchange exchange2
+    private static final String HELLO = "Hello"
+    private static final String WORLD = "World"
+    
+    @Before
+    public void setUp() throws Exception {
+        CamelContext context = new DefaultCamelContext()
+        exchange1 = new DefaultExchange(context);
+        exchange2 = new DefaultExchange(context);
+    }
+    
+    @Test
+    public void testAggregationStrategy() {
+        exchange1.in.body = HELLO
+        exchange2.in.body = WORLD
+        ClosureAggregationStrategy cas = toAggregationStrategy { Exchange oldExchange, Exchange newExchange ->
+            newExchange.in.body = newExchange.in.body + ' ' + oldExchange.in.body
+            newExchange
+        }
+        assertEquals(HELLO + ' ' + WORLD, cas.aggregate(exchange2, exchange1).in.body)  
+    }
+
+}

Added: camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureExpressionTest.groovy
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureExpressionTest.groovy?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureExpressionTest.groovy (added)
+++ camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureExpressionTest.groovy Thu Dec 20 07:05:05 2012
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.groovy.extend
+
+import static org.junit.Assert.*
+import static org.apache.camel.groovy.extend.CamelGroovyMethods.toExpression
+
+import org.apache.camel.Exchange
+import org.apache.camel.impl.DefaultCamelContext
+import org.apache.camel.impl.DefaultExchange
+import org.junit.Before
+import org.junit.Test
+
+
+class ClosureExpressionTest {
+
+    private Exchange exchange
+    private static final String HELLO = "Hello"
+    
+    @Before
+    public void setUp() throws Exception {
+        exchange = new DefaultExchange(new DefaultCamelContext());
+        exchange.in.body = HELLO
+    }
+    
+    @Test
+    public void testAsExpression() {
+        ClosureExpression expression = toExpression { Exchange exchange ->
+            exchange.in.body
+        }        
+        assertEquals(HELLO, expression.evaluate(exchange))       
+    }
+    
+    @Test
+    public void testAsPredicate() {
+        ClosureExpression expressionTrue = toExpression { Exchange exchange ->
+            exchange.in.body == HELLO
+        }
+        assertTrue(expressionTrue.evaluate(exchange))
+        ClosureExpression expressionFalse = toExpression { Exchange exchange ->
+            exchange.in.body != HELLO
+        }
+        assertFalse(expressionFalse.evaluate(exchange))    
+    }
+
+    @Test
+    public void testClosureException() {
+        String unknownProperty = 'Gablorg'
+        ClosureExpression expression = toExpression { Exchange exchange ->
+            exchange."${unknownProperty}"
+        }
+        try {
+            expression.evaluate(exchange)
+        } catch (MissingPropertyException e) {
+            assertTrue(e.message.contains(unknownProperty))
+        }
+    }
+}

Added: camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureProcessorTest.groovy
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureProcessorTest.groovy?rev=1424345&view=auto
==============================================================================
--- camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureProcessorTest.groovy (added)
+++ camel/trunk/components/camel-groovy/src/test/groovy/org/apache/camel/groovy/extend/ClosureProcessorTest.groovy Thu Dec 20 07:05:05 2012
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.groovy.extend
+
+import static org.junit.Assert.*
+import static org.apache.camel.groovy.extend.CamelGroovyMethods.toProcessor
+
+import org.apache.camel.Exchange
+import org.apache.camel.impl.DefaultCamelContext
+import org.apache.camel.impl.DefaultExchange
+import org.junit.Before
+import org.junit.Test
+
+
+class ClosureProcessorTest {
+
+    private Exchange exchange
+    private static final String HELLO = "Hello"
+    
+    @Before
+    public void setUp() throws Exception {
+        exchange = new DefaultExchange(new DefaultCamelContext());
+    }
+    
+    @Test
+    public void testProcessor() {
+        exchange.in.body = HELLO
+        ClosureProcessor processor = toProcessor { Exchange exchange ->
+            exchange.in.body = exchange.in.body.reverse()
+        }
+        processor.process(exchange)
+        assertEquals(HELLO.reverse(), exchange.in.body )       
+    }
+
+    @Test(expected=NullPointerException)
+    public void testProcessorException() {
+        exchange.in.body = null
+        ClosureProcessor processor = toProcessor { Exchange exchange ->
+            exchange.in.body = exchange.in.body.reverse()
+        }
+        processor.process(exchange)
+    }
+}