You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2017/02/14 12:21:24 UTC
[3/3] camel git commit: CAMEL-10532 Extract ContractAdvice as an
individual file
CAMEL-10532 Extract ContractAdvice as an individual file
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/25b2ba25
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/25b2ba25
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/25b2ba25
Branch: refs/heads/master
Commit: 25b2ba250776c0046d0bcec869f0aa98caa92e4c
Parents: 605710d
Author: Tomohisa Igarashi <tm...@gmail.com>
Authored: Fri Feb 3 15:17:23 2017 +0900
Committer: Tomohisa Igarashi <tm...@gmail.com>
Committed: Tue Feb 14 20:43:46 2017 +0900
----------------------------------------------------------------------
.../apache/camel/impl/DefaultRouteContext.java | 3 +-
.../camel/processor/CamelInternalProcessor.java | 140 -----------------
.../apache/camel/processor/ContractAdvice.java | 152 +++++++++++++++++++
3 files changed, 154 insertions(+), 141 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/25b2ba25/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java
index 8a2e7c1..328dae9 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java
@@ -35,6 +35,7 @@ import org.apache.camel.model.FromDefinition;
import org.apache.camel.model.ProcessorDefinition;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.processor.CamelInternalProcessor;
+import org.apache.camel.processor.ContractAdvice;
import org.apache.camel.processor.Pipeline;
import org.apache.camel.spi.Contract;
import org.apache.camel.spi.InterceptStrategy;
@@ -195,7 +196,7 @@ public class DefaultRouteContext implements RouteContext {
// wrap in contract
if (contract != null) {
- internal.addAdvice(new CamelInternalProcessor.ContractAdvice(contract));
+ internal.addAdvice(new ContractAdvice(contract));
}
// and create the route that wraps the UoW
http://git-wip-us.apache.org/repos/asf/camel/blob/25b2ba25/camel-core/src/main/java/org/apache/camel/processor/CamelInternalProcessor.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/CamelInternalProcessor.java b/camel-core/src/main/java/org/apache/camel/processor/CamelInternalProcessor.java
index 3ce9220..c98b1b0 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/CamelInternalProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/CamelInternalProcessor.java
@@ -25,7 +25,6 @@ import java.util.concurrent.RejectedExecutionException;
import org.apache.camel.AsyncCallback;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
-import org.apache.camel.Message;
import org.apache.camel.MessageHistory;
import org.apache.camel.Ordered;
import org.apache.camel.Processor;
@@ -40,8 +39,6 @@ import org.apache.camel.model.ProcessorDefinitionHelper;
import org.apache.camel.processor.interceptor.BacklogDebugger;
import org.apache.camel.processor.interceptor.BacklogTracer;
import org.apache.camel.processor.interceptor.DefaultBacklogTracerEventMessage;
-import org.apache.camel.spi.Contract;
-import org.apache.camel.spi.DataType;
import org.apache.camel.spi.InflightRepository;
import org.apache.camel.spi.MessageHistoryFactory;
import org.apache.camel.spi.RouteContext;
@@ -857,141 +854,4 @@ public class CamelInternalProcessor extends DelegateAsyncProcessor {
// noop
}
}
-
- /**
- * Advice for data type contract
- * TODO add declarative validation
- */
- public static class ContractAdvice implements CamelInternalProcessorAdvice {
- private Contract contract;
-
- public ContractAdvice(Contract contract) {
- this.contract = contract;
- }
-
- @Override
- public Object before(Exchange exchange) throws Exception {
- DataType from = getCurrentType(exchange, Exchange.INPUT_TYPE);
- DataType to = contract.getInputType();
- if (to != null && !to.equals(from)) {
- LOG.debug("Looking for transformer for INPUT: from='{}', to='{}'", from, to);
- doTransform(exchange.getIn(), from, to);
- exchange.setProperty(Exchange.INPUT_TYPE, to);
- }
- return null;
- }
-
- @Override
- public void after(Exchange exchange, Object data) throws Exception {
- Message target = exchange.hasOut() ? exchange.getOut() : exchange.getIn();
- DataType from = getCurrentType(exchange, exchange.hasOut() ? Exchange.OUTPUT_TYPE : Exchange.INPUT_TYPE);
- DataType to = contract.getOutputType();
- if (to != null && !to.equals(from)) {
- LOG.debug("Looking for transformer for OUTPUT: from='{}', to='{}'", from, to);
- doTransform(target, from, to);
- exchange.setProperty(exchange.hasOut() ? Exchange.OUTPUT_TYPE : Exchange.INPUT_TYPE, to);
- }
- }
-
- private void doTransform(Message message, DataType from, DataType to) throws Exception {
- // transform into 'from' type before performing declared transformation
- convertIfRequired(message, from);
-
- if (applyExactlyMatchedTransformer(message, from, to)) {
- // Found exactly matched transformer. Java-Java transformer is also allowed.
- return;
- } else if (from == null || from.isJavaType()) {
- if (convertIfRequired(message, to)) {
- // Java->Java transformation just relies on TypeConverter if no explicit transformer
- return;
- } else if (from == null) {
- // {undefined}->Other transformation - assuming it's already in expected shape
- return;
- } else if (applyTransformerByToModel(message, from, to)) {
- // Java->Other transformation - found a transformer supports 'to' data model
- return;
- }
- } else if (from != null) {
- if (to.isJavaType()) {
- if (applyTransformerByFromModel(message, from, to)) {
- // Other->Java transformation - found a transformer supprts 'from' data model
- return;
- }
- } else if (applyTransformerChain(message, from, to)) {
- // Other->Other transformation - found a transformer chain
- return;
- }
- }
-
- throw new IllegalArgumentException("No Transformer found for [from='" + from + "', to='" + to + "']");
- }
-
- private boolean convertIfRequired(Message message, DataType type) throws Exception {
- // TODO for better performance it may be better to add TypeConveterTransformer
- // into transformer registry automatically to avoid unnecessary scan in transformer registry
- CamelContext context = message.getExchange().getContext();
- if (type != null && type.isJavaType() && type.getName() != null) {
- Class<?> typeJava = getClazz(type.getName(), context);
- if (!typeJava.isAssignableFrom(message.getBody().getClass())) {
- LOG.debug("Converting to '{}'", typeJava.getName());
- message.setBody(message.getMandatoryBody(typeJava));
- return true;
- }
- }
- return false;
- }
-
- private boolean applyTransformer(Transformer transformer, Message message, DataType from, DataType to) throws Exception {
- if (transformer != null) {
- LOG.debug("Applying transformer: from='{}', to='{}', transformer='{}'", from, to, transformer);
- transformer.transform(message, from, to);
- return true;
- }
- return false;
- }
- private boolean applyExactlyMatchedTransformer(Message message, DataType from, DataType to) throws Exception {
- Transformer transformer = message.getExchange().getContext().resolveTransformer(from, to);
- return applyTransformer(transformer, message, from, to);
- }
-
- private boolean applyTransformerByToModel(Message message, DataType from, DataType to) throws Exception {
- Transformer transformer = message.getExchange().getContext().resolveTransformer(to.getModel());
- return applyTransformer(transformer, message, from, to);
- }
-
- private boolean applyTransformerByFromModel(Message message, DataType from, DataType to) throws Exception {
- Transformer transformer = message.getExchange().getContext().resolveTransformer(from.getModel());
- return applyTransformer(transformer, message, from, to);
- }
-
- private boolean applyTransformerChain(Message message, DataType from, DataType to) throws Exception {
- CamelContext context = message.getExchange().getContext();
- Transformer fromTransformer = context.resolveTransformer(from.getModel());
- Transformer toTransformer = context.resolveTransformer(to.getModel());
- if (fromTransformer != null && toTransformer != null) {
- LOG.debug("Applying transformer 1/2: from='{}', to='{}', transformer='{}'", from, to, fromTransformer);
- fromTransformer.transform(message, from, new DataType(Object.class));
- LOG.debug("Applying transformer 2/2: from='{}', to='{}', transformer='{}'", from, to, toTransformer);
- toTransformer.transform(message, new DataType(Object.class), to);
- return true;
- }
- return false;
- }
-
- private Class<?> getClazz(String type, CamelContext context) throws Exception {
- return context.getClassResolver().resolveMandatoryClass(type);
- }
-
- private DataType getCurrentType(Exchange exchange, String name) {
- Object prop = exchange.getProperty(name);
- if (prop instanceof DataType) {
- return (DataType)prop;
- } else if (prop instanceof String) {
- DataType answer = new DataType((String)prop);
- exchange.setProperty(name, answer);
- return answer;
- }
- return null;
- }
- }
}
http://git-wip-us.apache.org/repos/asf/camel/blob/25b2ba25/camel-core/src/main/java/org/apache/camel/processor/ContractAdvice.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/ContractAdvice.java b/camel-core/src/main/java/org/apache/camel/processor/ContractAdvice.java
new file mode 100644
index 0000000..15a3d61
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/processor/ContractAdvice.java
@@ -0,0 +1,152 @@
+package org.apache.camel.processor;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.spi.Contract;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Transformer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A {@code CamelInternalProcessorAdvice} which performs Transformation and Validation
+ * according to the data type Contract.
+ *
+ * TODO add declarative validation
+ * @see CamelInternalProcessor, CamelInternalProcessorAdvice
+ */
+public class ContractAdvice implements CamelInternalProcessorAdvice {
+ private static final Logger LOG = LoggerFactory.getLogger(CamelInternalProcessor.class);
+
+ private Contract contract;
+
+ public ContractAdvice(Contract contract) {
+ this.contract = contract;
+ }
+
+ @Override
+ public Object before(Exchange exchange) throws Exception {
+ DataType from = getCurrentType(exchange, Exchange.INPUT_TYPE);
+ DataType to = contract.getInputType();
+ if (to != null && !to.equals(from)) {
+ LOG.debug("Looking for transformer for INPUT: from='{}', to='{}'", from, to);
+ doTransform(exchange.getIn(), from, to);
+ exchange.setProperty(Exchange.INPUT_TYPE, to);
+ }
+ return null;
+ }
+
+ @Override
+ public void after(Exchange exchange, Object data) throws Exception {
+ Message target = exchange.hasOut() ? exchange.getOut() : exchange.getIn();
+ DataType from = getCurrentType(exchange, exchange.hasOut() ? Exchange.OUTPUT_TYPE : Exchange.INPUT_TYPE);
+ DataType to = contract.getOutputType();
+ if (to != null && !to.equals(from)) {
+ LOG.debug("Looking for transformer for OUTPUT: from='{}', to='{}'", from, to);
+ doTransform(target, from, to);
+ exchange.setProperty(exchange.hasOut() ? Exchange.OUTPUT_TYPE : Exchange.INPUT_TYPE, to);
+ }
+ }
+
+ private void doTransform(Message message, DataType from, DataType to) throws Exception {
+ // transform into 'from' type before performing declared transformation
+ convertIfRequired(message, from);
+
+ if (applyExactlyMatchedTransformer(message, from, to)) {
+ // Found exactly matched transformer. Java-Java transformer is also allowed.
+ return;
+ } else if (from == null || from.isJavaType()) {
+ if (convertIfRequired(message, to)) {
+ // Java->Java transformation just relies on TypeConverter if no explicit transformer
+ return;
+ } else if (from == null) {
+ // {undefined}->Other transformation - assuming it's already in expected shape
+ return;
+ } else if (applyTransformerByToModel(message, from, to)) {
+ // Java->Other transformation - found a transformer supports 'to' data model
+ return;
+ }
+ } else if (from != null) {
+ if (to.isJavaType()) {
+ if (applyTransformerByFromModel(message, from, to)) {
+ // Other->Java transformation - found a transformer supprts 'from' data model
+ return;
+ }
+ } else if (applyTransformerChain(message, from, to)) {
+ // Other->Other transformation - found a transformer chain
+ return;
+ }
+ }
+
+ throw new IllegalArgumentException("No Transformer found for [from='" + from + "', to='" + to + "']");
+ }
+
+ private boolean convertIfRequired(Message message, DataType type) throws Exception {
+ // TODO for better performance it may be better to add TypeConveterTransformer
+ // into transformer registry automatically to avoid unnecessary scan in transformer registry
+ CamelContext context = message.getExchange().getContext();
+ if (type != null && type.isJavaType() && type.getName() != null) {
+ Class<?> typeJava = getClazz(type.getName(), context);
+ if (!typeJava.isAssignableFrom(message.getBody().getClass())) {
+ LOG.debug("Converting to '{}'", typeJava.getName());
+ message.setBody(message.getMandatoryBody(typeJava));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean applyTransformer(Transformer transformer, Message message, DataType from, DataType to) throws Exception {
+ if (transformer != null) {
+ LOG.debug("Applying transformer: from='{}', to='{}', transformer='{}'", from, to, transformer);
+ transformer.transform(message, from, to);
+ return true;
+ }
+ return false;
+ }
+ private boolean applyExactlyMatchedTransformer(Message message, DataType from, DataType to) throws Exception {
+ Transformer transformer = message.getExchange().getContext().resolveTransformer(from, to);
+ return applyTransformer(transformer, message, from, to);
+ }
+
+ private boolean applyTransformerByToModel(Message message, DataType from, DataType to) throws Exception {
+ Transformer transformer = message.getExchange().getContext().resolveTransformer(to.getModel());
+ return applyTransformer(transformer, message, from, to);
+ }
+
+ private boolean applyTransformerByFromModel(Message message, DataType from, DataType to) throws Exception {
+ Transformer transformer = message.getExchange().getContext().resolveTransformer(from.getModel());
+ return applyTransformer(transformer, message, from, to);
+ }
+
+ private boolean applyTransformerChain(Message message, DataType from, DataType to) throws Exception {
+ CamelContext context = message.getExchange().getContext();
+ Transformer fromTransformer = context.resolveTransformer(from.getModel());
+ Transformer toTransformer = context.resolveTransformer(to.getModel());
+ if (fromTransformer != null && toTransformer != null) {
+ LOG.debug("Applying transformer 1/2: from='{}', to='{}', transformer='{}'", from, to, fromTransformer);
+ fromTransformer.transform(message, from, new DataType(Object.class));
+ LOG.debug("Applying transformer 2/2: from='{}', to='{}', transformer='{}'", from, to, toTransformer);
+ toTransformer.transform(message, new DataType(Object.class), to);
+ return true;
+ }
+ return false;
+ }
+
+ private Class<?> getClazz(String type, CamelContext context) throws Exception {
+ return context.getClassResolver().resolveMandatoryClass(type);
+ }
+
+ private DataType getCurrentType(Exchange exchange, String name) {
+ Object prop = exchange.getProperty(name);
+ if (prop instanceof DataType) {
+ return (DataType)prop;
+ } else if (prop instanceof String) {
+ DataType answer = new DataType((String)prop);
+ exchange.setProperty(name, answer);
+ return answer;
+ }
+ return null;
+ }
+}
\ No newline at end of file