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/06/24 17:42:11 UTC

[2/5] camel git commit: CAMEL-11379: Optimise - core type converters to be invoked faster

CAMEL-11379: Optimise - core type converters to be invoked faster


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/4a72341e
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/4a72341e
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/4a72341e

Branch: refs/heads/master
Commit: 4a72341ebffc9177be2d2897fdcfbc15a6c65c41
Parents: 79a1ae9
Author: Claus Ibsen <da...@apache.org>
Authored: Sat Jun 24 11:10:19 2017 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Sat Jun 24 13:55:42 2017 +0200

----------------------------------------------------------------------
 .../org/apache/camel/impl/DefaultExchange.java  |  4 +-
 .../converter/BaseTypeConverterRegistry.java    | 10 +-
 .../impl/converter/OptimisedTypeConverter.java  | 98 ++++++++++++++++++++
 .../apache/camel/builder/SimpleBuilderTest.java |  2 +-
 .../apache/camel/converter/ConverterTest.java   |  2 +-
 5 files changed, 111 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/4a72341e/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java
index 9888972..2ae2f5b 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java
@@ -185,7 +185,7 @@ public final class DefaultExchange implements Exchange {
         Object value = getProperty(name);
         if (value == null) {
             // lets avoid NullPointerException when converting to boolean for null values
-            if (boolean.class == type || Boolean.class == type) {
+            if (boolean.class == type) {
                 return (T) Boolean.FALSE;
             }
             return null;
@@ -205,7 +205,7 @@ public final class DefaultExchange implements Exchange {
         Object value = getProperty(name, defaultValue);
         if (value == null) {
             // lets avoid NullPointerException when converting to boolean for null values
-            if (boolean.class == type || Boolean.class == type) {
+            if (boolean.class == type) {
                 return (T) Boolean.FALSE;
             }
             return null;

http://git-wip-us.apache.org/repos/asf/camel/blob/4a72341e/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java b/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
index 28d9caf1..21e437a 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
@@ -64,6 +64,7 @@ import org.slf4j.LoggerFactory;
  */
 public abstract class BaseTypeConverterRegistry extends ServiceSupport implements TypeConverter, TypeConverterRegistry, CamelContextAware {
     protected final Logger log = LoggerFactory.getLogger(getClass());
+    protected final OptimisedTypeConverter optimisedTypeConverter = new OptimisedTypeConverter();
     protected final ConcurrentMap<TypeMapping, TypeConverter> typeMappings = new ConcurrentHashMap<TypeMapping, TypeConverter>();
     // for misses use a soft reference cache map, as the classes may be un-deployed at runtime
     protected final LRUSoftCache<TypeMapping, TypeMapping> misses = new LRUSoftCache<TypeMapping, TypeMapping>(1000);
@@ -256,7 +257,7 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
                 noopCounter.increment();
             }
             // lets avoid NullPointerException when converting to boolean for null values
-            if (boolean.class == type || Boolean.class == type) {
+            if (boolean.class == type) {
                 return Boolean.FALSE;
             }
             return null;
@@ -292,6 +293,13 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
             attemptCounter.increment();
         }
 
+        // use the optimised core converter first
+        Object result = optimisedTypeConverter.convertTo(type, exchange, value);
+        if (result != null) {
+            log.trace("Using optimised converter to convert: {} -> {}", type, value.getClass());
+            return result;
+        }
+
         // check if we have tried it before and if its a miss
         TypeMapping key = new TypeMapping(type, value.getClass());
         if (misses.containsKey(key)) {

http://git-wip-us.apache.org/repos/asf/camel/blob/4a72341e/camel-core/src/main/java/org/apache/camel/impl/converter/OptimisedTypeConverter.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/converter/OptimisedTypeConverter.java b/camel-core/src/main/java/org/apache/camel/impl/converter/OptimisedTypeConverter.java
new file mode 100644
index 0000000..45cc390
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/converter/OptimisedTypeConverter.java
@@ -0,0 +1,98 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.impl.converter;
+
+import java.util.Iterator;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.converter.ObjectConverter;
+import org.apache.camel.converter.TimePatternConverter;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * Optimised type converter for performing the most common conversions using the type converters
+ * from camel-core.
+ */
+public class OptimisedTypeConverter {
+
+    /**
+     * Attempts to convert the value to the given type
+     *
+     * @param type  the type to convert to
+     * @param exchange the exchange, may be null
+     * @param value the value
+     * @return the converted value, or null if no core type converter exists to convert
+     */
+    public Object convertTo(final Class<?> type, final Exchange exchange, final Object value) {
+        // converting to a String is very common
+        if (type == String.class) {
+            Class fromType = value.getClass();
+            if (fromType == boolean.class || fromType == Boolean.class) {
+                return value.toString();
+            } else if (fromType == int.class || fromType == Integer.class) {
+                return value.toString();
+            } else if (fromType == long.class || fromType == Long.class) {
+                return value.toString();
+            } else if (fromType == char[].class) {
+                return ObjectConverter.fromCharArray((char[]) value);
+            } else if (fromType == StringBuffer.class || fromType == StringBuilder.class) {
+                return value.toString();
+            }
+        }
+
+        // special for String -> long where we support time patterns
+        if (type == long.class || type == Long.class) {
+            Class fromType = value.getClass();
+            if (fromType == String.class) {
+                return TimePatternConverter.toMilliSeconds(value.toString());
+            }
+        }
+
+        if (type == boolean.class || type == Boolean.class) {
+            return ObjectConverter.toBoolean(value);
+        } else if (type == int.class || type == Integer.class) {
+            return ObjectConverter.toInteger(value);
+        } else if (type == long.class || type == Long.class) {
+            return ObjectConverter.toLong(value);
+        } else if (type == byte.class || type == Byte.class) {
+            return ObjectConverter.toByte(value);
+        } else if (type == double.class || type == Double.class) {
+            return ObjectConverter.toDouble(value);
+        } else if (type == float.class || type == Float.class) {
+            return ObjectConverter.toFloat(value);
+        } else if (type == short.class || type == Short.class) {
+            return ObjectConverter.toShort(value);
+        } else if ((type == char.class || type == Character.class) && value.getClass() == String.class) {
+            return ObjectConverter.toCharacter((String) value);
+        } else if ((type == char[].class || type == Character[].class) && value.getClass() == String.class) {
+            return ObjectConverter.toCharArray((String) value);
+        }
+
+        if (type == Iterator.class) {
+            return ObjectHelper.createIterator(value);
+        } else if (type == Iterable.class) {
+            return ObjectHelper.createIterable(value);
+        }
+
+        if (type == Class.class) {
+            return ObjectConverter.toClass(value, exchange);
+        }
+
+        // no optimised type converter found
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/4a72341e/camel-core/src/test/java/org/apache/camel/builder/SimpleBuilderTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/builder/SimpleBuilderTest.java b/camel-core/src/test/java/org/apache/camel/builder/SimpleBuilderTest.java
index 915ae53..c7cf355 100644
--- a/camel-core/src/test/java/org/apache/camel/builder/SimpleBuilderTest.java
+++ b/camel-core/src/test/java/org/apache/camel/builder/SimpleBuilderTest.java
@@ -66,7 +66,7 @@ public class SimpleBuilderTest extends TestSupport {
             SimpleBuilder.simple("${body}", int.class).evaluate(exchange, Object.class);
             fail("Should have thrown exception");
         } catch (TypeConversionException e) {
-            assertIsInstanceOf(NumberFormatException.class, e.getCause().getCause());
+            assertIsInstanceOf(NumberFormatException.class, e.getCause());
         }
 
         assertEquals(true, SimpleBuilder.simple("${header.cool}", boolean.class).evaluate(exchange, Object.class));

http://git-wip-us.apache.org/repos/asf/camel/blob/4a72341e/camel-core/src/test/java/org/apache/camel/converter/ConverterTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/converter/ConverterTest.java b/camel-core/src/test/java/org/apache/camel/converter/ConverterTest.java
index 0f2fab5..8bafbfb 100644
--- a/camel-core/src/test/java/org/apache/camel/converter/ConverterTest.java
+++ b/camel-core/src/test/java/org/apache/camel/converter/ConverterTest.java
@@ -242,7 +242,7 @@ public class ConverterTest extends TestCase {
             converter.mandatoryConvertTo(char.class, "ABC");
             fail("Should have thrown an exception");
         } catch (TypeConversionException e) {
-            assertEquals("java.lang.IllegalArgumentException: String must have exactly a length of 1: ABC", e.getCause().getMessage());
+            assertEquals("String must have exactly a length of 1: ABC", e.getCause().getMessage());
         }
     }