Camel 2.0-M2 Release
git-svn-id: https://svn.apache.org/repos/asf/camel/tags/camel-2.0-M2@783997 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/camel-core/src/main/java/org/apache/camel/Exchange.java b/camel-core/src/main/java/org/apache/camel/Exchange.java
index 38524d2..2e22c9e 100644
--- a/camel-core/src/main/java/org/apache/camel/Exchange.java
+++ b/camel-core/src/main/java/org/apache/camel/Exchange.java
@@ -59,6 +59,7 @@
String FILE_NAME_PRODUCED = "CamelFileNameProduced";
String FILE_PATH = "CamelFilePath";
String FILE_PARENT = "CamelFileParent";
+ String FILTERED = "CamelFiltered";
String HTTP_CHARACTER_ENCODING = "CamelHttpCharacterEncoding";
String HTTP_METHOD = "CamelHttpMethod";
diff --git a/camel-core/src/main/java/org/apache/camel/processor/Enricher.java b/camel-core/src/main/java/org/apache/camel/processor/Enricher.java
index fe73c45..ade86ee 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/Enricher.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/Enricher.java
@@ -23,6 +23,8 @@
import org.apache.camel.impl.DefaultExchange;
import org.apache.camel.impl.ServiceSupport;
import org.apache.camel.processor.aggregate.AggregationStrategy;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import static org.apache.camel.util.ExchangeHelper.copyResultsPreservePattern;
@@ -35,8 +37,8 @@
*/
public class Enricher extends ServiceSupport implements Processor {
+ private static final transient Log LOG = LogFactory.getLog(Enricher.class);
private AggregationStrategy aggregationStrategy;
-
private Producer producer;
/**
@@ -99,10 +101,19 @@
copyResultsPreservePattern(exchange, resourceExchange);
} else {
prepareResult(exchange);
+
// aggregate original exchange and resource exchange
- Exchange aggregatedExchange = aggregationStrategy.aggregate(exchange, resourceExchange);
- // copy aggregation result onto original exchange (preserving pattern)
- copyResultsPreservePattern(exchange, aggregatedExchange);
+ // but do not aggregate if the resource exchange was filtered
+ Boolean filtered = resourceExchange.getProperty(Exchange.FILTERED, Boolean.class);
+ if (filtered == null || !filtered) {
+ Exchange aggregatedExchange = aggregationStrategy.aggregate(exchange, resourceExchange);
+ // copy aggregation result onto original exchange (preserving pattern)
+ copyResultsPreservePattern(exchange, aggregatedExchange);
+ } else {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Cannot aggregate exchange as its filtered: " + resourceExchange);
+ }
+ }
}
}
diff --git a/camel-core/src/main/java/org/apache/camel/processor/FilterProcessor.java b/camel-core/src/main/java/org/apache/camel/processor/FilterProcessor.java
index 3739cb3..1a07e60 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/FilterProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/FilterProcessor.java
@@ -19,6 +19,8 @@
import org.apache.camel.Exchange;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* The processor which implements the
@@ -27,6 +29,7 @@
* @version $Revision$
*/
public class FilterProcessor extends DelegateProcessor {
+ private static final Log LOG = LogFactory.getLog(FilterProcessor.class);
private final Predicate predicate;
public FilterProcessor(Predicate predicate, Processor processor) {
@@ -37,6 +40,12 @@
public void process(Exchange exchange) throws Exception {
if (predicate.matches(exchange)) {
super.process(exchange);
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Marking exchange as filtered: " + exchange);
+ }
+ // mark this exchange as filtered
+ exchange.setProperty(Exchange.FILTERED, Boolean.TRUE);
}
}
diff --git a/camel-core/src/main/java/org/apache/camel/processor/MulticastProcessor.java b/camel-core/src/main/java/org/apache/camel/processor/MulticastProcessor.java
index 4d430a5..151e70a 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/MulticastProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/MulticastProcessor.java
@@ -92,6 +92,7 @@
public MulticastProcessor(Collection<Processor> processors, AggregationStrategy aggregationStrategy, boolean parallelProcessing, ExecutorService executorService, boolean streaming) {
notNull(processors, "processors");
+ // TODO: end() does not work correctly with Splitter
this.processors = processors;
this.aggregationStrategy = aggregationStrategy;
this.isParallelProcessing = parallelProcessing;
@@ -204,8 +205,14 @@
* @param exchange the exchange to be added to the result
*/
protected synchronized void doAggregate(AtomicExchange result, Exchange exchange) {
- if (aggregationStrategy != null) {
+ // only aggregate if the exchange is not filtered (eg by the FilterProcessor)
+ Boolean filtered = exchange.getProperty(Exchange.FILTERED, Boolean.class);
+ if (aggregationStrategy != null && (filtered == null || !filtered)) {
result.set(aggregationStrategy.aggregate(result.get(), exchange));
+ } else {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Cannot aggregate exchange as its filtered: " + exchange);
+ }
}
}
diff --git a/camel-core/src/main/java/org/apache/camel/processor/aggregate/DefaultAggregationCollection.java b/camel-core/src/main/java/org/apache/camel/processor/aggregate/DefaultAggregationCollection.java
index e27776a..6874a9a 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/aggregate/DefaultAggregationCollection.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/aggregate/DefaultAggregationCollection.java
@@ -57,11 +57,22 @@
@Override
public boolean add(Exchange exchange) {
+ // do not add exchange if it was filtered
+ Boolean filtered = exchange.getProperty(Exchange.FILTERED, Boolean.class);
+ if (filtered != null && filtered) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Cannot aggregate exchange as its filtered: " + exchange);
+ }
+ return false;
+ }
+
Object correlationKey = correlationExpression.evaluate(exchange, Object.class);
if (LOG.isTraceEnabled()) {
- LOG.trace("Evaluated expression: " + correlationExpression + " as CorrelationKey: " + correlationKey);
+ LOG.trace("Evaluated expression: " + correlationExpression + " as correlation key: " + correlationKey);
}
+ // TODO: correlationKey evalutated to null should be skipped by default
+
Exchange oldExchange = aggregated.get(correlationKey);
Exchange newExchange = exchange;
@@ -80,7 +91,7 @@
// the strategy may just update the old exchange and return it
if (!newExchange.equals(oldExchange)) {
if (LOG.isTraceEnabled()) {
- LOG.trace("Put exchange:" + newExchange + " with coorelation key:" + correlationKey);
+ LOG.trace("Put exchange:" + newExchange + " with correlation key:" + correlationKey);
}
aggregated.put(correlationKey, newExchange);
}
diff --git a/camel-core/src/test/java/org/apache/camel/processor/AggregateShouldSkipFilteredExchanges.java b/camel-core/src/test/java/org/apache/camel/processor/AggregateShouldSkipFilteredExchanges.java
new file mode 100644
index 0000000..ce0596e
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/processor/AggregateShouldSkipFilteredExchanges.java
@@ -0,0 +1,81 @@
+/**
+ * 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.processor;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Predicate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.processor.aggregate.AggregationStrategy;
+
+/**
+ * Unit test to verify that Aggregate aggregator does not included filtered exchanges.
+ *
+ * @version $Revision$
+ */
+public class AggregateShouldSkipFilteredExchanges extends ContextTestSupport {
+
+ public void testAggregateWithFilter() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedBodiesReceived("Hello World,Bye World");
+
+ MockEndpoint filtered = getMockEndpoint("mock:filtered");
+ filtered.expectedBodiesReceived("Hello World", "Bye World");
+
+ template.sendBodyAndHeader("direct:start", "Hello World", "id", 1);
+ template.sendBodyAndHeader("direct:start", "Hi there", "id", 1);
+ template.sendBodyAndHeader("direct:start", "Bye World", "id", 1);
+ template.sendBodyAndHeader("direct:start", "How do you do?", "id", 1);
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ Predicate goodWord = body().contains("World");
+
+ from("direct:start")
+ .filter(goodWord)
+ .to("mock:filtered")
+ .aggregate(header("id"), new MyAggregationStrategy())
+ .to("mock:result")
+ .end();
+ }
+ };
+ }
+
+ private class MyAggregationStrategy implements AggregationStrategy {
+
+ public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
+ String newBody = newExchange.getIn().getBody(String.class);
+
+ if (oldExchange == null) {
+ return newExchange;
+ }
+
+ String body = oldExchange.getIn().getBody(String.class);
+ body = body + "," + newBody;
+ oldExchange.getIn().setBody(body);
+ return oldExchange;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/camel-core/src/test/java/org/apache/camel/processor/EnrichShouldSkipFilteredExchanges.java b/camel-core/src/test/java/org/apache/camel/processor/EnrichShouldSkipFilteredExchanges.java
new file mode 100644
index 0000000..41ded81
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/processor/EnrichShouldSkipFilteredExchanges.java
@@ -0,0 +1,85 @@
+/**
+ * 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.processor;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Predicate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.processor.aggregate.AggregationStrategy;
+
+/**
+ * Unit test to verify that Enrich aggregator does not included filtered exchanges.
+ *
+ * @version $Revision$
+ */
+public class EnrichShouldSkipFilteredExchanges extends ContextTestSupport {
+
+ public void testEnrichWithFilterNotFiltered() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedBodiesReceived("Hello World,Hello World");
+
+ template.sendBody("direct:start", "Hello World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ public void testEnrichWithFilterFiltered() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedBodiesReceived("Hi there");
+
+ template.sendBody("direct:start", "Hi there");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .enrich("direct:enrich", new MyAggregationStrategy())
+ .to("mock:result");
+
+ Predicate goodWord = body().contains("World");
+ from("direct:enrich")
+ .filter(goodWord)
+ .to("mock:filtered");
+ }
+ };
+ }
+
+ private class MyAggregationStrategy implements AggregationStrategy {
+
+ public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
+ String newBody = newExchange.getIn().getBody(String.class);
+ assertTrue("Should have been filtered: " + newBody, newBody.contains("World"));
+
+ if (oldExchange == null) {
+ return newExchange;
+ }
+
+ String body = oldExchange.getIn().getBody(String.class);
+ body = body + "," + newBody;
+ oldExchange.getIn().setBody(body);
+ return oldExchange;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/camel-core/src/test/java/org/apache/camel/processor/MulticastShouldSkipFilteredExchanges.java b/camel-core/src/test/java/org/apache/camel/processor/MulticastShouldSkipFilteredExchanges.java
new file mode 100644
index 0000000..faad756
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/processor/MulticastShouldSkipFilteredExchanges.java
@@ -0,0 +1,90 @@
+/**
+ * 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.processor;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Predicate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.processor.aggregate.AggregationStrategy;
+
+/**
+ * Unit test to verify that Multicast aggregator does not included filtered exchanges.
+ *
+ * @version $Revision$
+ */
+public class MulticastShouldSkipFilteredExchanges extends ContextTestSupport {
+
+ public void testMulticastWithFilterNotFiltered() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedBodiesReceived("Hello World,Hello World");
+
+ template.sendBody("direct:start", "Hello World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ public void testMulticastWithFilterFiltered() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedBodiesReceived("Hi there");
+
+ template.sendBody("direct:start", "Hi there");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .to("direct:multicast")
+ .to("mock:result");
+
+ from("direct:multicast")
+ .multicast(new MyAggregationStrategy())
+ .to("direct:a")
+ .to("direct:b");
+
+ Predicate goodWord = body().contains("World");
+ from("direct:a", "direct:b")
+ .filter(goodWord)
+ .to("mock:filtered");
+ }
+ };
+ }
+
+ private class MyAggregationStrategy implements AggregationStrategy {
+
+ public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
+ String newBody = newExchange.getIn().getBody(String.class);
+ assertTrue("Should have been filtered: " + newBody, newBody.contains("World"));
+
+ if (oldExchange == null) {
+ return newExchange;
+ }
+
+ String body = oldExchange.getIn().getBody(String.class);
+ body = body + "," + newBody;
+ oldExchange.getIn().setBody(body);
+ return oldExchange;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/camel-core/src/test/java/org/apache/camel/processor/SplitShouldSkipFilteredExchanges.java b/camel-core/src/test/java/org/apache/camel/processor/SplitShouldSkipFilteredExchanges.java
new file mode 100644
index 0000000..468446a
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/processor/SplitShouldSkipFilteredExchanges.java
@@ -0,0 +1,89 @@
+/**
+ * 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.processor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Predicate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.processor.aggregate.AggregationStrategy;
+
+/**
+ * Unit test to verify that Splitter aggregator does not included filtered exchanges.
+ *
+ * @version $Revision$
+ */
+public class SplitShouldSkipFilteredExchanges extends ContextTestSupport {
+
+ public void testSplitWithFilter() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedBodiesReceived("Hello World,Bye World");
+
+ MockEndpoint filtered = getMockEndpoint("mock:filtered");
+ filtered.expectedBodiesReceived("Hello World", "Bye World");
+
+ List<String> body = new ArrayList<String>();
+ body.add("Hello World");
+ body.add("Hi there");
+ body.add("Bye World");
+ body.add("How do you do?");
+
+ template.sendBody("direct:start", body);
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .to("direct:split")
+ .to("mock:result");
+
+ Predicate goodWord = body().contains("World");
+ from("direct:split")
+ .split(body(List.class), new MyAggregationStrategy())
+ .filter(goodWord)
+ .to("mock:filtered");
+ }
+ };
+ }
+
+ private class MyAggregationStrategy implements AggregationStrategy {
+
+ public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
+ String newBody = newExchange.getIn().getBody(String.class);
+ assertTrue("Should have been filtered: " + newBody, newBody.contains("World"));
+
+ if (oldExchange == null) {
+ return newExchange;
+ }
+
+ String body = oldExchange.getIn().getBody(String.class);
+ body = body + "," + newBody;
+ oldExchange.getIn().setBody(body);
+ return oldExchange;
+ }
+
+ }
+}
diff --git a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfSpringEndpoint.java b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfSpringEndpoint.java
index a605ac8..f638067 100644
--- a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfSpringEndpoint.java
+++ b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfSpringEndpoint.java
@@ -17,6 +17,7 @@
package org.apache.camel.component.cxf;
import java.lang.reflect.Proxy;
+
import javax.xml.namespace.QName;
import org.apache.camel.CamelContext;
@@ -32,7 +33,7 @@
import org.apache.cxf.frontend.ClientProxyFactoryBean;
import org.apache.cxf.frontend.ServerFactoryBean;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
-import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
/**
* Defines the <a href="http://camel.apache.org/cxf.html">CXF Endpoint</a>
@@ -174,8 +175,8 @@
void configure(Object beanInstance) {
// check the ApplicationContext states first , and call the refresh if necessary
- if (((SpringCamelContext)getCamelContext()).getApplicationContext() instanceof AbstractApplicationContext) {
- AbstractApplicationContext context = (AbstractApplicationContext)((SpringCamelContext)getCamelContext()).getApplicationContext();
+ if (((SpringCamelContext)getCamelContext()).getApplicationContext() instanceof ConfigurableApplicationContext) {
+ ConfigurableApplicationContext context = (ConfigurableApplicationContext)((SpringCamelContext)getCamelContext()).getApplicationContext();
if (!context.isActive()) {
context.refresh();
}
diff --git a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/spring/CxfEndpointBean.java b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/spring/CxfEndpointBean.java
index 73fba1e..7f6f2bc 100644
--- a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/spring/CxfEndpointBean.java
+++ b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/spring/CxfEndpointBean.java
@@ -18,13 +18,18 @@
import java.util.List;
+import org.apache.cxf.BusFactory;
import org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory;
import org.apache.cxf.service.factory.ReflectionServiceFactoryBean;
+import org.springframework.beans.factory.DisposableBean;
+
/**
*
*/
-public class CxfEndpointBean extends AbstractWSDLBasedEndpointFactory {
+public class CxfEndpointBean extends AbstractWSDLBasedEndpointFactory
+ implements DisposableBean {
+
private List handlers;
public CxfEndpointBean() {
@@ -42,4 +47,11 @@
public void setHandlers(List handlers) {
this.handlers = handlers;
}
+
+ public void destroy() throws Exception {
+ // Clean up the BusFactory's defaultBus
+ BusFactory.setDefaultBus(null);
+ BusFactory.setThreadDefaultBus(null);
+
+ }
}
diff --git a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/spring/CxfEndpointBeanDefinitionParser.java b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/spring/CxfEndpointBeanDefinitionParser.java
index 73ee4cf..85e5015 100644
--- a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/spring/CxfEndpointBeanDefinitionParser.java
+++ b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/spring/CxfEndpointBeanDefinitionParser.java
@@ -26,7 +26,9 @@
import org.apache.cxf.BusFactory;
import org.apache.cxf.bus.spring.BusWiringBeanFactoryPostProcessor;
import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.configuration.Configurer;
import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
+import org.apache.cxf.configuration.spring.ConfigurerImpl;
import org.apache.cxf.service.factory.ReflectionServiceFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
@@ -36,6 +38,7 @@
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
public class CxfEndpointBeanDefinitionParser extends AbstractCxfBeanDefinitionParser {
diff --git a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/util/CxfUtils.java b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/util/CxfUtils.java
index 8823c5a..5b748b0 100644
--- a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/util/CxfUtils.java
+++ b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/util/CxfUtils.java
@@ -34,9 +34,7 @@
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import com.sun.org.apache.xml.internal.serialize.OutputFormat;
-import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
-
+import org.apache.camel.converter.jaxp.XmlConverter;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.io.CachedOutputStream;
@@ -63,7 +61,8 @@
visitNodesForNameSpace(element, namespaces);
W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
writeElement(element, writer, namespaces);
- return getStringFromDoc(writer.getDocument());
+ XmlConverter converter = new XmlConverter();
+ return converter.toString(converter.toSource(writer.getDocument()));
}
@@ -164,20 +163,6 @@
}
- private static String getStringFromDoc(Document document) throws IOException {
- //Serialize DOM
- OutputFormat format = new OutputFormat(document);
- format.setOmitXMLDeclaration(true);
- // as a String
- StringWriter stringOut = new StringWriter();
- XMLSerializer serial = new XMLSerializer(stringOut,
- format);
- serial.serialize(document);
-
- return stringOut.toString();
-
- }
-
private static void visitNodesForNameSpace(Node node, Map<String, String> namespaces) {
if (node instanceof Element) {
Element element = (Element)node;
diff --git a/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/spring/AbstractSpringBeanTestSupport.java b/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/spring/AbstractSpringBeanTestSupport.java
index 9f6d031..9a40bcf 100644
--- a/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/spring/AbstractSpringBeanTestSupport.java
+++ b/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/spring/AbstractSpringBeanTestSupport.java
@@ -32,8 +32,7 @@
}
protected void tearDown() throws Exception {
- ctx.close();
- BusFactory.setDefaultBus(null);
+ ctx.close();
}
}
diff --git a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java
index 3052acc..1860483 100644
--- a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java
+++ b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java
@@ -94,40 +94,72 @@
// if there is an alternativebody provided, set up a mime multipart alternative message
if (hasAlternativeBody(endpoint.getConfiguration(), exchange.getIn())) {
- createMultipartAlternativeMessage(mimeMessage, exchange.getIn(), endpoint.getConfiguration());
+ createMultipartAlternativeMessage(mimeMessage, endpoint.getConfiguration(), exchange);
} else {
if (exchange.getIn().hasAttachments()) {
- appendAttachmentsFromCamel(mimeMessage, exchange.getIn(), endpoint.getConfiguration());
+ appendAttachmentsFromCamel(mimeMessage, endpoint.getConfiguration(), exchange);
} else {
- String contentType = populateContentType(endpoint, mimeMessage, exchange);
- if (contentType == null) {
- mimeMessage.setText(exchange.getIn().getBody(String.class));
- } else if (contentType.startsWith("text/plain")) {
- String charset = ObjectHelper.after(contentType, "charset=");
- if (charset != null) {
- mimeMessage.setText(exchange.getIn().getBody(String.class), charset);
- } else {
- mimeMessage.setText(exchange.getIn().getBody(String.class));
- }
- } else {
- // store content in a byte array data store
- DataSource ds = new ByteArrayDataSource(exchange.getIn().getBody(String.class), contentType);
- mimeMessage.setDataHandler(new DataHandler(ds));
- }
+ populateContentOnMimeMessage(mimeMessage, endpoint.getConfiguration(), exchange);
}
}
}
- protected String populateContentType(MailEndpoint endpoint, MimeMessage mimeMessage, Exchange exchange) throws MessagingException {
+ protected String determineContentType(MailConfiguration configuration, Exchange exchange) {
// see if we got any content type set
- String contentType = endpoint.getConfiguration().getContentType();
+ String contentType = configuration.getContentType();
if (exchange.getIn().getHeader("contentType") != null) {
contentType = exchange.getIn().getHeader("contentType", String.class);
} else if (exchange.getIn().getHeader(Exchange.CONTENT_TYPE) != null) {
contentType = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class);
}
- if (contentType != null) {
- mimeMessage.setHeader("Content-Type", contentType);
+
+ // fix content type to include a space after semi colon if missing
+ if (contentType != null && contentType.contains(";")) {
+ String before = ObjectHelper.before(contentType, ";");
+ String after = ObjectHelper.after(contentType, ";");
+ if (before != null && after != null) {
+ contentType = before.trim() + "; " + after.trim();
+ }
+ }
+
+ return contentType;
+ }
+
+ protected String populateContentOnMimeMessage(MimeMessage part, MailConfiguration configuration, Exchange exchange) throws MessagingException, IOException {
+ String contentType = determineContentType(configuration, exchange);
+ if (contentType == null) {
+ part.setText(exchange.getIn().getBody(String.class));
+ } else {
+ if (contentType.startsWith("text/plain")) {
+ String charset = ObjectHelper.after(contentType, "charset=");
+ if (charset != null) {
+ part.setText(exchange.getIn().getBody(String.class), charset.trim());
+ } else {
+ part.setText(exchange.getIn().getBody(String.class));
+ }
+ } else {
+ // store content in a byte array data store
+ DataSource ds = new ByteArrayDataSource(exchange.getIn().getBody(String.class), contentType);
+ part.setDataHandler(new DataHandler(ds));
+ }
+ part.setHeader("Content-Type", contentType);
+ }
+ return contentType;
+ }
+
+ protected String populateContentOnBodyPart(BodyPart part, MailConfiguration configuration, Exchange exchange) throws MessagingException, IOException {
+ String contentType = determineContentType(configuration, exchange);
+ if (contentType == null) {
+ part.setText(exchange.getIn().getBody(String.class));
+ } else {
+ if (contentType.startsWith("text/plain")) {
+ part.setText(exchange.getIn().getBody(String.class));
+ } else {
+ // store content in a byte array data store
+ DataSource ds = new ByteArrayDataSource(exchange.getIn().getBody(String.class), contentType);
+ part.setDataHandler(new DataHandler(ds));
+ }
+ part.setHeader("Content-Type", contentType);
}
return contentType;
}
@@ -221,30 +253,31 @@
/**
* Appends the Mail attachments from the Camel {@link MailMessage}
*/
- protected void appendAttachmentsFromCamel(MimeMessage mimeMessage, org.apache.camel.Message camelMessage,
- MailConfiguration configuration)
- throws MessagingException {
-
+ protected void appendAttachmentsFromCamel(MimeMessage mimeMessage, MailConfiguration configuration,
+ Exchange exchange) throws MessagingException, IOException {
+
// Put parts in message
- mimeMessage.setContent(createMixedMultipartAttachments(camelMessage, configuration));
+ mimeMessage.setContent(createMixedMultipartAttachments(configuration, exchange));
}
- private MimeMultipart createMixedMultipartAttachments(org.apache.camel.Message camelMessage, MailConfiguration configuration) throws MessagingException {
+ private MimeMultipart createMixedMultipartAttachments(MailConfiguration configuration, Exchange exchange)
+ throws MessagingException, IOException {
+
// fill the body with text
MimeMultipart multipart = new MimeMultipart();
multipart.setSubType("mixed");
- addBodyToMultipart(camelMessage, configuration, multipart);
+ addBodyToMultipart(configuration, multipart, exchange);
String partDisposition = configuration.isUseInlineAttachments() ? Part.INLINE : Part.ATTACHMENT;
- if (camelMessage.hasAttachments()) {
- addAttachmentsToMultipart(camelMessage, multipart, partDisposition);
+ if (exchange.getIn().hasAttachments()) {
+ addAttachmentsToMultipart(multipart, partDisposition, exchange);
}
return multipart;
}
- protected void addAttachmentsToMultipart(org.apache.camel.Message camelMessage, MimeMultipart multipart, String partDisposition) throws MessagingException {
+ protected void addAttachmentsToMultipart(MimeMultipart multipart, String partDisposition, Exchange exchange) throws MessagingException {
LOG.trace("Adding attachments +++ start +++");
int i = 0;
- for (Map.Entry<String, DataHandler> entry : camelMessage.getAttachments().entrySet()) {
+ for (Map.Entry<String, DataHandler> entry : exchange.getIn().getAttachments().entrySet()) {
String attachmentFilename = entry.getKey();
DataHandler handler = entry.getValue();
@@ -254,7 +287,7 @@
LOG.trace("Attachment #" + i + ": FileName: " + attachmentFilename);
}
if (handler != null) {
- if (shouldAddAttachment(camelMessage, attachmentFilename, handler)) {
+ if (shouldAddAttachment(exchange, attachmentFilename, handler)) {
// Create another body part
BodyPart messageBodyPart = new MimeBodyPart();
// Set the data handler to the attachment
@@ -294,53 +327,54 @@
LOG.trace("Adding attachments +++ done +++");
}
- protected void createMultipartAlternativeMessage(MimeMessage mimeMessage, org.apache.camel.Message camelMessage, MailConfiguration configuration)
- throws MessagingException {
+ protected void createMultipartAlternativeMessage(MimeMessage mimeMessage, MailConfiguration configuration,
+ Exchange exchange) throws MessagingException, IOException {
MimeMultipart multipartAlternative = new MimeMultipart("alternative");
mimeMessage.setContent(multipartAlternative);
BodyPart plainText = new MimeBodyPart();
- plainText.setText(getAlternativeBody(configuration, camelMessage));
+ plainText.setText(getAlternativeBody(configuration, exchange.getIn()));
multipartAlternative.addBodyPart(plainText);
// if there are no attachments, add the body to the same mulitpart message
- if (!camelMessage.hasAttachments()) {
- addBodyToMultipart(camelMessage, configuration, multipartAlternative);
+ if (!exchange.getIn().hasAttachments()) {
+ addBodyToMultipart(configuration, multipartAlternative, exchange);
} else {
// if there are attachments, but they aren't set to be inline, add them to
- // treat them as normal. It will append a multipart-mixed with the attachments and the
- // body text
+ // treat them as normal. It will append a multipart-mixed with the attachments and the body text
if (!configuration.isUseInlineAttachments()) {
BodyPart mixedAttachments = new MimeBodyPart();
- mixedAttachments.setContent(createMixedMultipartAttachments(camelMessage, configuration));
+ mixedAttachments.setContent(createMixedMultipartAttachments(configuration, exchange));
multipartAlternative.addBodyPart(mixedAttachments);
- //appendAttachmentsFromCamel(mimeMessage, camelMessage, configuration);
- } else { // if the attachments are set to be inline, attach them as inline attachments
+ } else {
+ // if the attachments are set to be inline, attach them as inline attachments
MimeMultipart multipartRelated = new MimeMultipart("related");
BodyPart related = new MimeBodyPart();
related.setContent(multipartRelated);
multipartAlternative.addBodyPart(related);
- addBodyToMultipart(camelMessage, configuration, multipartRelated);
+ addBodyToMultipart(configuration, multipartRelated, exchange);
- addAttachmentsToMultipart(camelMessage, multipartRelated, Part.INLINE);
+ addAttachmentsToMultipart(multipartRelated, Part.INLINE, exchange);
}
}
}
- protected void addBodyToMultipart(org.apache.camel.Message camelMessage, MailConfiguration configuration, MimeMultipart activeMultipart) throws MessagingException {
+ protected void addBodyToMultipart(MailConfiguration configuration, MimeMultipart activeMultipart, Exchange exchange)
+ throws MessagingException, IOException {
+
BodyPart bodyMessage = new MimeBodyPart();
- bodyMessage.setContent(camelMessage.getBody(String.class), configuration.getContentType());
+ populateContentOnBodyPart(bodyMessage, configuration, exchange);
activeMultipart.addBodyPart(bodyMessage);
}
/**
* Strategy to allow filtering of attachments which are added on the Mail message
*/
- protected boolean shouldAddAttachment(org.apache.camel.Message camelMessage, String attachmentFilename, DataHandler handler) {
+ protected boolean shouldAddAttachment(Exchange exchange, String attachmentFilename, DataHandler handler) {
return true;
}
diff --git a/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailCustomContentTypeTest.java b/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailCustomContentTypeTest.java
index 5162ace..e808f42 100644
--- a/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailCustomContentTypeTest.java
+++ b/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailCustomContentTypeTest.java
@@ -37,7 +37,7 @@
Message msg = box.get(0);
assertTrue(msg.getContentType().startsWith("text/html"));
- assertEquals("text/html;charset=UTF-8", msg.getContentType());
+ assertEquals("text/html; charset=UTF-8", msg.getContentType());
assertEquals("<html><body><h1>Hello</h1>World</body></html>", msg.getContent());
}
@@ -50,14 +50,14 @@
Message msg = box.get(0);
assertTrue(msg.getContentType().startsWith("text/html"));
- assertEquals("text/html;charset=iso-8859-1", msg.getContentType());
+ assertEquals("text/html; charset=iso-8859-1", msg.getContentType());
assertEquals("<html><body><h1>Hello</h1>World</body></html>", msg.getContent());
}
public void testSendPlainMailContentTypeInHeader() throws Exception {
Mailbox.clearAll();
- template.sendBodyAndHeader("direct:b", "Hello World", "contentType", "text/plain;charset=iso-8859-1");
+ template.sendBodyAndHeader("direct:b", "Hello World", "contentType", "text/plain; charset=iso-8859-1");
Mailbox box = Mailbox.get("claus@localhost");
Message msg = box.get(0);
@@ -68,7 +68,7 @@
public void testSendPlainMailContentTypeInHeader2() throws Exception {
Mailbox.clearAll();
- template.sendBodyAndHeader("direct:b", "Hello World", Exchange.CONTENT_TYPE, "text/plain;charset=iso-8859-1");
+ template.sendBodyAndHeader("direct:b", "Hello World", Exchange.CONTENT_TYPE, "text/plain; charset=iso-8859-1");
Mailbox box = Mailbox.get("claus@localhost");
Message msg = box.get(0);
@@ -76,6 +76,19 @@
assertEquals("Hello World", msg.getContent());
}
+ public void testSendPlainMailContentTypeTinyTypeInHeader() throws Exception {
+ Mailbox.clearAll();
+
+ // Camel will fixup the Content-Type if you do not have a space after the semi colon
+ template.sendBodyAndHeader("direct:b", "Hello World", "contentType", "text/plain;charset=iso-8859-1");
+
+ Mailbox box = Mailbox.get("claus@localhost");
+ Message msg = box.get(0);
+ // the content type should have a space after the semi colon
+ assertEquals("text/plain; charset=iso-8859-1", msg.getContentType());
+ assertEquals("Hello World", msg.getContent());
+ }
+
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
public void configure() throws Exception {
diff --git a/components/camel-web/pom.xml b/components/camel-web/pom.xml
index 6e1571f..107e123 100644
--- a/components/camel-web/pom.xml
+++ b/components/camel-web/pom.xml
@@ -73,6 +73,14 @@
<artifactId>camel-spring</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-groovy</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-ruby</artifactId>
+ </dependency>
+ <dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>${jersey-version}</version>
diff --git a/components/camel-web/src/main/java/org/apache/camel/web/resources/RouteResource.java b/components/camel-web/src/main/java/org/apache/camel/web/resources/RouteResource.java
index aa3e018..259ba4e 100644
--- a/components/camel-web/src/main/java/org/apache/camel/web/resources/RouteResource.java
+++ b/components/camel-web/src/main/java/org/apache/camel/web/resources/RouteResource.java
@@ -16,12 +16,15 @@
*/
package org.apache.camel.web.resources;
+import java.io.File;
+import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
+import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -39,12 +42,17 @@
import com.sun.jersey.api.representation.Form;
import com.sun.jersey.api.view.Viewable;
+import groovy.lang.GroovyClassLoader;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.ruby.RubyCamel;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.view.RouteDotGenerator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jruby.Main;
/**
* A single Camel Route which is used to implement one or more
@@ -54,11 +62,23 @@
*/
public class RouteResource extends CamelChildResourceSupport {
private static final transient Log LOG = LogFactory.getLog(RouteResource.class);
+ private static final String LANGUAGE_XML = "Xml";
+ private static final String LANGUAGE_GROOVY = "Groovy";
+ private static final String LANGUAGE_RUBY = "Ruby";
+ private static final String LANGUAGE_SCALA = "Scala";
private RouteDefinition route;
private String error = "";
private String id;
+ // what language is used to define this route
+ private String language = LANGUAGE_XML;
+
+ // the route configuration: when language is Xml, the routeDefinition is
+ // null; when language is Groovy/Scala/Ruby, the routeDefinition contains
+ // the route definition class. It must be initialized because RouteResource
+ // is stateless.
+ private String routeDefinition = "";
public RouteResource(RoutesResource routesResource, RouteDefinition route) {
super(routesResource.getContextResource());
@@ -83,15 +103,40 @@
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// TODO fix to use "" namespace prefix
- // using this https://jaxb.dev.java.net/nonav/2.1.10/docs/vendorProperties.html#prefixmapper
+ // using this
+ // https://jaxb.dev.java.net/nonav/2.1.10/docs/vendorProperties.html#prefixmapper
StringWriter buffer = new StringWriter();
marshaller.marshal(route, buffer);
return buffer.toString();
}
/**
- * Returns the Graphviz DOT <a href="http://camel.apache.org/visualisation.html">Visualisation</a>
- * of this route
+ * Returns the language
+ */
+ public String getLanguage() {
+ return language;
+ }
+
+ /**
+ * Returns the content of the route definition class
+ */
+ public String getRouteDefinition() {
+ if (language.equals(LANGUAGE_XML)) {
+ try {
+ return getRouteXml();
+ } catch (JAXBException e) {
+ // e.printStackTrace();
+ return "Error on marshal the route definition!";
+ }
+ } else {
+ return routeDefinition;
+ }
+ }
+
+ /**
+ * Returns the Graphviz DOT <a
+ * href="http://camel.apache.org/visualisation.html">Visualisation</a> of
+ * this route
*/
@GET
@Produces(Constants.DOT_MIMETYPE)
@@ -100,7 +145,6 @@
return generator.getRoutesText(getCamelContext());
}
-
/**
* Allows a route definition to be updated
*/
@@ -115,46 +159,188 @@
getCamelContext().addRouteDefinitions(Collections.singletonList(routeDefinition));
}
+ /**
+ * Allows a routes builder to be updated
+ */
+ public void postRoutes(RouteBuilder builder) throws Exception {
+ // remove current route
+ DefaultCamelContext camelContext = (DefaultCamelContext)getCamelContext();
+ camelContext.removeRouteDefinition(id);
+
+ // lets install the updated routes
+ camelContext.addRoutes(builder);
+ }
/**
* Updates a route definition using form encoded data from a web form
- *
- * @param formData is the form data POSTed typically from a HTML form with the <code>route</code> field used to encode
- * the XML text of the new route definition
+ *
+ * @param formData is the form data POSTed typically from a HTML form with
+ * the <code>route</code> field used to encode the XML text of
+ * the new route definition
*/
@POST
@Consumes("application/x-www-form-urlencoded")
public Response postRouteForm(@Context UriInfo uriInfo, Form formData) throws URISyntaxException {
// TODO replace the Form class with an injected bean?
- String xml = formData.getFirst("route", String.class);
+ String language = formData.getFirst("language", String.class);
+ String body = formData.getFirst("route", String.class);
if (LOG.isDebugEnabled()) {
- LOG.debug("new XML is: " + xml);
+ LOG.debug("new Route is: " + body);
}
- if (xml == null) {
- error = "No XML submitted!";
- } else {
- try {
- JAXBContext context = JAXBContext.newInstance(Constants.JAXB_PACKAGES);
- Unmarshaller unmarshaller = context.createUnmarshaller();
- Object value = unmarshaller.unmarshal(new StringReader(xml));
- if (value instanceof RouteDefinition) {
- RouteDefinition routeDefinition = (RouteDefinition) value;
- postRoute(routeDefinition);
- return Response.seeOther(new URI("/routes")).build();
- } else {
- error = "Posted XML is not a route but is of type " + ObjectHelper.className(value);
- }
- } catch (JAXBException e) {
- error = "Failed to parse XML: " + e.getMessage();
- } catch (Exception e) {
- error = "Failed to install route: " + e.getMessage();
+ LOG.info(body);
+ if (body == null) {
+ error = "No Route submitted!";
+ } else if (language.equals(LANGUAGE_XML)) {
+ return parseXml(body);
+ } else if (language.equals(LANGUAGE_GROOVY)) {
+ return parseGroovy(body);
+ } else if (language.equals(LANGUAGE_RUBY)) {
+ return parseRuby(body);
+ } else if (language.equals(LANGUAGE_SCALA)) {
+ return parseScala(body);
+ }
+ error = "Not supproted language!";
+ return Response.ok(new Viewable("edit", this)).build();
+
+ }
+
+ /**
+ * process the route configuration defined in Xml
+ */
+ private Response parseXml(String xml) {
+ try {
+ JAXBContext context = JAXBContext.newInstance(Constants.JAXB_PACKAGES);
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ Object value = unmarshaller.unmarshal(new StringReader(xml));
+ if (value instanceof RouteDefinition) {
+ RouteDefinition routeDefinition = (RouteDefinition)value;
+ postRoute(routeDefinition);
+ return Response.seeOther(new URI("/routes")).build();
+ } else {
+ error = "Posted XML is not a route but is of type " + ObjectHelper.className(value);
}
+ } catch (JAXBException e) {
+ error = "Failed to parse XML: " + e.getMessage();
+ } catch (Exception e) {
+ error = "Failed to install route: " + e.getMessage();
}
// lets re-render the form
return Response.ok(new Viewable("edit", this)).build();
}
/**
+ * process the route configuration defined in Groovy class
+ */
+ private Response parseGroovy(String route) {
+ try {
+ // store the route definition
+ File file = storeRoute(route, LANGUAGE_GROOVY);
+
+ // load the definition class into a RouteBuilder instance
+ GroovyClassLoader classLoader = new GroovyClassLoader();
+ Class clazz = classLoader.parseClass(file);
+ RouteBuilder builder = (RouteBuilder)clazz.newInstance();
+ LOG.info("Loaded builder: " + builder);
+
+ postRoutes(builder);
+
+ return Response.seeOther(new URI("/routes")).build();
+
+ } catch (IOException e) {
+ // e.printStackTrace();
+ error = "Failed to store the route: " + e.getMessage();
+ } catch (InstantiationException e) {
+ // e.printStackTrace();
+ error = "Failed to instantiate the route: " + e.getMessage();
+
+ } catch (IllegalAccessException e) {
+ // e.printStackTrace();
+ error = "Failed to instantiate the route: " + e.getMessage();
+ } catch (Exception e) {
+ // e.printStackTrace();
+ error = "Failed to edit the route: " + e.getMessage();
+ }
+ // lets re-render the form
+ return Response.ok(new Viewable("edit", this)).build();
+ }
+
+ /**
+ * process the route configuration defined in Ruby class
+ */
+ private Response parseRuby(String route) {
+ try {
+ // add the script of addRouteBuilder into ruby script
+ route += "\n RubyCamel.addRouteBuilder(RubyRoute.new)";
+
+ // store the route definition
+ File file = storeRoute(route, LANGUAGE_RUBY);
+
+ // execute the ruby script, which will store the RouteBuilder
+ // instances into RubyCamel
+ String[] args = {file.getAbsolutePath()};
+ Main.main(args);
+
+ // get the route builders from the RubyCamel and add them into this
+ // route
+ List<RouteBuilder> list = RubyCamel.getRoutes();
+ for (RouteBuilder builder : list) {
+ postRoutes(builder);
+ }
+
+ return Response.seeOther(new URI("/routes")).build();
+
+ } catch (IOException e) {
+ // e.printStackTrace();
+ error = "Failed to store the route: " + e.getMessage();
+ } catch (Exception e) {
+ // e.printStackTrace();
+ error = "Failed to edit the route: " + e.getMessage();
+
+ }
+ // lets re-render the form
+ return Response.ok(new Viewable("edit", this)).build();
+ }
+
+ /**
+ * process the route configuration defined in Scala class
+ */
+ private Response parseScala(String route) {
+ try {
+
+ // store the route definition
+ File file = storeRoute(route, LANGUAGE_SCALA);
+
+ // load the definition class
+
+ return Response.seeOther(new URI("/routes")).build();
+
+ } catch (IOException e) {
+ // e.printStackTrace();
+ error = "Failed to store the route: " + e.getMessage();
+ } catch (Exception e) {
+ // e.printStackTrace();
+ error = "Failed to edit the route: " + e.getMessage();
+ }
+ // lets re-render the form
+ return Response.ok(new Viewable("edit", this)).build();
+ }
+
+ /**
+ * Stores the route definition class into a file
+ */
+ private File storeRoute(String route, String language) throws IOException {
+ // create a temporary file to store the route definition class
+ File file = File.createTempFile("Route-", "." + language);
+ FileWriter fw = new FileWriter(file);
+
+ // write the route into the file
+ fw.write(route);
+ fw.flush();
+ fw.close();
+ return file;
+ }
+
+ /**
* Looks up an individual route
*/
@Path("status")
diff --git a/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp b/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp
index 7220141..c7b2aae 100644
--- a/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp
+++ b/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp
@@ -1,28 +1,33 @@
<html>
<head>
- <script type='text/javascript' src="<c:url value='/js/dojo/dojo.js'/>"></script>
- <script type='text/javascript' src="<c:url value='/js/bespin/editor/embed.js'/>"></script>
- <script type='text/javascript' src="<c:url value='/js/route.js'/>"></script>
+<script type='text/javascript' src="<c:url value='/js/dojo/dojo.js'/>"></script>
+<script type='text/javascript'
+ src="<c:url value='/js/bespin/editor/embed.js'/>"></script>
+<script type='text/javascript' src="<c:url value='/js/route.js'/>"></script>
- <title>Edit ${it.route.id}</title>
+<title>Edit ${it.route.id}</title>
</head>
<body>
-<form id="routeForm" action="<c:url value="/routes/${it.route.id}"/>" method="post">
+<form id="routeForm" action="<c:url value="/routes/${it.route.id}"/>"
+ method="post">
<table>
- <tr>
- <td>
- <h2>Edit ${it.route.id}</h2>
- </td>
- <td>
- <input type="submit" value="Save">
- </td>
- </tr>
- <tr>
- <td colspan="2">
- <textarea id="route" name="route" style="width: 800px; height: 300px; border: 10px solid #ddd; -moz-border-radius: 10px; -webkit-border-radius: 10px;">${it.routeXml}</textarea>
- </td>
- </tr>
+ <tr>
+ <td>
+ <h2>Edit ${it.route.id}</h2>
+ </td>
+ <td><input type="submit" value="Save"> as <select id="language" name="language">
+ <option value="Xml" selected>XML</option>
+ <option value="Groovy">Groovy</option>
+ <option value="Ruby">Ruby</option>
+ <option value="Scala">Scala</option>
+ </select></td>
+ </tr>
+ <tr>
+ <td colspan="2"><textarea id="route" name="route"
+ style="width: 800px; height: 300px; border: 10px solid #ddd; -moz-border-radius: 10px; -webkit-border-radius: 10px;">${it.routeDefinition}</textarea>
+ </td>
+ </tr>
</table>
<div class="error">${it.error}</div>
diff --git a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppConsumer.java b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppConsumer.java
index d3ef7d4..9f5c0db 100644
--- a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppConsumer.java
+++ b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppConsumer.java
@@ -60,6 +60,12 @@
LOG.info("Open private chat to: " + privateChat.getParticipant());
}
} else {
+ // add the presence packet listener to the connection so we only get packets that concers us
+ // we must add the listener before creating the muc
+ final ToContainsFilter toFilter = new ToContainsFilter(endpoint.getParticipant());
+ final AndFilter packetFilter = new AndFilter(new PacketTypeFilter(Presence.class), toFilter);
+ connection.addPacketListener(this, packetFilter);
+
muc = new MultiUserChat(connection, endpoint.resolveRoom(connection));
muc.addMessageListener(this);
DiscussionHistory history = new DiscussionHistory();
@@ -69,11 +75,6 @@
if (LOG.isInfoEnabled()) {
LOG.info("Joined room: " + muc.getRoom() + " as: " + endpoint.getNickname());
}
-
- // add the presence packet listener to the connection so we only get packets that concers us
- final ToContainsFilter toFilter = new ToContainsFilter(endpoint.getParticipant());
- final AndFilter packetFilter = new AndFilter(new PacketTypeFilter(Presence.class), toFilter);
- connection.addPacketListener(this, packetFilter);
}
super.doStart();