You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by zr...@apache.org on 2018/03/23 14:55:16 UTC

[camel] branch master updated (c3f93db -> 9dbf5eb)

This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from c3f93db  CAMEL-12412 - Camel-Git: Add show tags operation
     new e9dac47  CAMEL-12334: Mapped date to LocalDate and time to LocalTime
     new 9499be8  CAMEL-12334: Mapped date to LocalDate and time to OffsetTime. Added properties to control the behavior
     new d6cdc13  CAMEL-12334: unify date (de)serialization handling
     new c6c5621  CAMEL-12334: allow customization of types in ge...
     new 9dbf5eb  CAMEL-12334: change defaults and add support fo...

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../camel-salesforce-component/README.md           |   2 +-
 .../camel-salesforce-component/pom.xml             |   5 +
 .../src/main/docs/salesforce-component.adoc        |  50 ++--
 .../salesforce/api/utils/DateTimeConverter.java    |  56 ----
 .../salesforce/api/utils/DateTimeHandling.java     |  59 +++++
 .../salesforce/api/utils/DateTimeUtils.java        |  56 ----
 ...TimeDeserializer.java => InstantConverter.java} |  40 +--
 ...ateTimeModule.java => InstantDeserializer.java} |  20 +-
 ...eTimeSerializer.java => InstantSerializer.java} |  29 +--
 .../component/salesforce/api/utils/JsonUtils.java  |  14 +-
 ...Serializer.java => LocalDateTimeConverter.java} |  36 +--
 ...ializer.java => LocalDateTimeDeserializer.java} |  29 +--
 ...erializer.java => LocalDateTimeSerializer.java} |  31 ++-
 ...erializer.java => OffsetDateTimeConverter.java} |  39 +--
 ...alizer.java => OffsetDateTimeDeserializer.java} |  25 +-
 ...rializer.java => OffsetDateTimeSerializer.java} |  30 +--
 .../salesforce/api/utils/OffsetTimeConverter.java  |  52 ++++
 ...TimeModule.java => OffsetTimeDeserializer.java} |  17 +-
 ...teTimeModule.java => OffsetTimeSerializer.java} |  19 +-
 .../component/salesforce/api/utils/TimeModule.java |  76 ++++++
 .../salesforce/api/utils/XStreamUtils.java         | 119 +++++++++
 ...serializer.java => ZonedDateTimeConverter.java} |  39 +--
 ...eModule.java => ZonedDateTimeDeserializer.java} |  21 +-
 .../internal/client/DefaultCompositeApiClient.java |  47 +---
 .../internal/client/DefaultRestClient.java         |   9 +-
 .../salesforce/internal/client/XStreamUtils.java   |  74 ------
 .../internal/processor/XmlRestProcessor.java       |  24 +-
 .../salesforce/api/MultiSelectPicklistXmlTest.java |  14 +-
 .../component/salesforce/api/dto/LimitsTest.java   |  32 +--
 .../salesforce/api/dto/RecentItemTest.java         |  27 +-
 .../salesforce/api/dto/RestErrorTest.java          |  11 +-
 .../api/dto/approval/ApprovalRequestTest.java      |  39 +--
 .../api/dto/approval/ApprovalRequestsTest.java     |  23 +-
 .../api/dto/approval/ApprovalResultTest.java       |  39 +--
 .../salesforce/api/dto/approval/ApprovalsTest.java |  27 +-
 .../dto/composite/SObjectBatchResponseTest.java    |  71 ++---
 .../api/dto/composite/SObjectBatchTest.java        | 177 +++++++------
 .../composite/SObjectCompositeResponseTest.java    |   5 +-
 .../api/dto/composite/SObjectCompositeTest.java    |   4 +-
 .../api/dto/composite/SObjectTreeResponseTest.java |  12 +-
 .../api/dto/composite/SObjectTreeTest.java         |  62 ++---
 .../salesforce/api/utils/DateTimeUtilsTest.java    |  47 ----
 .../api/utils/SalesforceTimeFormatsTest.java       | 203 +++++++++++++++
 .../camel-salesforce-maven-plugin/README.md        |  18 +-
 .../src/it/{simple-it => customized-types}/pom.xml |  15 +-
 .../src/it/customized-types/verify.groovy}         |  18 +-
 .../src/it/simple-it/pom.xml                       |   8 +-
 .../apache/camel/maven/AbstractSalesforceMojo.java |   5 +
 .../java/org/apache/camel/maven/GenerateMojo.java  |  33 ++-
 .../camel/maven/CamelSalesforceMojoOutputTest.java |  65 +++--
 .../src/test/resources/asset.json                  | 290 +++++++++++++++++++++
 .../src/test/resources/generated/Asset.java        | 137 ++++++++++
 .../resources/generated/Asset_LocalDateTime.java   | 137 ++++++++++
 53 files changed, 1693 insertions(+), 844 deletions(-)
 delete mode 100644 components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeConverter.java
 create mode 100644 components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeHandling.java
 delete mode 100644 components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java
 copy components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeDeserializer.java => InstantConverter.java} (50%)
 copy components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeModule.java => InstantDeserializer.java} (59%)
 copy components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeSerializer.java => InstantSerializer.java} (57%)
 copy components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeSerializer.java => LocalDateTimeConverter.java} (50%)
 copy components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeDeserializer.java => LocalDateTimeDeserializer.java} (59%)
 copy components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeSerializer.java => LocalDateTimeSerializer.java} (57%)
 copy components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeDeserializer.java => OffsetDateTimeConverter.java} (50%)
 copy components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeDeserializer.java => OffsetDateTimeDeserializer.java} (59%)
 rename components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeSerializer.java => OffsetDateTimeSerializer.java} (57%)
 create mode 100644 components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetTimeConverter.java
 copy components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeModule.java => OffsetTimeDeserializer.java} (67%)
 copy components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeModule.java => OffsetTimeSerializer.java} (63%)
 create mode 100644 components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
 create mode 100644 components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/XStreamUtils.java
 rename components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeDeserializer.java => ZonedDateTimeConverter.java} (50%)
 copy components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/{DateTimeModule.java => ZonedDateTimeDeserializer.java} (60%)
 delete mode 100644 components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/XStreamUtils.java
 delete mode 100644 components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java
 create mode 100644 components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/SalesforceTimeFormatsTest.java
 copy components/camel-salesforce/camel-salesforce-maven-plugin/src/it/{simple-it => customized-types}/pom.xml (85%)
 rename components/camel-salesforce/{camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeModule.java => camel-salesforce-maven-plugin/src/it/customized-types/verify.groovy} (66%)
 create mode 100644 components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/asset.json
 create mode 100644 components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset.java
 create mode 100644 components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset_LocalDateTime.java

-- 
To stop receiving notification emails like this one, please contact
zregvart@apache.org.

[camel] 05/05: CAMEL-12334: change defaults and add support fo...

Posted by zr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 9dbf5eb2e8e2cc0c4b611cbfb564f961e045acec
Author: Zoran Regvart <zr...@apache.org>
AuthorDate: Fri Mar 23 15:43:35 2018 +0100

    CAMEL-12334: change defaults and add support fo...
    
    ...r OffsetTime
    
    The new defaults when generating Salesforce DTOs are:
    
     - java.time.ZonedDateTime for dateTime
     - java.time.OffsetTime for time
     - java.time.LocalDate for date
    
    Even though some client code might break because of this change its easy
    to use plugins `customTypes` parameter to use the old types.
---
 .../salesforce/api/utils/DateTimeHandling.java     |  13 +++
 .../salesforce/api/utils/OffsetTimeConverter.java  |  52 ++++++++++
 .../api/utils/OffsetTimeDeserializer.java          |  32 ++++++
 .../salesforce/api/utils/OffsetTimeSerializer.java |  34 ++++++
 .../component/salesforce/api/utils/TimeModule.java |   4 +
 .../salesforce/api/utils/XStreamUtils.java         |   1 +
 .../api/utils/SalesforceTimeFormatsTest.java       |   6 +-
 .../java/org/apache/camel/maven/GenerateMojo.java  |   6 +-
 .../src/test/resources/asset.json                  | 114 +++++++++++++++++++++
 .../src/test/resources/generated/Asset.java        |  36 ++++++-
 .../resources/generated/Asset_LocalDateTime.java   |  30 ++++++
 11 files changed, 321 insertions(+), 7 deletions(-)

diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeHandling.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeHandling.java
index 6a262cf..3da6903 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeHandling.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeHandling.java
@@ -41,6 +41,19 @@ final class DateTimeHandling {
         .appendOffset("+HHMM", "Z")//
         .toFormatter();
 
+    static final DateTimeFormatter ISO_OFFSET_TIME = new DateTimeFormatterBuilder()//
+        .parseCaseInsensitive()//
+        .appendValue(HOUR_OF_DAY, 2)//
+        .appendLiteral(':')//
+        .appendValue(MINUTE_OF_HOUR, 2)//
+        .appendLiteral(':')//
+        .appendValue(SECOND_OF_MINUTE, 2)//
+        .optionalStart()//
+        .appendFraction(NANO_OF_SECOND, 3, 3, true)//
+        .optionalEnd()//
+        .appendOffset("+HHMM", "Z")//
+        .toFormatter();
+
     private DateTimeHandling() {
     }
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetTimeConverter.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetTimeConverter.java
new file mode 100644
index 0000000..76c7269
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetTimeConverter.java
@@ -0,0 +1,52 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.time.OffsetTime;
+
+import com.thoughtworks.xstream.converters.SingleValueConverter;
+
+import static org.apache.camel.component.salesforce.api.utils.DateTimeHandling.ISO_OFFSET_TIME;
+
+final class OffsetTimeConverter implements SingleValueConverter {
+
+    static final SingleValueConverter INSTANCE = new OffsetTimeConverter();
+
+    private OffsetTimeConverter() {
+    }
+
+    @Override
+    public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) {
+        return OffsetTime.class.equals(type);
+    }
+
+    @Override
+    public Object fromString(final String value) {
+        return OffsetTime.parse(value, ISO_OFFSET_TIME);
+    }
+
+    @Override
+    public String toString(final Object value) {
+        if (value == null) {
+            return null;
+        }
+
+        final OffsetTime offsetTime = (OffsetTime) value;
+
+        return ISO_OFFSET_TIME.format(offsetTime);
+    }
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetTimeDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetTimeDeserializer.java
new file mode 100644
index 0000000..fc360a0
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetTimeDeserializer.java
@@ -0,0 +1,32 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.time.OffsetTime;
+
+import com.fasterxml.jackson.databind.JsonDeserializer;
+
+final class OffsetTimeDeserializer extends com.fasterxml.jackson.datatype.jsr310.deser.OffsetTimeDeserializer {
+
+    static final JsonDeserializer<OffsetTime> INSTANCE = new OffsetTimeDeserializer();
+
+    private static final long serialVersionUID = 1L;
+
+    private OffsetTimeDeserializer() {
+        super(DateTimeHandling.ISO_OFFSET_TIME);
+    }
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetTimeSerializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetTimeSerializer.java
new file mode 100644
index 0000000..6f0e497
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetTimeSerializer.java
@@ -0,0 +1,34 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.time.OffsetTime;
+
+import com.fasterxml.jackson.databind.JsonSerializer;
+
+final class OffsetTimeSerializer extends com.fasterxml.jackson.datatype.jsr310.ser.OffsetTimeSerializer {
+
+    static final JsonSerializer<OffsetTime> INSTANCE = new OffsetTimeSerializer();
+
+    private static final long serialVersionUID = 1L;
+
+    private OffsetTimeSerializer() {
+        super(com.fasterxml.jackson.datatype.jsr310.ser.OffsetTimeSerializer.INSTANCE, null,
+            DateTimeHandling.ISO_OFFSET_TIME);
+    }
+
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
index bcad059..fcbfc2e 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
@@ -20,6 +20,7 @@ import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.OffsetDateTime;
+import java.time.OffsetTime;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 
@@ -61,6 +62,9 @@ public class TimeModule extends SimpleModule {
 
         addSerializer(Instant.class, InstantSerializer.INSTANCE);
         addDeserializer(Instant.class, InstantDeserializer.INSTANCE);
+
+        addSerializer(OffsetTime.class, OffsetTimeSerializer.INSTANCE);
+        addDeserializer(OffsetTime.class, OffsetTimeDeserializer.INSTANCE);
     }
 
     @Override
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/XStreamUtils.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/XStreamUtils.java
index 4ec04a8..33d73d2 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/XStreamUtils.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/XStreamUtils.java
@@ -106,6 +106,7 @@ public final class XStreamUtils {
         result.registerConverter(OffsetDateTimeConverter.INSTANCE, XStream.PRIORITY_VERY_HIGH);
         result.registerConverter(ZonedDateTimeConverter.INSTANCE, XStream.PRIORITY_VERY_HIGH);
         result.registerConverter(InstantConverter.INSTANCE, XStream.PRIORITY_VERY_HIGH);
+        result.registerConverter(OffsetTimeConverter.INSTANCE, XStream.PRIORITY_VERY_HIGH);
 
         result.setMarshallingStrategy(new TreeMarshallingStrategy());
 
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/SalesforceTimeFormatsTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/SalesforceTimeFormatsTest.java
index 2a47013..e4cd63b 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/SalesforceTimeFormatsTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/SalesforceTimeFormatsTest.java
@@ -19,6 +19,8 @@ package org.apache.camel.component.salesforce.api.utils;
 import java.io.IOException;
 import java.time.Instant;
 import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.OffsetTime;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
@@ -183,7 +185,9 @@ public class SalesforceTimeFormatsTest {
             dto(instant,
                 instant.atZone(ZoneId.systemDefault())
                     .format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"))), // 10
-            dto(ZonedDateTime.of(2018, 03, 22, 9, 58, 8, 5000000, ZoneId.of("Z")), "2018-03-22T09:58:08.005Z") // 11
+            dto(ZonedDateTime.of(2018, 03, 22, 9, 58, 8, 5000000, ZoneId.of("Z")), "2018-03-22T09:58:08.005Z"), // 11
+            dto(OffsetTime.of(LocalTime.MIDNIGHT, ZoneOffset.UTC), "00:00:00.000Z"), // 12
+            dto(OffsetTime.of(12, 13, 14, 7000000, ZoneOffset.UTC), "12:13:14.007Z") // 13
         );
     }
 
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
index ef9031c..df2eb9b 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
@@ -484,15 +484,15 @@ public class GenerateMojo extends AbstractSalesforceMojo {
             {"double", "Double"}, //
             {"boolean", "Boolean"}, //
             {"byte", "Byte"}, //
-            {"dateTime", "java.time.ZonedDateTime"}, //
             // the blob base64Binary type is mapped to String URL for retrieving
             // the blob
             {"base64Binary", "String"}, //
             {"unsignedInt", "Long"}, //
             {"unsignedShort", "Integer"}, //
             {"unsignedByte", "Short"}, //
-            {"time", "java.time.ZonedDateTime"}, //
-            {"date", "java.time.ZonedDateTime"}, //
+            {"dateTime", "java.time.ZonedDateTime"}, //
+            {"time", "java.time.OffsetTime"}, //
+            {"date", "java.time.LocalDate"}, //
             {"g", "java.time.ZonedDateTime"}, //
             // Salesforce maps any types like string, picklist, reference, etc.
             // to string
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/asset.json b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/asset.json
index 2caa54c..9864a8e 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/asset.json
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/asset.json
@@ -122,6 +122,120 @@
       "unique": false,
       "updateable": true,
       "writeRequiresMasterRead": false
+    },
+    {
+      "aggregatable": true,
+      "autoNumber": false,
+      "byteLength": 0,
+      "calculated": false,
+      "calculatedFormula": null,
+      "cascadeDelete": false,
+      "caseSensitive": false,
+      "compoundFieldName": null,
+      "controllerName": null,
+      "createable": true,
+      "custom": true,
+      "defaultValue": null,
+      "defaultValueFormula": null,
+      "defaultedOnCreate": false,
+      "dependentPicklist": false,
+      "deprecatedAndHidden": false,
+      "digits": 0,
+      "displayLocationInDecimal": false,
+      "encrypted": false,
+      "externalId": false,
+      "extraTypeInfo": null,
+      "filterable": true,
+      "filteredLookupInfo": null,
+      "groupable": false,
+      "highScaleNumber": false,
+      "htmlFormatted": false,
+      "idLookup": false,
+      "inlineHelpText": null,
+      "label": "date_time",
+      "length": 0,
+      "mask": null,
+      "maskType": null,
+      "name": "date_time",
+      "nameField": false,
+      "namePointing": false,
+      "nillable": true,
+      "permissionable": true,
+      "picklistValues": [],
+      "polymorphicForeignKey": false,
+      "precision": 0,
+      "queryByDistance": false,
+      "referenceTargetField": null,
+      "referenceTo": [],
+      "relationshipName": null,
+      "relationshipOrder": null,
+      "restrictedDelete": false,
+      "restrictedPicklist": false,
+      "scale": 0,
+      "searchPrefilterable": false,
+      "soapType": "xsd:dateTime",
+      "sortable": true,
+      "type": "datetime",
+      "unique": false,
+      "updateable": true,
+      "writeRequiresMasterRead": false
+    },
+    {
+      "aggregatable": false,
+      "autoNumber": false,
+      "byteLength": 0,
+      "calculated": false,
+      "calculatedFormula": null,
+      "cascadeDelete": false,
+      "caseSensitive": false,
+      "compoundFieldName": null,
+      "controllerName": null,
+      "createable": true,
+      "custom": true,
+      "defaultValue": null,
+      "defaultValueFormula": null,
+      "defaultedOnCreate": false,
+      "dependentPicklist": false,
+      "deprecatedAndHidden": false,
+      "digits": 0,
+      "displayLocationInDecimal": false,
+      "encrypted": false,
+      "externalId": false,
+      "extraTypeInfo": null,
+      "filterable": true,
+      "filteredLookupInfo": null,
+      "groupable": false,
+      "highScaleNumber": false,
+      "htmlFormatted": false,
+      "idLookup": false,
+      "inlineHelpText": null,
+      "label": "time",
+      "length": 0,
+      "mask": null,
+      "maskType": null,
+      "name": "time",
+      "nameField": false,
+      "namePointing": false,
+      "nillable": true,
+      "permissionable": true,
+      "picklistValues": [],
+      "polymorphicForeignKey": false,
+      "precision": 0,
+      "queryByDistance": false,
+      "referenceTargetField": null,
+      "referenceTo": [],
+      "relationshipName": null,
+      "relationshipOrder": null,
+      "restrictedDelete": false,
+      "restrictedPicklist": false,
+      "scale": 0,
+      "searchPrefilterable": false,
+      "soapType": "xsd:time",
+      "sortable": true,
+      "type": "time",
+      "unique": false,
+      "updateable": true,
+      "writeRequiresMasterRead": false
     }
   ],
   "hasSubtypes": false,
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset.java
index 00468ec..de25141 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset.java
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset.java
@@ -32,18 +32,44 @@ public class Asset extends AbstractDescribedSObjectBase {
     private static final SObjectDescription DESCRIPTION = createSObjectDescription();
 
     // InstallDate
-    private java.time.ZonedDateTime InstallDate;
+    private java.time.LocalDate InstallDate;
 
     @JsonProperty("InstallDate")
-    public java.time.ZonedDateTime getInstallDate() {
+    public java.time.LocalDate getInstallDate() {
         return this.InstallDate;
     }
 
     @JsonProperty("InstallDate")
-    public void setInstallDate(java.time.ZonedDateTime InstallDate) {
+    public void setInstallDate(java.time.LocalDate InstallDate) {
         this.InstallDate = InstallDate;
     }
 
+    // date_time
+    private java.time.ZonedDateTime date_time;
+
+    @JsonProperty("date_time")
+    public java.time.ZonedDateTime getdate_time() {
+        return this.date_time;
+    }
+
+    @JsonProperty("date_time")
+    public void setdate_time(java.time.ZonedDateTime date_time) {
+        this.date_time = date_time;
+    }
+
+    // time
+    private java.time.OffsetTime time;
+
+    @JsonProperty("time")
+    public java.time.OffsetTime gettime() {
+        return this.time;
+    }
+
+    @JsonProperty("time")
+    public void settime(java.time.OffsetTime time) {
+        this.time = time;
+    }
+
 
     @Override
     public final SObjectDescription description() {
@@ -96,6 +122,10 @@ public class Asset extends AbstractDescribedSObjectBase {
         fields1.add(sObjectField1);
         final SObjectField sObjectField2 = createField("InstallDate", "Install Date", "date", "xsd:date", 0, false, true, false, false, false, false, false);
         fields1.add(sObjectField2);
+        final SObjectField sObjectField3 = createField("date_time", "date_time", "datetime", "xsd:dateTime", 0, false, true, false, false, true, false, false);
+        fields1.add(sObjectField3);
+        final SObjectField sObjectField4 = createField("time", "time", "time", "xsd:time", 0, false, true, false, false, true, false, false);
+        fields1.add(sObjectField4);
 
         description.setActivateable(false);
         description.setLabelPlural("Assets");
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset_LocalDateTime.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset_LocalDateTime.java
index a0c6830..1d9d17a 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset_LocalDateTime.java
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset_LocalDateTime.java
@@ -44,6 +44,32 @@ public class Asset extends AbstractDescribedSObjectBase {
         this.InstallDate = InstallDate;
     }
 
+    // date_time
+    private java.time.ZonedDateTime date_time;
+
+    @JsonProperty("date_time")
+    public java.time.ZonedDateTime getdate_time() {
+        return this.date_time;
+    }
+
+    @JsonProperty("date_time")
+    public void setdate_time(java.time.ZonedDateTime date_time) {
+        this.date_time = date_time;
+    }
+
+    // time
+    private java.time.OffsetTime time;
+
+    @JsonProperty("time")
+    public java.time.OffsetTime gettime() {
+        return this.time;
+    }
+
+    @JsonProperty("time")
+    public void settime(java.time.OffsetTime time) {
+        this.time = time;
+    }
+
 
     @Override
     public final SObjectDescription description() {
@@ -96,6 +122,10 @@ public class Asset extends AbstractDescribedSObjectBase {
         fields1.add(sObjectField1);
         final SObjectField sObjectField2 = createField("InstallDate", "Install Date", "date", "xsd:date", 0, false, true, false, false, false, false, false);
         fields1.add(sObjectField2);
+        final SObjectField sObjectField3 = createField("date_time", "date_time", "datetime", "xsd:dateTime", 0, false, true, false, false, true, false, false);
+        fields1.add(sObjectField3);
+        final SObjectField sObjectField4 = createField("time", "time", "time", "xsd:time", 0, false, true, false, false, true, false, false);
+        fields1.add(sObjectField4);
 
         description.setActivateable(false);
         description.setLabelPlural("Assets");

-- 
To stop receiving notification emails like this one, please contact
zregvart@apache.org.

[camel] 03/05: CAMEL-12334: unify date (de)serialization handling

Posted by zr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit d6cdc13ea35c3d861f8a01c55a3f30b14020be44
Author: Zoran Regvart <zr...@apache.org>
AuthorDate: Thu Mar 22 09:13:19 2018 +0100

    CAMEL-12334: unify date (de)serialization handling
    
    This adds support for using any of the following date/time classes:
     - java.util.Date
     - java.time.Instant
     - java.time.LocalDate
     - java.time.ZonedDateTime
     - java.time.OffsetDateTime
    
    With this all usage of Jackson `ObjectMapper` and `XStream` instances
    goes through the single utility method in `JsonUtils` or `XStreamUtils`
    in order to register default serializers/deserializers/converters.
---
 .../camel-salesforce-component/pom.xml             |   5 +
 .../salesforce/api/utils/DateConverter.java        |  56 ------
 .../salesforce/api/utils/DateTimeConverter.java    |  56 ------
 .../salesforce/api/utils/DateTimeHandling.java     |  46 +++++
 .../salesforce/api/utils/DateTimeUtils.java        |  82 ---------
 ...TimeDeserializer.java => InstantConverter.java} |  40 +++--
 .../{DateModule.java => InstantDeserializer.java}  |  20 ++-
 ...eTimeSerializer.java => InstantSerializer.java} |  29 ++-
 .../component/salesforce/api/utils/JsonUtils.java  |   4 +-
 ...Serializer.java => LocalDateTimeConverter.java} |  36 ++--
 ...ializer.java => LocalDateTimeDeserializer.java} |  29 ++-
 ...erializer.java => LocalDateTimeSerializer.java} |  33 ++--
 ...erializer.java => OffsetDateTimeConverter.java} |  39 ++--
 ...alizer.java => OffsetDateTimeDeserializer.java} |  27 ++-
 ...rializer.java => OffsetDateTimeSerializer.java} |  32 ++--
 .../salesforce/api/utils/TimeConverter.java        |  56 ------
 .../salesforce/api/utils/TimeDeserializer.java     |  48 -----
 .../component/salesforce/api/utils/TimeModule.java |  53 +++++-
 .../salesforce/api/utils/XStreamUtils.java         | 118 ++++++++++++
 ...serializer.java => ZonedDateTimeConverter.java} |  39 ++--
 ...eModule.java => ZonedDateTimeDeserializer.java} |  21 ++-
 .../internal/client/DefaultCompositeApiClient.java |  51 +-----
 .../internal/client/DefaultRestClient.java         |   9 +-
 .../salesforce/internal/client/XStreamUtils.java   |  74 --------
 .../internal/processor/XmlRestProcessor.java       |  24 +--
 .../salesforce/api/MultiSelectPicklistXmlTest.java |  14 +-
 .../component/salesforce/api/dto/LimitsTest.java   |  32 ++--
 .../salesforce/api/dto/RecentItemTest.java         |  27 +--
 .../salesforce/api/dto/RestErrorTest.java          |  11 +-
 .../api/dto/approval/ApprovalRequestTest.java      |  39 ++--
 .../api/dto/approval/ApprovalRequestsTest.java     |  23 +--
 .../api/dto/approval/ApprovalResultTest.java       |  39 ++--
 .../salesforce/api/dto/approval/ApprovalsTest.java |  27 +--
 .../dto/composite/SObjectBatchResponseTest.java    |  71 ++++----
 .../api/dto/composite/SObjectBatchTest.java        | 177 +++++++++---------
 .../composite/SObjectCompositeResponseTest.java    |   5 +-
 .../api/dto/composite/SObjectCompositeTest.java    |   4 +-
 .../api/dto/composite/SObjectTreeResponseTest.java |  12 +-
 .../api/dto/composite/SObjectTreeTest.java         |  62 +++----
 .../salesforce/api/utils/DateTimeUtilsTest.java    |  80 ---------
 .../api/utils/SalesforceTimeFormatsTest.java       | 199 +++++++++++++++++++++
 41 files changed, 874 insertions(+), 975 deletions(-)

diff --git a/components/camel-salesforce/camel-salesforce-component/pom.xml b/components/camel-salesforce/camel-salesforce-component/pom.xml
index 5dd6eae..8ec2422 100644
--- a/components/camel-salesforce/camel-salesforce-component/pom.xml
+++ b/components/camel-salesforce/camel-salesforce-component/pom.xml
@@ -91,6 +91,11 @@
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-databind</artifactId>
     </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.datatype</groupId>
+      <artifactId>jackson-datatype-jsr310</artifactId>
+      <version>${jackson2-version}</version>
+    </dependency>
     <!-- json schema -->
     <dependency>
       <groupId>com.fasterxml.jackson.jaxrs</groupId>
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateConverter.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateConverter.java
deleted file mode 100644
index 6fa5ede..0000000
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateConverter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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.component.salesforce.api.utils;
-
-import java.time.LocalDate;
-
-import com.thoughtworks.xstream.converters.ConversionException;
-import com.thoughtworks.xstream.converters.Converter;
-import com.thoughtworks.xstream.converters.MarshallingContext;
-import com.thoughtworks.xstream.converters.UnmarshallingContext;
-import com.thoughtworks.xstream.io.HierarchicalStreamReader;
-import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
-
-/**
- * XStream converter for handling {@link LocalDate} fields.
- */
-public class DateConverter implements Converter {
-
-    @Override
-    public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) {
-        LocalDate date = (LocalDate) o;
-        writer.setValue(DateTimeUtils.formatDate(date));
-    }
-
-    @Override
-    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
-        try {
-            return DateTimeUtils.parseDate(reader.getValue());
-        } catch (Exception e) {
-            throw new ConversionException(
-                    String.format("Error reading LocalDate from value %s: %s",
-                        reader.getValue(), e.getMessage()),
-                    e);
-        }
-    }
-
-    @Override
-    public boolean canConvert(Class aClass) {
-        return LocalDate.class.isAssignableFrom(aClass);
-    }
-
-}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeConverter.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeConverter.java
deleted file mode 100644
index 6722688..0000000
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeConverter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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.component.salesforce.api.utils;
-
-import java.time.ZonedDateTime;
-
-import com.thoughtworks.xstream.converters.ConversionException;
-import com.thoughtworks.xstream.converters.Converter;
-import com.thoughtworks.xstream.converters.MarshallingContext;
-import com.thoughtworks.xstream.converters.UnmarshallingContext;
-import com.thoughtworks.xstream.io.HierarchicalStreamReader;
-import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
-
-/**
- * XStream converter for handling {@link ZonedDateTime} fields.
- */
-public class DateTimeConverter implements Converter {
-
-    @Override
-    public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) {
-        ZonedDateTime dateTime = (ZonedDateTime) o;
-        writer.setValue(DateTimeUtils.formatDateTime(dateTime));
-    }
-
-    @Override
-    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
-        try {
-            return DateTimeUtils.parseDateTime(reader.getValue());
-        } catch (Exception e) {
-            throw new ConversionException(
-                    String.format("Error reading ZonedDateTime from value %s: %s",
-                        reader.getValue(), e.getMessage()),
-                    e);
-        }
-    }
-
-    @Override
-    public boolean canConvert(Class aClass) {
-        return ZonedDateTime.class.isAssignableFrom(aClass);
-    }
-
-}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeHandling.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeHandling.java
new file mode 100644
index 0000000..6a262cf
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeHandling.java
@@ -0,0 +1,46 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+
+import static java.time.temporal.ChronoField.HOUR_OF_DAY;
+import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
+import static java.time.temporal.ChronoField.NANO_OF_SECOND;
+import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
+
+final class DateTimeHandling {
+
+    static final DateTimeFormatter ISO_OFFSET_DATE_TIME = new DateTimeFormatterBuilder()//
+        .parseCaseInsensitive()//
+        .append(DateTimeFormatter.ISO_LOCAL_DATE)//
+        .appendLiteral('T')//
+        .appendValue(HOUR_OF_DAY, 2)//
+        .appendLiteral(':')//
+        .appendValue(MINUTE_OF_HOUR, 2)//
+        .appendLiteral(':')//
+        .appendValue(SECOND_OF_MINUTE, 2)//
+        .optionalStart()//
+        .appendFraction(NANO_OF_SECOND, 3, 3, true)//
+        .optionalEnd()//
+        .appendOffset("+HHMM", "Z")//
+        .toFormatter();
+
+    private DateTimeHandling() {
+    }
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java
deleted file mode 100644
index 881da39..0000000
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * 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.component.salesforce.api.utils;
-
-import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.LocalTime;
-import java.time.OffsetTime;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.format.DateTimeParseException;
-import java.util.regex.Pattern;
-
-import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME;
-import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE;
-
-/**
- * Utility class for working with DateTime fields.
- */
-public abstract class DateTimeUtils {
-
-    private static final Pattern BAD_TZ_PATTERN = Pattern.compile("[+-][0-9]{4}+$");
-
-    private static final DateTimeFormatter ISO_8601_FORMATTER = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .appendPattern("yyyy-MM-dd")
-            .appendLiteral('T')
-            .appendPattern("HH:mm:ss[.SSS]")
-            .appendOffset("+HH:MM", "Z")
-            .toFormatter();
-
-    public static String formatDateTime(ZonedDateTime dateTime) throws DateTimeException {
-        return ISO_8601_FORMATTER.format(dateTime);
-    }
-
-    public static ZonedDateTime parseDateTime(String dateTimeStr) throws DateTimeParseException {
-        return ISO_8601_FORMATTER.parse(normalizeDateTime(dateTimeStr), ZonedDateTime::from);
-    }
-
-    private static String normalizeDateTime(String dateTimeAsString) {
-        if (BAD_TZ_PATTERN.matcher(dateTimeAsString).find()) {
-            int splitAt = dateTimeAsString.length() - 2;
-            dateTimeAsString = dateTimeAsString.substring(0, splitAt) + ":" + dateTimeAsString.substring(splitAt);
-        }
-        return dateTimeAsString;
-    }
-    
-    public static String formatDate(LocalDate date) {
-        return ISO_LOCAL_DATE.format(date);
-    }
-    
-    public static LocalDate parseDate(String date) {
-        return ISO_LOCAL_DATE.parse(date,LocalDate::from);
-    }
-        
-    public static String formatTime(OffsetTime time) {
-        // Sets the timezone as UTC for the time before sending to salesforce
-        return ISO_LOCAL_TIME.format(time.withOffsetSameInstant(ZoneOffset.UTC).toLocalTime());
-    }
-    
-    public static OffsetTime parseTime(String time) {
-        // Sets the timezone as UTC for the time which comes from salesforce
-        return OffsetTime.of(ISO_LOCAL_TIME.parse(time, LocalTime::from), ZoneOffset.UTC);
-    }
- 
-}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/InstantConverter.java
similarity index 50%
copy from components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java
copy to components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/InstantConverter.java
index fefa68b..6b859af 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/InstantConverter.java
@@ -16,33 +16,39 @@
  */
 package org.apache.camel.component.salesforce.api.utils;
 
-import java.io.IOException;
+import java.time.Instant;
+import java.time.ZoneId;
 import java.time.ZonedDateTime;
 
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonMappingException;
+import com.thoughtworks.xstream.converters.SingleValueConverter;
 
+import static org.apache.camel.component.salesforce.api.utils.DateTimeHandling.ISO_OFFSET_DATE_TIME;
 
-public class DateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {
+final class InstantConverter implements SingleValueConverter {
 
-    public DateTimeDeserializer() {
-        super();
+    static final SingleValueConverter INSTANCE = new InstantConverter();
+
+    private InstantConverter() {
     }
 
     @Override
-    public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
-        JsonToken currentToken = jsonParser.getCurrentToken();
-        if (currentToken == JsonToken.VALUE_STRING) {
-            return DateTimeUtils.parseDateTime(jsonParser.getText().trim());
-        }
-        throw JsonMappingException.from(deserializationContext, "Expected String value, got: " + currentToken);
+    public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) {
+        return Instant.class.equals(type);
+    }
+
+    @Override
+    public Object fromString(final String value) {
+        return ZonedDateTime.parse(value, ISO_OFFSET_DATE_TIME).toInstant();
     }
 
     @Override
-    public Class<?> handledType() {
-        return ZonedDateTime.class;
+    public String toString(final Object value) {
+        if (value == null) {
+            return null;
+        }
+
+        final Instant instant = (Instant) value;
+
+        return ISO_OFFSET_DATE_TIME.format(instant.atZone(ZoneId.systemDefault()));
     }
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateModule.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/InstantDeserializer.java
similarity index 59%
rename from components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateModule.java
rename to components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/InstantDeserializer.java
index 7a2d5ad..e4b7ff1 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateModule.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/InstantDeserializer.java
@@ -16,16 +16,20 @@
  */
 package org.apache.camel.component.salesforce.api.utils;
 
+import java.time.Instant;
 
-import java.time.LocalDate;
+import com.fasterxml.jackson.databind.JsonDeserializer;
 
-import com.fasterxml.jackson.databind.module.SimpleModule;
+import static org.apache.camel.component.salesforce.api.utils.DateTimeHandling.ISO_OFFSET_DATE_TIME;
 
-public class DateModule extends SimpleModule {
+final class InstantDeserializer extends com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer<Instant> {
 
-    public DateModule() {
-        super();
-        addSerializer(LocalDate.class, new DateSerializer());
-        addDeserializer(LocalDate.class, new DateDeserializer());
+    static final JsonDeserializer<Instant> INSTANCE = new InstantDeserializer();
+
+    private static final long serialVersionUID = 1L;
+
+    private InstantDeserializer() {
+        super(com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer.INSTANT, ISO_OFFSET_DATE_TIME);
     }
-}
\ No newline at end of file
+
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeSerializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/InstantSerializer.java
similarity index 57%
copy from components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeSerializer.java
copy to components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/InstantSerializer.java
index 26c8a39..75c628e 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeSerializer.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/InstantSerializer.java
@@ -17,34 +17,31 @@
 package org.apache.camel.component.salesforce.api.utils;
 
 import java.io.IOException;
+import java.time.Instant;
+import java.time.ZoneId;
 import java.time.ZonedDateTime;
 
 import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.JsonSerializer;
 import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
 
+final class InstantSerializer extends StdSerializer<Instant> {
 
-public class DateTimeSerializer extends JsonSerializer<ZonedDateTime> {
+    static final JsonSerializer<Instant> INSTANCE = new InstantSerializer();
 
-    public DateTimeSerializer() {
-        super();
-    }
+    private static final long serialVersionUID = 1L;
 
-    @Override
-    public void serialize(ZonedDateTime dateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-        jsonGenerator.writeString(DateTimeUtils.formatDateTime(dateTime));
+    private InstantSerializer() {
+        super(Instant.class);
     }
 
     @Override
-    public Class<ZonedDateTime> handledType() {
-        return ZonedDateTime.class;
-    }
+    public void serialize(final Instant value, final JsonGenerator gen, final SerializerProvider serializers)
+        throws IOException {
+        final ZonedDateTime zonedDateTime = value.atZone(ZoneId.systemDefault());
 
-    @Override
-    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException {
-        visitor.expectStringFormat(type);
+        serializers.defaultSerializeValue(zonedDateTime, gen);
     }
+
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/JsonUtils.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/JsonUtils.java
index 4fbe8765..f75c639 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/JsonUtils.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/JsonUtils.java
@@ -28,6 +28,7 @@ import static java.util.stream.Collectors.joining;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.BeanDescription;
+import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.JsonSerializer;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -76,8 +77,7 @@ public abstract class JsonUtils {
         // enable date time support including Java 1.8 ZonedDateTime
         ObjectMapper objectMapper = new ObjectMapper();
         objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
-        objectMapper.registerModule(new DateModule());
-        objectMapper.registerModule(new DateTimeModule());
+        objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
         objectMapper.registerModule(new TimeModule());
         return objectMapper;
     }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeSerializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/LocalDateTimeConverter.java
similarity index 50%
rename from components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeSerializer.java
rename to components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/LocalDateTimeConverter.java
index 26c8a39..0337669 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeSerializer.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/LocalDateTimeConverter.java
@@ -16,35 +16,39 @@
  */
 package org.apache.camel.component.salesforce.api.utils;
 
-import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.time.ZonedDateTime;
 
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.thoughtworks.xstream.converters.SingleValueConverter;
 
+import static org.apache.camel.component.salesforce.api.utils.DateTimeHandling.ISO_OFFSET_DATE_TIME;
 
-public class DateTimeSerializer extends JsonSerializer<ZonedDateTime> {
+final class LocalDateTimeConverter implements SingleValueConverter {
 
-    public DateTimeSerializer() {
-        super();
+    static final SingleValueConverter INSTANCE = new LocalDateTimeConverter();
+
+    private LocalDateTimeConverter() {
     }
 
     @Override
-    public void serialize(ZonedDateTime dateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-        jsonGenerator.writeString(DateTimeUtils.formatDateTime(dateTime));
+    public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) {
+        return LocalDateTime.class.equals(type);
     }
 
     @Override
-    public Class<ZonedDateTime> handledType() {
-        return ZonedDateTime.class;
+    public Object fromString(final String value) {
+        return ZonedDateTime.parse(value, ISO_OFFSET_DATE_TIME).toLocalDateTime();
     }
 
     @Override
-    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException {
-        visitor.expectStringFormat(type);
+    public String toString(final Object value) {
+        if (value == null) {
+            return null;
+        }
+
+        final LocalDateTime localDateTime = (LocalDateTime) value;
+
+        return ISO_OFFSET_DATE_TIME.format(localDateTime.atZone(ZoneId.systemDefault()));
     }
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/LocalDateTimeDeserializer.java
similarity index 59%
copy from components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java
copy to components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/LocalDateTimeDeserializer.java
index fefa68b..36825aa 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/LocalDateTimeDeserializer.java
@@ -17,32 +17,31 @@
 package org.apache.camel.component.salesforce.api.utils;
 
 import java.io.IOException;
+import java.time.LocalDateTime;
 import java.time.ZonedDateTime;
 
 import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.DeserializationContext;
 import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
 
+final class LocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
 
-public class DateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {
+    static final JsonDeserializer<LocalDateTime> INSTANCE = new LocalDateTimeDeserializer();
 
-    public DateTimeDeserializer() {
-        super();
-    }
+    private static final long serialVersionUID = 1L;
 
-    @Override
-    public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
-        JsonToken currentToken = jsonParser.getCurrentToken();
-        if (currentToken == JsonToken.VALUE_STRING) {
-            return DateTimeUtils.parseDateTime(jsonParser.getText().trim());
-        }
-        throw JsonMappingException.from(deserializationContext, "Expected String value, got: " + currentToken);
+    private LocalDateTimeDeserializer() {
+        super(LocalDateTime.class);
     }
 
     @Override
-    public Class<?> handledType() {
-        return ZonedDateTime.class;
+    public LocalDateTime deserialize(final JsonParser p, final DeserializationContext ctxt)
+        throws IOException, JsonProcessingException {
+        final ZonedDateTime zonedDateTime = ctxt.readValue(p, ZonedDateTime.class);
+
+        return zonedDateTime.toLocalDateTime();
     }
+
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeSerializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/LocalDateTimeSerializer.java
similarity index 56%
rename from components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeSerializer.java
rename to components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/LocalDateTimeSerializer.java
index f8d684a..586ce76 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeSerializer.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/LocalDateTimeSerializer.java
@@ -17,34 +17,33 @@
 package org.apache.camel.component.salesforce.api.utils;
 
 import java.io.IOException;
-import java.time.OffsetTime;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
 
 import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonSerializer;
 import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
 
+final class LocalDateTimeSerializer extends StdSerializer<LocalDateTime> {
 
-public class TimeSerializer extends JsonSerializer<OffsetTime> {
+    static final JsonSerializer<LocalDateTime> INSTANCE = new LocalDateTimeSerializer();
 
-    public TimeSerializer() {
-        super();
-    }
+    private static final long serialVersionUID = 1L;
 
-    @Override
-    public void serialize(OffsetTime time, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-        jsonGenerator.writeString(DateTimeUtils.formatTime(time));
+    private LocalDateTimeSerializer() {
+        super(LocalDateTime.class);
     }
 
     @Override
-    public Class<OffsetTime> handledType() {
-        return OffsetTime.class;
-    }
+    public void serialize(final LocalDateTime value, final JsonGenerator gen, final SerializerProvider serializers)
+        throws IOException, JsonProcessingException {
 
-    @Override
-    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException {
-        visitor.expectStringFormat(type);
+        final ZonedDateTime zonedDateTime = ZonedDateTime.of(value, ZoneId.systemDefault());
+
+        serializers.defaultSerializeValue(zonedDateTime, gen);
     }
+
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetDateTimeConverter.java
similarity index 50%
copy from components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java
copy to components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetDateTimeConverter.java
index fefa68b..8f19038 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetDateTimeConverter.java
@@ -16,33 +16,38 @@
  */
 package org.apache.camel.component.salesforce.api.utils;
 
-import java.io.IOException;
+import java.time.OffsetDateTime;
 import java.time.ZonedDateTime;
 
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonMappingException;
+import com.thoughtworks.xstream.converters.SingleValueConverter;
 
+import static org.apache.camel.component.salesforce.api.utils.DateTimeHandling.ISO_OFFSET_DATE_TIME;
 
-public class DateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {
+final class OffsetDateTimeConverter implements SingleValueConverter {
 
-    public DateTimeDeserializer() {
-        super();
+    static final SingleValueConverter INSTANCE = new OffsetDateTimeConverter();
+
+    private OffsetDateTimeConverter() {
     }
 
     @Override
-    public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
-        JsonToken currentToken = jsonParser.getCurrentToken();
-        if (currentToken == JsonToken.VALUE_STRING) {
-            return DateTimeUtils.parseDateTime(jsonParser.getText().trim());
-        }
-        throw JsonMappingException.from(deserializationContext, "Expected String value, got: " + currentToken);
+    public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) {
+        return OffsetDateTime.class.equals(type);
+    }
+
+    @Override
+    public Object fromString(final String value) {
+        return ZonedDateTime.parse(value, ISO_OFFSET_DATE_TIME).toOffsetDateTime();
     }
 
     @Override
-    public Class<?> handledType() {
-        return ZonedDateTime.class;
+    public String toString(final Object value) {
+        if (value == null) {
+            return null;
+        }
+
+        final OffsetDateTime offsetDateTime = (OffsetDateTime) value;
+
+        return ISO_OFFSET_DATE_TIME.format(offsetDateTime);
     }
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetDateTimeDeserializer.java
similarity index 58%
rename from components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateDeserializer.java
rename to components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetDateTimeDeserializer.java
index e39a695..f575cd3 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateDeserializer.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetDateTimeDeserializer.java
@@ -17,32 +17,27 @@
 package org.apache.camel.component.salesforce.api.utils;
 
 import java.io.IOException;
-import java.time.LocalDate;
+import java.time.OffsetDateTime;
+import java.time.ZonedDateTime;
 
 import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.DeserializationContext;
 import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonMappingException;
 
+final class OffsetDateTimeDeserializer extends JsonDeserializer<OffsetDateTime> {
 
-public class DateDeserializer extends JsonDeserializer<LocalDate> {
+    static final JsonDeserializer<OffsetDateTime> INSTANCE = new OffsetDateTimeDeserializer();
 
-    public DateDeserializer() {
-        super();
+    private OffsetDateTimeDeserializer() {
     }
 
     @Override
-    public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
-        JsonToken currentToken = jsonParser.getCurrentToken();
-        if (currentToken == JsonToken.VALUE_STRING) {
-            return DateTimeUtils.parseDate(jsonParser.getText().trim());
-        }
-        throw JsonMappingException.from(deserializationContext, "Expected String value, got: " + currentToken);
-    }
+    public OffsetDateTime deserialize(final JsonParser p, final DeserializationContext ctxt)
+        throws IOException, JsonProcessingException {
+        final ZonedDateTime zonedDateTime = ctxt.readValue(p, ZonedDateTime.class);
 
-    @Override
-    public Class<?> handledType() {
-        return LocalDate.class;
+        return zonedDateTime.toOffsetDateTime();
     }
+
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateSerializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetDateTimeSerializer.java
similarity index 57%
rename from components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateSerializer.java
rename to components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetDateTimeSerializer.java
index 4f21d6e..beddbcf 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateSerializer.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/OffsetDateTimeSerializer.java
@@ -17,34 +17,32 @@
 package org.apache.camel.component.salesforce.api.utils;
 
 import java.io.IOException;
-import java.time.LocalDate;
+import java.time.OffsetDateTime;
+import java.time.ZonedDateTime;
 
 import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonSerializer;
 import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
 
+final class OffsetDateTimeSerializer extends StdSerializer<OffsetDateTime> {
 
-public class DateSerializer extends JsonSerializer<LocalDate> {
+    static final JsonSerializer<OffsetDateTime> INSTANCE = new OffsetDateTimeSerializer();
 
-    public DateSerializer() {
-        super();
-    }
+    private static final long serialVersionUID = 1L;
 
-    @Override
-    public void serialize(LocalDate date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-        jsonGenerator.writeString(DateTimeUtils.formatDate(date));
+    private OffsetDateTimeSerializer() {
+        super(OffsetDateTime.class);
     }
 
     @Override
-    public Class<LocalDate> handledType() {
-        return LocalDate.class;
-    }
+    public void serialize(final OffsetDateTime value, final JsonGenerator gen, final SerializerProvider serializers)
+        throws IOException, JsonProcessingException {
 
-    @Override
-    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException {
-        visitor.expectStringFormat(type);
+        final ZonedDateTime zonedDateTime = value.toZonedDateTime();
+
+        serializers.defaultSerializeValue(zonedDateTime, gen);
     }
+
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeConverter.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeConverter.java
deleted file mode 100644
index 4f87b59..0000000
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeConverter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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.component.salesforce.api.utils;
-
-import java.time.OffsetTime;
-
-import com.thoughtworks.xstream.converters.ConversionException;
-import com.thoughtworks.xstream.converters.Converter;
-import com.thoughtworks.xstream.converters.MarshallingContext;
-import com.thoughtworks.xstream.converters.UnmarshallingContext;
-import com.thoughtworks.xstream.io.HierarchicalStreamReader;
-import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
-
-/**
- * XStream converter for handling {@link OffsetTime} fields.
- */
-public class TimeConverter implements Converter {
-
-    @Override
-    public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) {
-        OffsetTime time = (OffsetTime) o;
-        writer.setValue(DateTimeUtils.formatTime(time));
-    }
-
-    @Override
-    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
-        try {
-            return DateTimeUtils.parseTime(reader.getValue());
-        } catch (Exception e) {
-            throw new ConversionException(
-                    String.format("Error reading OffsetTime from value %s: %s",
-                        reader.getValue(), e.getMessage()),
-                    e);
-        }
-    }
-
-    @Override
-    public boolean canConvert(Class aClass) {
-        return OffsetTime.class.isAssignableFrom(aClass);
-    }
-
-}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeDeserializer.java
deleted file mode 100644
index 7363db4..0000000
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeDeserializer.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * 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.component.salesforce.api.utils;
-
-import java.io.IOException;
-import java.time.OffsetTime;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonMappingException;
-
-
-public class TimeDeserializer extends JsonDeserializer<OffsetTime> {
-
-    public TimeDeserializer() {
-        super();
-    }
-
-    @Override
-    public OffsetTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
-        JsonToken currentToken = jsonParser.getCurrentToken();
-        if (currentToken == JsonToken.VALUE_STRING) {
-            return DateTimeUtils.parseTime(jsonParser.getText().trim());
-        }
-        throw JsonMappingException.from(deserializationContext, "Expected String value, got: " + currentToken);
-    }
-
-    @Override
-    public Class<?> handledType() {
-        return OffsetTime.class;
-    }
-}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
index 3cfea55..bcad059 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
@@ -16,16 +16,57 @@
  */
 package org.apache.camel.component.salesforce.api.utils;
 
-
-import java.time.OffsetTime;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
 
 import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.ZonedDateTimeSerializer;
+
+import static org.apache.camel.component.salesforce.api.utils.DateTimeHandling.ISO_OFFSET_DATE_TIME;
 
 public class TimeModule extends SimpleModule {
 
+    private static final LocalDateDeserializer LOCAL_DATE_DESERIALIZER = new LocalDateDeserializer(
+        DateTimeFormatter.ISO_DATE);
+
+    private static final LocalDateSerializer LOCAL_DATE_SERIALIZER = new LocalDateSerializer(
+        DateTimeFormatter.ISO_DATE);
+
+    private static final long serialVersionUID = 1L;
+
+    private static final ZonedDateTimeSerializer ZONED_DATE_TIME_SERIALIZER = new ZonedDateTimeSerializer(
+        ISO_OFFSET_DATE_TIME);
+
+    private final JavaTimeModule delegate = new JavaTimeModule();
+
     public TimeModule() {
-        super();
-        addSerializer(OffsetTime.class, new TimeSerializer());
-        addDeserializer(OffsetTime.class, new TimeDeserializer());
+        addSerializer(LocalDate.class, LOCAL_DATE_SERIALIZER);
+        addDeserializer(LocalDate.class, LOCAL_DATE_DESERIALIZER);
+
+        addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE);
+        addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
+
+        addSerializer(OffsetDateTime.class, OffsetDateTimeSerializer.INSTANCE);
+        addDeserializer(OffsetDateTime.class, OffsetDateTimeDeserializer.INSTANCE);
+
+        addSerializer(ZonedDateTime.class, ZONED_DATE_TIME_SERIALIZER);
+        addDeserializer(ZonedDateTime.class, ZonedDateTimeDeserializer.INSTANCE);
+
+        addSerializer(Instant.class, InstantSerializer.INSTANCE);
+        addDeserializer(Instant.class, InstantDeserializer.INSTANCE);
     }
-}
\ No newline at end of file
+
+    @Override
+    public void setupModule(final SetupContext context) {
+        delegate.setupModule(context);
+        super.setupModule(context);
+    }
+
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/XStreamUtils.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/XStreamUtils.java
new file mode 100644
index 0000000..4ec04a8
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/XStreamUtils.java
@@ -0,0 +1,118 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.io.Writer;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.converters.basic.DateConverter;
+import com.thoughtworks.xstream.converters.reflection.FieldDictionary;
+import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
+import com.thoughtworks.xstream.core.TreeMarshallingStrategy;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.io.naming.NoNameCoder;
+import com.thoughtworks.xstream.io.xml.CompactWriter;
+import com.thoughtworks.xstream.io.xml.XppDriver;
+import com.thoughtworks.xstream.security.AnyTypePermission;
+import com.thoughtworks.xstream.security.ExplicitTypePermission;
+import com.thoughtworks.xstream.security.TypePermission;
+import com.thoughtworks.xstream.security.WildcardTypePermission;
+
+import org.apache.camel.component.salesforce.api.dto.AnnotationFieldKeySorter;
+import org.apache.camel.component.salesforce.internal.dto.RestChoices;
+import org.apache.camel.component.salesforce.internal.dto.RestErrors;
+
+public final class XStreamUtils {
+    private static final String PERMISSIONS_PROPERTY_DEFAULT = "java.lang.*,java.util.*";
+    private static final String PERMISSIONS_PROPERTY_KEY = "org.apache.camel.xstream.permissions";
+
+    private XStreamUtils() {
+    }
+
+    public static void addDefaultPermissions(final XStream xstream) {
+        addPermissions(xstream, System.getProperty(PERMISSIONS_PROPERTY_KEY, PERMISSIONS_PROPERTY_DEFAULT));
+    }
+
+    public static void addPermissions(final XStream xstream, final String permissions) {
+        for (String pterm : permissions.split(",")) {
+            boolean aod;
+            pterm = pterm.trim();
+            if (pterm.startsWith("-")) {
+                aod = false;
+                pterm = pterm.substring(1);
+            } else {
+                aod = true;
+                if (pterm.startsWith("+")) {
+                    pterm = pterm.substring(1);
+                }
+            }
+            TypePermission typePermission = null;
+            if ("*".equals(pterm)) {
+                // accept or deny any
+                typePermission = AnyTypePermission.ANY;
+            } else if (pterm.indexOf('*') < 0) {
+                // exact type
+                typePermission = new ExplicitTypePermission(new String[] {pterm});
+            } else if (pterm.length() > 0) {
+                // wildcard type
+                typePermission = new WildcardTypePermission(new String[] {pterm});
+            }
+            if (typePermission != null) {
+                if (aod) {
+                    xstream.addPermission(typePermission);
+                } else {
+                    xstream.denyPermission(typePermission);
+                }
+            }
+        }
+    }
+
+    public static XStream createXStream(final Class<?>... additionalTypes) {
+        final PureJavaReflectionProvider reflectionProvider = new PureJavaReflectionProvider(
+            new FieldDictionary(new AnnotationFieldKeySorter()));
+
+        // use NoNameCoder to avoid escaping __ in custom field names
+        // and CompactWriter to avoid pretty printing
+        final XppDriver hierarchicalStreamDriver = new XppDriver(new NoNameCoder()) {
+            @Override
+            public HierarchicalStreamWriter createWriter(final Writer out) {
+                return new CompactWriter(out, getNameCoder());
+            }
+
+        };
+
+        final XStream result = new XStream(reflectionProvider, hierarchicalStreamDriver);
+        result.aliasSystemAttribute(null, "class");
+        result.ignoreUnknownElements();
+        XStreamUtils.addDefaultPermissions(result);
+
+        result.registerConverter(new DateConverter("yyyy-MM-dd'T'HH:mm:ss.SSSZ", null), XStream.PRIORITY_VERY_HIGH);
+        result.registerConverter(LocalDateTimeConverter.INSTANCE, XStream.PRIORITY_VERY_HIGH);
+        result.registerConverter(OffsetDateTimeConverter.INSTANCE, XStream.PRIORITY_VERY_HIGH);
+        result.registerConverter(ZonedDateTimeConverter.INSTANCE, XStream.PRIORITY_VERY_HIGH);
+        result.registerConverter(InstantConverter.INSTANCE, XStream.PRIORITY_VERY_HIGH);
+
+        result.setMarshallingStrategy(new TreeMarshallingStrategy());
+
+        result.processAnnotations(RestErrors.class);
+        result.processAnnotations(RestChoices.class);
+        result.processAnnotations(additionalTypes);
+
+        return result;
+    }
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/ZonedDateTimeConverter.java
similarity index 50%
rename from components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java
rename to components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/ZonedDateTimeConverter.java
index fefa68b..9b00973 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeDeserializer.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/ZonedDateTimeConverter.java
@@ -16,33 +16,38 @@
  */
 package org.apache.camel.component.salesforce.api.utils;
 
-import java.io.IOException;
 import java.time.ZonedDateTime;
 
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonMappingException;
+import com.thoughtworks.xstream.converters.SingleValueConverter;
 
+import static org.apache.camel.component.salesforce.api.utils.DateTimeHandling.ISO_OFFSET_DATE_TIME;
 
-public class DateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {
+final class ZonedDateTimeConverter implements SingleValueConverter {
 
-    public DateTimeDeserializer() {
-        super();
+    static final SingleValueConverter INSTANCE = new ZonedDateTimeConverter();
+
+    private ZonedDateTimeConverter() {
     }
 
     @Override
-    public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
-        JsonToken currentToken = jsonParser.getCurrentToken();
-        if (currentToken == JsonToken.VALUE_STRING) {
-            return DateTimeUtils.parseDateTime(jsonParser.getText().trim());
-        }
-        throw JsonMappingException.from(deserializationContext, "Expected String value, got: " + currentToken);
+    public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) {
+        return ZonedDateTime.class.equals(type);
     }
 
     @Override
-    public Class<?> handledType() {
-        return ZonedDateTime.class;
+    public Object fromString(final String value) {
+        return ZonedDateTime.parse(value, ISO_OFFSET_DATE_TIME);
     }
+
+    @Override
+    public String toString(final Object value) {
+        if (value == null) {
+            return null;
+        }
+
+        final ZonedDateTime zonedDateTime = (ZonedDateTime) value;
+
+        return ISO_OFFSET_DATE_TIME.format(zonedDateTime);
+    }
+
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeModule.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/ZonedDateTimeDeserializer.java
similarity index 60%
rename from components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeModule.java
rename to components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/ZonedDateTimeDeserializer.java
index 665a6d8..2748c9c 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeModule.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/ZonedDateTimeDeserializer.java
@@ -16,16 +16,21 @@
  */
 package org.apache.camel.component.salesforce.api.utils;
 
-
 import java.time.ZonedDateTime;
 
-import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer;
+
+import static org.apache.camel.component.salesforce.api.utils.DateTimeHandling.ISO_OFFSET_DATE_TIME;
+
+final class ZonedDateTimeDeserializer extends InstantDeserializer<ZonedDateTime> {
 
-public class DateTimeModule extends SimpleModule {
+    static final JsonDeserializer<ZonedDateTime> INSTANCE = new ZonedDateTimeDeserializer();
 
-    public DateTimeModule() {
-        super();
-        addSerializer(ZonedDateTime.class, new DateTimeSerializer());
-        addDeserializer(ZonedDateTime.class, new DateTimeDeserializer());
+    private static final long serialVersionUID = 1L;
+
+    private ZonedDateTimeDeserializer() {
+        super(InstantDeserializer.ZONED_DATE_TIME, ISO_OFFSET_DATE_TIME);
     }
-}
\ No newline at end of file
+
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java
index bc682d3..1777f0c 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java
@@ -20,7 +20,6 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.Writer;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -32,19 +31,11 @@ import com.fasterxml.jackson.databind.ObjectReader;
 import com.fasterxml.jackson.databind.ObjectWriter;
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.XStreamException;
-import com.thoughtworks.xstream.converters.reflection.FieldDictionary;
-import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
-import com.thoughtworks.xstream.core.TreeMarshallingStrategy;
-import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
-import com.thoughtworks.xstream.io.naming.NoNameCoder;
-import com.thoughtworks.xstream.io.xml.CompactWriter;
-import com.thoughtworks.xstream.io.xml.XppDriver;
 
 import org.apache.camel.component.salesforce.SalesforceEndpointConfig;
 import org.apache.camel.component.salesforce.SalesforceHttpClient;
 import org.apache.camel.component.salesforce.api.NoSuchSObjectException;
 import org.apache.camel.component.salesforce.api.SalesforceException;
-import org.apache.camel.component.salesforce.api.dto.AnnotationFieldKeySorter;
 import org.apache.camel.component.salesforce.api.dto.RestError;
 import org.apache.camel.component.salesforce.api.dto.composite.SObjectBatch;
 import org.apache.camel.component.salesforce.api.dto.composite.SObjectBatchResponse;
@@ -52,11 +43,9 @@ import org.apache.camel.component.salesforce.api.dto.composite.SObjectComposite;
 import org.apache.camel.component.salesforce.api.dto.composite.SObjectCompositeResponse;
 import org.apache.camel.component.salesforce.api.dto.composite.SObjectTree;
 import org.apache.camel.component.salesforce.api.dto.composite.SObjectTreeResponse;
-import org.apache.camel.component.salesforce.api.utils.DateConverter;
-import org.apache.camel.component.salesforce.api.utils.DateTimeConverter;
-import org.apache.camel.component.salesforce.api.utils.TimeConverter;
 import org.apache.camel.component.salesforce.api.utils.JsonUtils;
 import org.apache.camel.component.salesforce.api.utils.Version;
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.apache.camel.component.salesforce.internal.PayloadFormat;
 import org.apache.camel.component.salesforce.internal.SalesforceSession;
 import org.apache.camel.util.IOHelper;
@@ -103,10 +92,11 @@ public class DefaultCompositeApiClient extends AbstractClientBase implements Com
             mapper = JsonUtils.createObjectMapper();
         }
 
-        xStreamCompositeBatch = configureXStream(SObjectBatch.class, SObjectBatchResponse.class);
+        xStreamCompositeBatch = XStreamUtils.createXStream(SObjectBatch.class, SObjectBatchResponse.class);
 
-        xStreamCompositeTree = configureXStream(SObjectTree.class, SObjectTreeResponse.class);
-        // newer Salesforce API versions return `<SObjectTreeResponse>` element, older versions
+        xStreamCompositeTree = XStreamUtils.createXStream(SObjectTree.class, SObjectTreeResponse.class);
+        // newer Salesforce API versions return `<SObjectTreeResponse>` element,
+        // older versions
         // return `<Result>` element
         xStreamCompositeTree.alias("SObjectTreeResponse", SObjectTreeResponse.class);
     }
@@ -124,10 +114,8 @@ public class DefaultCompositeApiClient extends AbstractClientBase implements Com
         final ContentProvider content = serialize(NO_XSTREAM, composite, composite.objectTypes());
         post.content(content);
 
-        doHttpRequest(post,
-            (response, responseHeaders, exception) -> callback.onResponse(
-                tryToReadResponse(NO_XSTREAM, SObjectCompositeResponse.class, response), responseHeaders,
-                exception));
+        doHttpRequest(post, (response, responseHeaders, exception) -> callback.onResponse(
+            tryToReadResponse(NO_XSTREAM, SObjectCompositeResponse.class, response), responseHeaders, exception));
     }
 
     @Override
@@ -293,31 +281,6 @@ public class DefaultCompositeApiClient extends AbstractClientBase implements Com
         }
     }
 
-    static XStream configureXStream(final Class<?>... additionalTypes) {
-        final PureJavaReflectionProvider reflectionProvider = new PureJavaReflectionProvider(
-            new FieldDictionary(new AnnotationFieldKeySorter()));
-
-        final XppDriver hierarchicalStreamDriver = new XppDriver(new NoNameCoder()) {
-            @Override
-            public HierarchicalStreamWriter createWriter(final Writer out) {
-                return new CompactWriter(out, getNameCoder());
-            }
-
-        };
-
-        final XStream xStream = new XStream(reflectionProvider, hierarchicalStreamDriver);
-        xStream.aliasSystemAttribute(null, "class");
-        xStream.ignoreUnknownElements();
-        XStreamUtils.addDefaultPermissions(xStream);
-        xStream.registerConverter(new DateConverter());
-        xStream.registerConverter(new DateTimeConverter());
-        xStream.registerConverter(new TimeConverter());
-        xStream.setMarshallingStrategy(new TreeMarshallingStrategy());
-        xStream.processAnnotations(additionalTypes);
-
-        return xStream;
-    }
-
     static <T> T fromXml(final XStream xstream, final InputStream responseStream) {
         @SuppressWarnings("unchecked")
         final T read = (T) xstream.fromXML(responseStream);
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java
index f21a523..8bb1aea 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java
@@ -36,10 +36,10 @@ import org.apache.camel.component.salesforce.api.SalesforceMultipleChoicesExcept
 import org.apache.camel.component.salesforce.api.TypeReferences;
 import org.apache.camel.component.salesforce.api.dto.RestError;
 import org.apache.camel.component.salesforce.api.utils.JsonUtils;
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.apache.camel.component.salesforce.internal.PayloadFormat;
 import org.apache.camel.component.salesforce.internal.SalesforceSession;
 import org.apache.camel.component.salesforce.internal.dto.RestChoices;
-import org.apache.camel.component.salesforce.internal.dto.RestErrors;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.URISupport;
 import org.eclipse.jetty.client.api.Request;
@@ -69,12 +69,7 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
 
         // initialize error parsers for JSON and XML
         this.objectMapper = JsonUtils.createObjectMapper();
-        this.xStream = new XStream();
-        xStream.processAnnotations(RestErrors.class);
-        xStream.processAnnotations(RestChoices.class);
-
-        xStream.ignoreUnknownElements();
-        XStreamUtils.addDefaultPermissions(xStream);
+        this.xStream = XStreamUtils.createXStream();
     }
 
     @Override
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/XStreamUtils.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/XStreamUtils.java
deleted file mode 100644
index 43c66ad..0000000
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/XStreamUtils.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * 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.component.salesforce.internal.client;
-
-import com.thoughtworks.xstream.XStream;
-import com.thoughtworks.xstream.security.AnyTypePermission;
-import com.thoughtworks.xstream.security.ExplicitTypePermission;
-import com.thoughtworks.xstream.security.TypePermission;
-import com.thoughtworks.xstream.security.WildcardTypePermission;
-
-/**
- * REVISIT this code is duplicated from camel-xstream and we should
- * find another way...
- */
-public final class XStreamUtils {
-    private static final String PERMISSIONS_PROPERTY_KEY = "org.apache.camel.xstream.permissions";
-    private static final String PERMISSIONS_PROPERTY_DEFAULT = "java.lang.*,java.util.*";
-
-    private XStreamUtils() {
-    }
-
-    public static void addPermissions(XStream xstream, String permissions) {
-        for (String pterm : permissions.split(",")) {
-            boolean aod;
-            pterm = pterm.trim();
-            if (pterm.startsWith("-")) {
-                aod = false;
-                pterm = pterm.substring(1);
-            } else {
-                aod = true;
-                if (pterm.startsWith("+")) {
-                    pterm = pterm.substring(1);
-                }
-            }
-            TypePermission typePermission = null;
-            if ("*".equals(pterm)) {
-                // accept or deny any
-                typePermission = AnyTypePermission.ANY;
-            } else if (pterm.indexOf('*') < 0) {
-                // exact type
-                typePermission = new ExplicitTypePermission(new String[]{pterm});
-            } else if (pterm.length() > 0) {
-                // wildcard type
-                typePermission = new WildcardTypePermission(new String[]{pterm});
-            }
-            if (typePermission != null) {
-                if (aod) {
-                    xstream.addPermission(typePermission);
-                } else {
-                    xstream.denyPermission(typePermission);
-                }
-            }
-        }
-    }
-
-    public static void addDefaultPermissions(XStream xstream) {
-        addPermissions(xstream, System.getProperty(PERMISSIONS_PROPERTY_KEY, PERMISSIONS_PROPERTY_DEFAULT));
-    }
-}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java
index 14919f3..2a33d23 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java
@@ -22,16 +22,10 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
-import java.io.Writer;
 import java.util.Map;
 
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.XStreamException;
-import com.thoughtworks.xstream.core.TreeMarshallingStrategy;
-import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
-import com.thoughtworks.xstream.io.naming.NoNameCoder;
-import com.thoughtworks.xstream.io.xml.CompactWriter;
-import com.thoughtworks.xstream.io.xml.XppDriver;
 import com.thoughtworks.xstream.mapper.CachingMapper;
 import com.thoughtworks.xstream.mapper.CannotResolveClassException;
 
@@ -49,8 +43,7 @@ import org.apache.camel.component.salesforce.api.dto.SObjectDescription;
 import org.apache.camel.component.salesforce.api.dto.SearchResults;
 import org.apache.camel.component.salesforce.api.dto.Versions;
 import org.apache.camel.component.salesforce.api.dto.approval.ApprovalResult;
-import org.apache.camel.component.salesforce.api.utils.DateTimeConverter;
-import org.apache.camel.component.salesforce.internal.client.XStreamUtils;
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.eclipse.jetty.util.StringUtil;
 
 import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_NAME;
@@ -65,20 +58,7 @@ public class XmlRestProcessor extends AbstractRestProcessor {
         new ThreadLocal<XStream>() {
             @Override
             protected XStream initialValue() {
-                // use NoNameCoder to avoid escaping __ in custom field names
-                // and CompactWriter to avoid pretty printing
-                XStream result = new XStream(new XppDriver(new NoNameCoder()) {
-                    @Override
-                    public HierarchicalStreamWriter createWriter(Writer out) {
-                        return new CompactWriter(out, getNameCoder());
-                    }
-
-                });
-                result.ignoreUnknownElements();
-                XStreamUtils.addDefaultPermissions(result);
-                result.registerConverter(new DateTimeConverter());
-                result.setMarshallingStrategy(new TreeMarshallingStrategy());
-                return result;
+                return XStreamUtils.createXStream();
             }
         };
 
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistXmlTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistXmlTest.java
index 1dec3fd..01e46b3 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistXmlTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistXmlTest.java
@@ -18,8 +18,8 @@ package org.apache.camel.component.salesforce.api;
 
 import com.thoughtworks.xstream.XStream;
 
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.apache.camel.component.salesforce.dto.generated.MSPTest;
-import org.junit.BeforeClass;
 import org.junit.Test;
 
 import static org.junit.Assert.assertArrayEquals;
@@ -28,19 +28,11 @@ import static org.junit.Assert.assertNull;
 
 public class MultiSelectPicklistXmlTest {
 
-    private static final String TEST_XML = "<MSPTest>\n"
-        + "  <MspField>Value1;Value2;Value3</MspField>\n"
-        + "</MSPTest>";
     private static final String TEST_NULL_XML = "<MSPTest/>";
 
-    private static XStream xStream = new XStream();
-
-    @BeforeClass
-    public static void beforeClass() throws Exception {
-        xStream = new XStream();
-        xStream.processAnnotations(MSPTest.class);
-    }
+    private static final String TEST_XML = "<MSPTest><MspField>Value1;Value2;Value3</MspField></MSPTest>";
 
+    private static XStream xStream = XStreamUtils.createXStream(MSPTest.class);
 
     @Test
     public void testMarshal() throws Exception {
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/LimitsTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/LimitsTest.java
index 7879b3c..b5f5a84 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/LimitsTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/LimitsTest.java
@@ -31,6 +31,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
 import org.apache.camel.component.salesforce.api.dto.Limits.Usage;
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
 import org.junit.Test;
 
 import static org.hamcrest.CoreMatchers.is;
@@ -49,10 +50,10 @@ public class LimitsTest {
 
     @Test
     public void shouldDeserializeFromSalesforceGeneratedJSON() throws JsonProcessingException, IOException {
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final Object read = mapper.readerFor(Limits.class)
-                .readValue(LimitsTest.class.getResource("/org/apache/camel/component/salesforce/api/dto/limits.json"));
+            .readValue(LimitsTest.class.getResource("/org/apache/camel/component/salesforce/api/dto/limits.json"));
 
         assertThat("Limits should be parsed from JSON", read, instanceOf(Limits.class));
 
@@ -61,31 +62,32 @@ public class LimitsTest {
         final Usage dailyApiRequests = limits.getDailyApiRequests();
         assertFalse("Should have some usage present", dailyApiRequests.isUnknown());
         assertFalse("Per application usage should be present", dailyApiRequests.getPerApplicationUsage().isEmpty());
-        assertNotNull("'Camel Salesman' application usage should be present", dailyApiRequests.forApplication("Camel Salesman"));
-    }
-
-    @Test
-    public void usageShouldBeUnknownIfUnknown() {
-        assertTrue("Unknown usage must declare itself as such", Usage.UNKNOWN.isUnknown());
+        assertNotNull("'Camel Salesman' application usage should be present",
+            dailyApiRequests.forApplication("Camel Salesman"));
     }
 
     @Test
     public void shouldSupportGettingAllDefinedUsages() throws IntrospectionException {
-        BeanInfo beanInfo = Introspector.getBeanInfo(Limits.class);
+        final BeanInfo beanInfo = Introspector.getBeanInfo(Limits.class);
 
-        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+        final PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
 
-        Set<String> found = new HashSet<>();
-        for (PropertyDescriptor descriptor : propertyDescriptors) {
+        final Set<String> found = new HashSet<>();
+        for (final PropertyDescriptor descriptor : propertyDescriptors) {
             found.add(descriptor.getName());
         }
 
-        Set<String> defined = Arrays.stream(Limits.Operation.values()).map(Limits.Operation::name)
-                .map(Introspector::decapitalize).collect(Collectors.toSet());
+        final Set<String> defined = Arrays.stream(Limits.Operation.values()).map(Limits.Operation::name)
+            .map(Introspector::decapitalize).collect(Collectors.toSet());
 
         defined.removeAll(found);
 
         assertThat("All operations declared in Operation enum should have it's corresponding getter", defined,
-                is(Collections.emptySet()));
+            is(Collections.emptySet()));
+    }
+
+    @Test
+    public void usageShouldBeUnknownIfUnknown() {
+        assertTrue("Unknown usage must declare itself as such", Usage.UNKNOWN.isUnknown());
     }
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/RecentItemTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/RecentItemTest.java
index 3fc16ee..9a2c77d 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/RecentItemTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/RecentItemTest.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
 import org.junit.Test;
 
 import static org.hamcrest.core.IsInstanceOf.instanceOf;
@@ -32,22 +33,22 @@ public class RecentItemTest {
 
     @Test
     public void shouldDeserializeFromJSON() throws JsonProcessingException, IOException {
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final Object read = mapper.readerFor(RecentItem.class)
-                .readValue("{ \n" + //
-                        "    \"attributes\" : \n" + //
-                        "    { \n" + //
-                        "        \"type\" : \"Account\", \n" + //
-                        "        \"url\" : \"/services/data/v28.0/sobjects/Account/a06U000000CelH0IAJ\" \n" + //
-                        "    }, \n" + //
-                        "    \"Id\" : \"a06U000000CelH0IAJ\", \n" + //
-                        "    \"Name\" : \"Acme\" \n" + //
-                        "}");
+            .readValue("{ \n" + //
+                "    \"attributes\" : \n" + //
+                "    { \n" + //
+                "        \"type\" : \"Account\", \n" + //
+                "        \"url\" : \"/services/data/v28.0/sobjects/Account/a06U000000CelH0IAJ\" \n" + //
+                "    }, \n" + //
+                "    \"Id\" : \"a06U000000CelH0IAJ\", \n" + //
+                "    \"Name\" : \"Acme\" \n" + //
+                "}");
 
         assertThat("RecentItem should deserialize from JSON", read, instanceOf(RecentItem.class));
 
-        RecentItem recentItem = (RecentItem) read;
+        final RecentItem recentItem = (RecentItem) read;
 
         assertEquals("RecentItem.Id should be deserialized", recentItem.getId(), "a06U000000CelH0IAJ");
 
@@ -56,10 +57,10 @@ public class RecentItemTest {
         assertNotNull("RecentItem.attributes should be deserialized", recentItem.getAttributes());
 
         assertEquals("RecentItem.attributes.type should be deserialized", recentItem.getAttributes().getType(),
-                "Account");
+            "Account");
 
         assertEquals("RecentItem.attributes.url should be deserialized", recentItem.getAttributes().getUrl(),
-                "/services/data/v28.0/sobjects/Account/a06U000000CelH0IAJ");
+            "/services/data/v28.0/sobjects/Account/a06U000000CelH0IAJ");
 
     }
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/RestErrorTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/RestErrorTest.java
index a2fc0c4..484cfeb 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/RestErrorTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/RestErrorTest.java
@@ -22,6 +22,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectReader;
 import com.thoughtworks.xstream.XStream;
 
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -32,22 +34,21 @@ public class RestErrorTest {
 
     @Test
     public void shouldDeserializeFromJson() throws Exception {
-        final ObjectMapper objectMapper = new ObjectMapper();
+        final ObjectMapper objectMapper = JsonUtils.createObjectMapper();
         final ObjectReader reader = objectMapper.readerFor(RestError.class);
 
-        final RestError gotWithErrorCode = reader.<RestError> readValue(
+        final RestError gotWithErrorCode = reader.<RestError>readValue(
             "{\"errorCode\":\"errorCode\",\"message\":\"message\",\"fields\":[ \"field1\",\"field2\" ]}");
         assertEquals(gotWithErrorCode, error);
 
-        final RestError gotWithStatusCode = reader.<RestError> readValue(
+        final RestError gotWithStatusCode = reader.<RestError>readValue(
             "{\"statusCode\":\"errorCode\",\"message\":\"message\",\"fields\":[ \"field1\",\"field2\" ]}");
         assertEquals(gotWithStatusCode, error);
     }
 
     @Test
     public void shouldDeserializeFromXml() {
-        final XStream xStream = new XStream();
-        xStream.processAnnotations(RestError.class);
+        final XStream xStream = XStreamUtils.createXStream(RestError.class);
         xStream.alias("errors", RestError.class);
 
         final RestError gotWithErrorCode = (RestError) xStream.fromXML(
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalRequestTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalRequestTest.java
index b331952..ddc7d7b 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalRequestTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalRequestTest.java
@@ -23,6 +23,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.thoughtworks.xstream.XStream;
 
 import org.apache.camel.component.salesforce.api.dto.approval.ApprovalRequest.Action;
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.junit.Test;
 
 import static org.hamcrest.CoreMatchers.sameInstance;
@@ -63,46 +65,45 @@ public class ApprovalRequestTest {
         final ApprovalRequest combined = request.applyTemplate(template);
 
         assertThat("Combined approval request should be a new instance", combined,
-                both(not(sameInstance(request))).and(not(sameInstance(template))));
+            both(not(sameInstance(request))).and(not(sameInstance(template))));
 
         assertEquals("Action type should not be overwriten", request.getActionType(), combined.getActionType());
         assertEquals("Comment should not be overwriten", request.getComments(), combined.getComments());
         assertEquals("Context id should not be overwriten", request.getContextId(), combined.getContextId());
         assertEquals("Next approver id should be taken from template", template.getNextApproverIds(),
-                combined.getNextApproverIds());
+            combined.getNextApproverIds());
     }
 
     @Test
     public void shouldSerializeAsJson() throws JsonProcessingException {
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final String json = mapper.writerFor(ApprovalRequest.class).writeValueAsString(sampleRequest);
 
         assertEquals("ApprovalRequest should serialize as JSON from Salesforce examples",
-                "{\"actionType\":\"Submit\",\"contextActorId\":\"005D00000015rZy\",\"contextId\":\"001D000000I8mIm\""
-                    + ",\"comments\":\"this is a test\",\"nextApproverIds\":[\"005D00000015rY9\"],"
-                    + "\"processDefinitionNameOrId\":\"PTO_Request_Process\",\"skipEntryCriteria\":true}",
-                json);
+            "{\"actionType\":\"Submit\",\"contextActorId\":\"005D00000015rZy\",\"contextId\":\"001D000000I8mIm\""
+                + ",\"comments\":\"this is a test\",\"nextApproverIds\":[\"005D00000015rY9\"],"
+                + "\"processDefinitionNameOrId\":\"PTO_Request_Process\",\"skipEntryCriteria\":true}",
+            json);
     }
 
     @Test
     public void shouldSerializeAsXml() {
-        final XStream xStream = new XStream();
-        xStream.processAnnotations(ApprovalRequest.class);
+        final XStream xStream = XStreamUtils.createXStream(ApprovalRequest.class);
 
         final String xml = xStream.toXML(sampleRequest);
 
         assertEquals("ApprovalRequest should serialize as XML",
-                "<requests>\n"//
-                    + "  <actionType>Submit</actionType>\n"//
-                    + "  <contextActorId>005D00000015rZy</contextActorId>\n"//
-                    + "  <contextId>001D000000I8mIm</contextId>\n"//
-                    + "  <comments>this is a test</comments>\n"//
-                    + "  <nextApproverIds>005D00000015rY9</nextApproverIds>\n"//
-                    + "  <processDefinitionNameOrId>PTO_Request_Process</processDefinitionNameOrId>\n"//
-                    + "  <skipEntryCriteria>true</skipEntryCriteria>\n"//
-                    + "</requests>",
-                xml);
+            "<requests>"//
+                + "<actionType>Submit</actionType>"//
+                + "<contextActorId>005D00000015rZy</contextActorId>"//
+                + "<contextId>001D000000I8mIm</contextId>"//
+                + "<comments>this is a test</comments>"//
+                + "<nextApproverIds>005D00000015rY9</nextApproverIds>"//
+                + "<processDefinitionNameOrId>PTO_Request_Process</processDefinitionNameOrId>"//
+                + "<skipEntryCriteria>true</skipEntryCriteria>"//
+                + "</requests>",
+            xml);
     }
 
     @Test
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalRequestsTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalRequestsTest.java
index a63959b..c0547801 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalRequestsTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalRequestsTest.java
@@ -16,20 +16,15 @@
  */
 package org.apache.camel.component.salesforce.api.dto.approval;
 
-import java.io.Writer;
 import java.util.Arrays;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.thoughtworks.xstream.XStream;
-import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
-import com.thoughtworks.xstream.io.naming.NoNameCoder;
-import com.thoughtworks.xstream.io.xml.CompactWriter;
-import com.thoughtworks.xstream.io.xml.XppDriver;
 
 import org.apache.camel.component.salesforce.api.dto.approval.ApprovalRequest.Action;
-import org.apache.camel.component.salesforce.api.utils.DateTimeConverter;
-import org.apache.camel.component.salesforce.internal.client.XStreamUtils;
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -84,7 +79,7 @@ public class ApprovalRequestsTest {
             + "}"//
             + "]}";
 
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final String serialized = mapper.writerFor(ApprovalRequests.class).writeValueAsString(requests);
 
@@ -114,17 +109,7 @@ public class ApprovalRequestsTest {
             + "</requests>"//
             + "</ProcessApprovalRequest>";
 
-        final XStream xStream = new XStream(new XppDriver(new NoNameCoder()) {
-            @Override
-            public HierarchicalStreamWriter createWriter(final Writer out) {
-                return new CompactWriter(out, getNameCoder());
-            }
-
-        });
-        xStream.ignoreUnknownElements();
-        XStreamUtils.addDefaultPermissions(xStream);
-        xStream.registerConverter(new DateTimeConverter());
-        xStream.processAnnotations(ApprovalRequests.class);
+        final XStream xStream = XStreamUtils.createXStream(ApprovalRequests.class);
 
         final String serialized = xStream.toXML(requests);
 
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalResultTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalResultTest.java
index a1d315e..0d2e595 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalResultTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalResultTest.java
@@ -24,6 +24,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.thoughtworks.xstream.XStream;
 
 import org.apache.camel.component.salesforce.api.dto.approval.ApprovalResult.Result;
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.junit.Test;
 
 import static org.hamcrest.core.IsCollectionContaining.hasItems;
@@ -34,22 +36,6 @@ import static org.junit.Assert.assertTrue;
 
 public class ApprovalResultTest {
 
-    private static void assertResponseReadCorrectly(final ApprovalResult results) {
-        final Iterator<Result> resultsIterator = results.iterator();
-        assertTrue("Should deserialize one approval result result", resultsIterator.hasNext());
-
-        final ApprovalResult.Result result = resultsIterator.next();
-
-        assertThat("Should deserialize actorIds", result.getActorIds(), hasItems("0050Y000000u5NOQAY"));
-        assertEquals("Should deserialize entityId", "0010Y000005BYrZQAW", result.getEntityId());
-        assertEquals("Should deserialize instanceId", "04g0Y000000PL53QAG", result.getInstanceId());
-        assertEquals("Should deserialize instanceStatus", "Pending", result.getInstanceStatus());
-        assertThat("Should deserialize newWorkitemIds", result.getNewWorkitemIds(), hasItems("04i0Y000000L0fkQAC"));
-        assertTrue("Should deserialize success", result.isSuccess());
-
-        assertFalse("Should be no more results", resultsIterator.hasNext());
-    }
-
     @Test
     public void shouldDeserializeFromJson() throws JsonProcessingException, IOException {
         final String json = "["//
@@ -64,7 +50,7 @@ public class ApprovalResultTest {
             + "}"//
             + "]";
 
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final ApprovalResult results = mapper.readerFor(ApprovalResult.class).readValue(json);
 
@@ -75,8 +61,7 @@ public class ApprovalResultTest {
     public void shouldDeserializeFromXml() throws InstantiationException, IllegalAccessException {
         final ApprovalResult results = new ApprovalResult();
 
-        final XStream xStream = new XStream();
-        xStream.processAnnotations(ApprovalResult.class);
+        final XStream xStream = XStreamUtils.createXStream(ApprovalResult.class);
 
         xStream.fromXML("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"//
             + "<ProcessApprovalResult>"//
@@ -92,4 +77,20 @@ public class ApprovalResultTest {
 
         assertResponseReadCorrectly(results);
     }
+
+    private static void assertResponseReadCorrectly(final ApprovalResult results) {
+        final Iterator<Result> resultsIterator = results.iterator();
+        assertTrue("Should deserialize one approval result result", resultsIterator.hasNext());
+
+        final ApprovalResult.Result result = resultsIterator.next();
+
+        assertThat("Should deserialize actorIds", result.getActorIds(), hasItems("0050Y000000u5NOQAY"));
+        assertEquals("Should deserialize entityId", "0010Y000005BYrZQAW", result.getEntityId());
+        assertEquals("Should deserialize instanceId", "04g0Y000000PL53QAG", result.getInstanceId());
+        assertEquals("Should deserialize instanceStatus", "Pending", result.getInstanceStatus());
+        assertThat("Should deserialize newWorkitemIds", result.getNewWorkitemIds(), hasItems("04i0Y000000L0fkQAC"));
+        assertTrue("Should deserialize success", result.isSuccess());
+
+        assertFalse("Should be no more results", resultsIterator.hasNext());
+    }
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalsTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalsTest.java
index 0943983..de95989 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalsTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/approval/ApprovalsTest.java
@@ -24,6 +24,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
 import org.apache.camel.component.salesforce.api.dto.approval.Approvals.Info;
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
 import org.junit.Test;
 
 import static org.hamcrest.core.IsInstanceOf.instanceOf;
@@ -36,20 +37,20 @@ public class ApprovalsTest {
 
     @Test
     public void shouldDeserialize() throws JsonProcessingException, IOException {
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final Object read = mapper.readerFor(Approvals.class)
-                .readValue("{\n" + //
-                    "  \"approvals\" : {\n" + //
-                    "   \"Account\" : [ {\n" + //
-                    "     \"description\" : null,\n" + //
-                    "     \"id\" : \"04aD00000008Py9\",\n" + //
-                    "     \"name\" : \"Account Approval Process\",\n" + //
-                    "     \"object\" : \"Account\",\n" + //
-                    "     \"sortOrder\" : 1\n" + //
-                    "   } ]\n" + //
-                    "  }\n" + //
-                    "}");
+            .readValue("{\n" + //
+                "  \"approvals\" : {\n" + //
+                "   \"Account\" : [ {\n" + //
+                "     \"description\" : null,\n" + //
+                "     \"id\" : \"04aD00000008Py9\",\n" + //
+                "     \"name\" : \"Account Approval Process\",\n" + //
+                "     \"object\" : \"Account\",\n" + //
+                "     \"sortOrder\" : 1\n" + //
+                "   } ]\n" + //
+                "  }\n" + //
+                "}");
 
         assertThat("Should deserialize Approvals", read, instanceOf(Approvals.class));
 
@@ -68,7 +69,7 @@ public class ApprovalsTest {
         assertNull("Deserialized `Account` approval should have null description", accountInfo.getDescription());
         assertEquals("Deserialized `Account` approval should have defined id", "04aD00000008Py9", accountInfo.getId());
         assertEquals("Deserialized `Account` approval should have defined name", "Account Approval Process",
-                accountInfo.getName());
+            accountInfo.getName());
         assertEquals("Deserialized `Account` approval should have defined object", "Account", accountInfo.getObject());
         assertEquals("Deserialized `Account` approval should have defined sortOrder", 1, accountInfo.getSortOrder());
     }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectBatchResponseTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectBatchResponseTest.java
index d8dfb89..0b60794 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectBatchResponseTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectBatchResponseTest.java
@@ -23,6 +23,8 @@ import java.util.Map;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.thoughtworks.xstream.XStream;
 
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -33,38 +35,6 @@ import static org.junit.Assert.assertTrue;
 
 public class SObjectBatchResponseTest {
 
-    static void assertResponse(final SObjectBatchResponse response) {
-        assertNotNull("Response should be parsed", response);
-
-        assertFalse("It should not have errors", response.hasErrors());
-
-        final List<SObjectBatchResult> results = response.getResults();
-        assertEquals("It should contain 2 results", 2, results.size());
-
-        final SObjectBatchResult firstResult = results.get(0);
-        assertEquals("First result should have status code of 204", 204, firstResult.getStatusCode());
-        assertNull("First result contain no data", firstResult.getResult());
-
-        final SObjectBatchResult secondResult = results.get(1);
-        assertEquals("Second result should have status code of 200", 200, secondResult.getStatusCode());
-
-        @SuppressWarnings("unchecked")
-        final Map<String, Object> secondResultMap = (Map<String, Object>) secondResult.getResult();
-        @SuppressWarnings("unchecked")
-        final Map<String, String> attributes = (Map<String, String>) secondResultMap.get("attributes");
-        assertEquals("Second result data should have attribute type set to `Account`", "Account",
-            attributes.get("type"));
-        assertEquals("Second result data should have attribute url set as expected",
-            "/services/data/v34.0/sobjects/Account/001D000000K0fXOIAZ", attributes.get("url"));
-
-        assertEquals("Second result data should have `NewName` set as expected", "NewName",
-            secondResultMap.get("Name"));
-        assertEquals("Second result data should have `BillingPostalCode` set as expected", "94105",
-            secondResultMap.get("BillingPostalCode"));
-        assertEquals("Second result data should have `Id` set as expected", "001D000000K0fXOIAZ",
-            secondResultMap.get("Id"));
-    }
-
     @Test
     public void shouldDeserializeFromJson() throws IOException {
 
@@ -87,7 +57,7 @@ public class SObjectBatchResponseTest {
             + "   }]\n"//
             + "}";
 
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final SObjectBatchResponse response = mapper.readerFor(SObjectBatchResponse.class).readValue(json);
 
@@ -116,8 +86,7 @@ public class SObjectBatchResponseTest {
             + "    </results>\n"//
             + "</batchResults>";
 
-        final XStream xStream = new XStream();
-        xStream.processAnnotations(new Class[] {SObjectBatchResponse.class});
+        final XStream xStream = XStreamUtils.createXStream(SObjectBatchResponse.class);
 
         final SObjectBatchResponse response = (SObjectBatchResponse) xStream.fromXML(xml);
 
@@ -153,4 +122,36 @@ public class SObjectBatchResponseTest {
         assertEquals("Second result data should have `Id` set as expected", "001D000000K0fXOIAZ", account.get("Id"));
     }
 
+    static void assertResponse(final SObjectBatchResponse response) {
+        assertNotNull("Response should be parsed", response);
+
+        assertFalse("It should not have errors", response.hasErrors());
+
+        final List<SObjectBatchResult> results = response.getResults();
+        assertEquals("It should contain 2 results", 2, results.size());
+
+        final SObjectBatchResult firstResult = results.get(0);
+        assertEquals("First result should have status code of 204", 204, firstResult.getStatusCode());
+        assertNull("First result contain no data", firstResult.getResult());
+
+        final SObjectBatchResult secondResult = results.get(1);
+        assertEquals("Second result should have status code of 200", 200, secondResult.getStatusCode());
+
+        @SuppressWarnings("unchecked")
+        final Map<String, Object> secondResultMap = (Map<String, Object>) secondResult.getResult();
+        @SuppressWarnings("unchecked")
+        final Map<String, String> attributes = (Map<String, String>) secondResultMap.get("attributes");
+        assertEquals("Second result data should have attribute type set to `Account`", "Account",
+            attributes.get("type"));
+        assertEquals("Second result data should have attribute url set as expected",
+            "/services/data/v34.0/sobjects/Account/001D000000K0fXOIAZ", attributes.get("url"));
+
+        assertEquals("Second result data should have `NewName` set as expected", "NewName",
+            secondResultMap.get("Name"));
+        assertEquals("Second result data should have `BillingPostalCode` set as expected", "94105",
+            secondResultMap.get("BillingPostalCode"));
+        assertEquals("Second result data should have `Id` set as expected", "001D000000K0fXOIAZ",
+            secondResultMap.get("Id"));
+    }
+
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectBatchTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectBatchTest.java
index 00c3d0b..5342e28 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectBatchTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectBatchTest.java
@@ -21,11 +21,10 @@ import java.util.regex.Pattern;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.thoughtworks.xstream.XStream;
-import com.thoughtworks.xstream.converters.reflection.FieldDictionary;
-import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
 
-import org.apache.camel.component.salesforce.api.dto.AnnotationFieldKeySorter;
 import org.apache.camel.component.salesforce.api.dto.composite.SObjectBatch.Method;
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.apache.camel.component.salesforce.dto.generated.Account;
 import org.apache.camel.component.salesforce.dto.generated.Account_IndustryEnum;
 import org.junit.Test;
@@ -54,16 +53,16 @@ public class SObjectBatchTest {
 
         batch.addLimits();
 
-        Account updates1 = new Account();
+        final Account updates1 = new Account();
         updates1.setName("NewName");
         updates1.setAccountNumber("AC12345");
         batch.addUpdate("Account", "001D000000K0fXOIAZ", updates1);
 
-        Account updates2 = new Account();
+        final Account updates2 = new Account();
         updates2.setName("NewName");
         batch.addUpdateByExternalId("Account", "EPK", "12345", updates2);
 
-        Account updates3 = new Account();
+        final Account updates3 = new Account();
         updates3.setName("NewName");
         batch.addUpsertByExternalId("Account", "EPK", "12345", updates3);
 
@@ -127,7 +126,7 @@ public class SObjectBatchTest {
                 + "}")
             .replaceAll("");
 
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final String serialized = mapper.writerFor(SObjectBatch.class).writeValueAsString(batch);
 
@@ -136,91 +135,89 @@ public class SObjectBatchTest {
 
     @Test
     public void shouldSerializeToXml() {
-        final String xml = "<batch>\n"//
-            + "  <batchRequests>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>POST</method>\n"//
-            + "      <url>v37.0/sobjects/Account/</url>\n"//
-            + "      <richInput>\n"//
-            + "        <Account>\n"//
-            + "          <Name>NewAccountName</Name>\n"//
-            + "          <Industry>Environmental</Industry>\n"//
-            + "        </Account>\n"//
-            + "      </richInput>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>DELETE</method>\n"//
-            + "      <url>v37.0/sobjects/Account/001D000000K0fXOIAZ</url>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>GET</method>\n"//
-            + "      <url>v37.0/sobjects/Account/001D000000K0fXOIAZ?fields=Name,BillingPostalCode</url>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>GET</method>\n"//
-            + "      <url>v37.0/sobjects/Account/EPK/12345</url>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>GET</method>\n"//
-            + "      <url>v37.0/sobjects/Account/001D000000K0fXOIAZ/CreatedBy?fields=Name</url>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>GET</method>\n"//
-            + "      <url>v37.0/limits/</url>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>PATCH</method>\n"//
-            + "      <url>v37.0/sobjects/Account/001D000000K0fXOIAZ</url>\n"//
-            + "      <richInput>\n"//
-            + "        <Account>\n"//
-            + "          <Name>NewName</Name>\n"//
-            + "          <AccountNumber>AC12345</AccountNumber>\n"//
-            + "        </Account>\n"//
-            + "      </richInput>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>PATCH</method>\n"//
-            + "      <url>v37.0/sobjects/Account/EPK/12345</url>\n"//
-            + "      <richInput>\n"//
-            + "        <Account>\n"//
-            + "          <Name>NewName</Name>\n"//
-            + "        </Account>\n"//
-            + "      </richInput>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>PATCH</method>\n"//
-            + "      <url>v37.0/sobjects/Account/EPK/12345</url>\n"//
-            + "      <richInput>\n"//
-            + "        <Account>\n"//
-            + "          <Name>NewName</Name>\n"//
-            + "        </Account>\n"//
-            + "      </richInput>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>PATCH</method>\n"//
-            + "      <url>v37.0/some/url</url>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>GET</method>\n"//
-            + "      <url>v37.0/query/?q=SELECT Name FROM Account</url>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>GET</method>\n"//
-            + "      <url>v37.0/queryAll/?q=SELECT Name FROM Account</url>\n"//
-            + "    </batchRequest>\n"//
-            + "    <batchRequest>\n"//
-            + "      <method>GET</method>\n"//
-            + "      <url>v37.0/search/?q=FIND {joe}</url>\n"//
-            + "    </batchRequest>\n"//
-            + "  </batchRequests>\n"//
+        final String xml = "<batch>"//
+            + "<batchRequests>"//
+            + "<batchRequest>"//
+            + "<method>POST</method>"//
+            + "<url>v37.0/sobjects/Account/</url>"//
+            + "<richInput>"//
+            + "<Account>"//
+            + "<Name>NewAccountName</Name>"//
+            + "<Industry>Environmental</Industry>"//
+            + "</Account>"//
+            + "</richInput>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>DELETE</method>"//
+            + "<url>v37.0/sobjects/Account/001D000000K0fXOIAZ</url>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>GET</method>"//
+            + "<url>v37.0/sobjects/Account/001D000000K0fXOIAZ?fields=Name,BillingPostalCode</url>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>GET</method>"//
+            + "<url>v37.0/sobjects/Account/EPK/12345</url>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>GET</method>"//
+            + "<url>v37.0/sobjects/Account/001D000000K0fXOIAZ/CreatedBy?fields=Name</url>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>GET</method>"//
+            + "<url>v37.0/limits/</url>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>PATCH</method>"//
+            + "<url>v37.0/sobjects/Account/001D000000K0fXOIAZ</url>"//
+            + "<richInput>"//
+            + "<Account>"//
+            + "<Name>NewName</Name>"//
+            + "<AccountNumber>AC12345</AccountNumber>"//
+            + "</Account>"//
+            + "</richInput>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>PATCH</method>"//
+            + "<url>v37.0/sobjects/Account/EPK/12345</url>"//
+            + "<richInput>"//
+            + "<Account>"//
+            + "<Name>NewName</Name>"//
+            + "</Account>"//
+            + "</richInput>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>PATCH</method>"//
+            + "<url>v37.0/sobjects/Account/EPK/12345</url>"//
+            + "<richInput>"//
+            + "<Account>"//
+            + "<Name>NewName</Name>"//
+            + "</Account>"//
+            + "</richInput>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>PATCH</method>"//
+            + "<url>v37.0/some/url</url>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>GET</method>"//
+            + "<url>v37.0/query/?q=SELECT Name FROM Account</url>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>GET</method>"//
+            + "<url>v37.0/queryAll/?q=SELECT Name FROM Account</url>"//
+            + "</batchRequest>"//
+            + "<batchRequest>"//
+            + "<method>GET</method>"//
+            + "<url>v37.0/search/?q=FIND {joe}</url>"//
+            + "</batchRequest>"//
+            + "</batchRequests>"//
             + "</batch>";
 
-        final PureJavaReflectionProvider reflectionProvider = new PureJavaReflectionProvider(
-            new FieldDictionary(new AnnotationFieldKeySorter()));
-        final XStream xStream = new XStream(reflectionProvider);
-        xStream.aliasSystemAttribute(null, "class");
-        xStream.processAnnotations(SObjectBatch.class);
-        xStream.processAnnotations(batch.objectTypes());
+        final Class<?>[] classes = new Class[batch.objectTypes().length + 1];
+        classes[0] = SObjectBatch.class;
+        System.arraycopy(batch.objectTypes(), 0, classes, 1, batch.objectTypes().length);
+        final XStream xStream = XStreamUtils.createXStream(classes);
 
         final String serialized = xStream.toXML(batch);
 
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectCompositeResponseTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectCompositeResponseTest.java
index d89e2c7..e192500 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectCompositeResponseTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectCompositeResponseTest.java
@@ -23,6 +23,7 @@ import java.util.Map;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
 import org.apache.commons.io.IOUtils;
 import org.junit.Test;
 
@@ -38,7 +39,7 @@ public class SObjectCompositeResponseTest {
                 "/org/apache/camel/component/salesforce/api/dto/composite_response_example_failure.json"),
             Charset.forName("UTF-8"));
 
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final SObjectCompositeResponse response = mapper.readerFor(SObjectCompositeResponse.class).readValue(json);
 
@@ -53,7 +54,7 @@ public class SObjectCompositeResponseTest {
                 "/org/apache/camel/component/salesforce/api/dto/composite_response_example_success.json"),
             Charset.forName("UTF-8"));
 
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final SObjectCompositeResponse response = mapper.readerFor(SObjectCompositeResponse.class).readValue(json);
 
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectCompositeTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectCompositeTest.java
index 5345875..fea7e05 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectCompositeTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectCompositeTest.java
@@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.SerializationFeature;
 
 import org.apache.camel.component.salesforce.api.dto.AbstractDescribedSObjectBase;
 import org.apache.camel.component.salesforce.api.dto.SObjectDescription;
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
 import org.apache.camel.component.salesforce.dto.generated.Account;
 import org.apache.camel.component.salesforce.dto.generated.Account_IndustryEnum;
 import org.apache.camel.component.salesforce.dto.generated.Contact;
@@ -109,7 +110,8 @@ public class SObjectCompositeTest {
                 .getResourceAsStream("/org/apache/camel/component/salesforce/api/dto/composite_request_example.json"),
             StandardCharsets.UTF_8);
 
-        final ObjectMapper mapper = new ObjectMapper().configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true)
+        final ObjectMapper mapper = JsonUtils.createObjectMapper().copy()
+            .configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true)
             .configure(SerializationFeature.INDENT_OUTPUT, true);
 
         final String serialized = mapper.writerFor(SObjectComposite.class).writeValueAsString(composite);
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectTreeResponseTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectTreeResponseTest.java
index ebdfe5d..8b85949 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectTreeResponseTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectTreeResponseTest.java
@@ -24,6 +24,8 @@ import com.fasterxml.jackson.databind.ObjectReader;
 import com.thoughtworks.xstream.XStream;
 
 import org.apache.camel.component.salesforce.api.dto.RestError;
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.junit.Test;
 
 import static org.hamcrest.core.IsCollectionContaining.hasItems;
@@ -54,7 +56,7 @@ public class SObjectTreeResponseTest {
             + "     }]\n"//
             + "}";
 
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final ObjectReader reader = mapper.readerFor(SObjectTreeResponse.class);
         final SObjectTreeResponse response = reader.readValue(json);
@@ -85,7 +87,7 @@ public class SObjectTreeResponseTest {
             + "     }]\n"//
             + "}";
 
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
 
         final ObjectReader reader = mapper.readerFor(SObjectTreeResponse.class);
         final SObjectTreeResponse response = reader.readValue(json);
@@ -123,8 +125,7 @@ public class SObjectTreeResponseTest {
             + "    </results>\n"//
             + "</Result>";
 
-        final XStream xStream = new XStream();
-        xStream.processAnnotations(new Class[] {SObjectTreeResponse.class});
+        final XStream xStream = XStreamUtils.createXStream(SObjectTreeResponse.class);
 
         final SObjectTreeResponse response = (SObjectTreeResponse) xStream.fromXML(xml);
 
@@ -154,8 +155,7 @@ public class SObjectTreeResponseTest {
             + "    </results>\n"//
             + "</Result>";
 
-        final XStream xStream = new XStream();
-        xStream.processAnnotations(new Class[] {SObjectTreeResponse.class});
+        final XStream xStream = XStreamUtils.createXStream(SObjectTreeResponse.class);
 
         final SObjectTreeResponse response = (SObjectTreeResponse) xStream.fromXML(xml);
 
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectTreeTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectTreeTest.java
index 4f0e46f..60b815d 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectTreeTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/composite/SObjectTreeTest.java
@@ -25,6 +25,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectWriter;
 import com.thoughtworks.xstream.XStream;
 
+import org.apache.camel.component.salesforce.api.utils.JsonUtils;
+import org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.apache.camel.component.salesforce.dto.generated.Account;
 import org.apache.camel.component.salesforce.dto.generated.Asset;
 import org.apache.camel.component.salesforce.dto.generated.Contact;
@@ -55,7 +57,7 @@ public class SObjectTreeTest extends CompositeTestBase {
 
     @Test
     public void shouldSerializeToJson() throws JsonProcessingException {
-        final ObjectMapper mapper = new ObjectMapper();
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
         mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
 
         final ObjectWriter writer = mapper.writerFor(SObjectTree.class);
@@ -123,39 +125,39 @@ public class SObjectTreeTest extends CompositeTestBase {
         final SObjectNode account2 = new SObjectNode(tree, simpleAccount2);
         tree.addNode(account2);
 
-        final XStream xStream = new XStream();
-        xStream.processAnnotations(new Class[] {SObjectTree.class, Account.class, Contact.class, Asset.class});
+        final XStream xStream = XStreamUtils.createXStream(SObjectTree.class, Account.class, Contact.class,
+            Asset.class);
 
         final String xml = xStream.toXML(tree);
 
         assertEquals("Should serialize to XML as in Salesforce example",
-            "<SObjectTreeRequest>\n"//
-                + "  <records type=\"Account\" referenceId=\"ref1\">\n"//
-                + "    <Name>SampleAccount</Name>\n"//
-                + "    <Phone>1234567890</Phone>\n"//
-                + "    <Website>www.salesforce.com</Website>\n"//
-                + "    <Industry>Banking</Industry>\n"//
-                + "    <NumberOfEmployees>100</NumberOfEmployees>\n"//
-                + "    <Contacts>\n"//
-                + "      <records type=\"Contact\" referenceId=\"ref2\">\n"//
-                + "        <Email>sample@salesforce.com</Email>\n"//
-                + "        <LastName>Smith</LastName>\n"//
-                + "        <Title>President</Title>\n"//
-                + "      </records>\n"//
-                + "      <records type=\"Contact\" referenceId=\"ref3\">\n"//
-                + "        <Email>sample@salesforce.com</Email>\n"//
-                + "        <LastName>Evans</LastName>\n"//
-                + "        <Title>Vice President</Title>\n"//
-                + "      </records>\n"//
-                + "    </Contacts>\n"//
-                + "  </records>\n"//
-                + "  <records type=\"Account\" referenceId=\"ref4\">\n"//
-                + "    <Name>SampleAccount2</Name>\n"//
-                + "    <Phone>1234567890</Phone>\n"//
-                + "    <Website>www.salesforce2.com</Website>\n"//
-                + "    <Industry>Banking</Industry>\n"//
-                + "    <NumberOfEmployees>100</NumberOfEmployees>\n"//
-                + "  </records>\n"//
+            "<SObjectTreeRequest>"//
+                + "<records type=\"Account\" referenceId=\"ref1\">"//
+                + "<Name>SampleAccount</Name>"//
+                + "<Phone>1234567890</Phone>"//
+                + "<Website>www.salesforce.com</Website>"//
+                + "<Industry>Banking</Industry>"//
+                + "<NumberOfEmployees>100</NumberOfEmployees>"//
+                + "<Contacts>"//
+                + "<records type=\"Contact\" referenceId=\"ref2\">"//
+                + "<Email>sample@salesforce.com</Email>"//
+                + "<LastName>Smith</LastName>"//
+                + "<Title>President</Title>"//
+                + "</records>"//
+                + "<records type=\"Contact\" referenceId=\"ref3\">"//
+                + "<Email>sample@salesforce.com</Email>"//
+                + "<LastName>Evans</LastName>"//
+                + "<Title>Vice President</Title>"//
+                + "</records>"//
+                + "</Contacts>"//
+                + "</records>"//
+                + "<records type=\"Account\" referenceId=\"ref4\">"//
+                + "<Name>SampleAccount2</Name>"//
+                + "<Phone>1234567890</Phone>"//
+                + "<Website>www.salesforce2.com</Website>"//
+                + "<Industry>Banking</Industry>"//
+                + "<NumberOfEmployees>100</NumberOfEmployees>"//
+                + "</records>"//
                 + "</SObjectTreeRequest>",
             xml);
     }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java
deleted file mode 100644
index f2bb8fe..0000000
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * 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.component.salesforce.api.utils;
-
-import java.time.LocalDate;
-import java.time.LocalTime;
-import java.time.OffsetTime;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class DateTimeUtilsTest {
-
-    @Test
-    public void testFormatDateTime() {
-        assertEquals("1991-12-10T12:13:14.007+01:00", DateTimeUtils.formatDateTime(ZonedDateTime.of(1991, 12, 10, 12, 13, 14, 7000000, ZoneId.of("UTC+01:00:21"))));
-        assertEquals("1991-12-10T12:13:14.007Z", DateTimeUtils.formatDateTime(ZonedDateTime.of(1991, 12, 10, 12, 13, 14, 7000000, ZoneId.of("UTC"))));
-        assertEquals("1700-01-01T01:13:14.007+00:19", DateTimeUtils.formatDateTime(ZonedDateTime.of(1700, 1, 1, 1, 13, 14, 7000000, ZoneId.of("UTC+00:19:21"))));
-        assertEquals("1700-02-03T02:13:14.007Z", DateTimeUtils.formatDateTime(ZonedDateTime.of(1700, 2, 3, 2, 13, 14, 7000000, ZoneId.of("UTC"))));
-    }
-
-    @Test
-    public void testParseDateTime() {
-        assertEquals(ZonedDateTime.of(1991, 12, 10, 12, 13, 14, 7000000, ZoneId.of("+01:00")), DateTimeUtils.parseDateTime("1991-12-10T12:13:14.007+01:00"));
-        assertEquals(ZonedDateTime.of(1991, 12, 10, 12, 13, 14, 0, ZoneId.of("Z")), DateTimeUtils.parseDateTime("1991-12-10T12:13:14+00:00"));
-        assertEquals(ZonedDateTime.of(1991, 12, 10, 12, 13, 14, 0, ZoneId.of("Z")), DateTimeUtils.parseDateTime("1991-12-10T12:13:14.000+00:00"));
-        assertEquals(ZonedDateTime.of(1991, 12, 10, 12, 13, 14, 0, ZoneId.of("Z")), DateTimeUtils.parseDateTime("1991-12-10T12:13:14+0000"));
-        assertEquals(ZonedDateTime.of(1991, 12, 10, 12, 13, 14, 0, ZoneId.of("Z")), DateTimeUtils.parseDateTime("1991-12-10T12:13:14.000+0000"));
-        assertEquals(ZonedDateTime.of(1991, 12, 10, 12, 13, 14, 7000000, ZoneId.of("Z")), DateTimeUtils.parseDateTime("1991-12-10T12:13:14.007Z"));
-        assertEquals(ZonedDateTime.of(1700, 1, 1, 1, 13, 14, 7000000, ZoneId.of("+00:19")), DateTimeUtils.parseDateTime("1700-01-01T01:13:14.007+00:19"));
-        assertEquals(ZonedDateTime.of(1700, 2, 3, 2, 13, 14, 7000000, ZoneId.of("Z")), DateTimeUtils.parseDateTime("1700-02-03T02:13:14.007Z"));
-    }
-
-    @Test
-    public void testFormatDate() {
-        assertEquals("1991-12-10", DateTimeUtils.formatDate(LocalDate.of(1991, 12, 10)));
-        assertEquals("2100-12-10", DateTimeUtils.formatDate(LocalDate.of(2100, 12, 10)));
-        assertEquals("1700-01-01", DateTimeUtils.formatDate(LocalDate.of(1700,  1,  1)));
-        }
-
-    @Test
-    public void testParseDate() {
-        assertEquals(LocalDate.of(1700, 01, 01), DateTimeUtils.parseDate("1700-01-01"));
-        assertEquals(LocalDate.of(2100, 12, 10), DateTimeUtils.parseDate("2100-12-10"));
-        assertEquals(LocalDate.of(1700,  1,  1), DateTimeUtils.parseDate("1700-01-01"));
-    }
-
-    @Test
-    public void testFormatTime() {
-        assertEquals("12:13:14.007", DateTimeUtils.formatTime(OffsetTime.of(12, 13, 14, 7000000,ZoneOffset.UTC)));
-        assertEquals("01:00:00", DateTimeUtils.formatTime(OffsetTime.of(1, 0, 0, 0,ZoneOffset.UTC)));
-        assertEquals("00:00:00", DateTimeUtils.formatTime(OffsetTime.of(LocalTime.MIDNIGHT,ZoneOffset.UTC)));
-    }
-
-    @Test
-    public void testParseTime() {
-        assertEquals(OffsetTime.of(LocalTime.MIDNIGHT, ZoneOffset.UTC), DateTimeUtils.parseTime("00:00:00.000"));
-        assertEquals(OffsetTime.of(1, 0, 0, 100, ZoneOffset.UTC), DateTimeUtils.parseTime("01:00:00.0000001"));
-        assertEquals(OffsetTime.of(12, 13, 14, 7000000, ZoneOffset.UTC), DateTimeUtils.parseTime("12:13:14.007"));
-        assertEquals(OffsetTime.of(12, 13, 0, 0, ZoneOffset.UTC), DateTimeUtils.parseTime("12:13"));
-    }
-}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/SalesforceTimeFormatsTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/SalesforceTimeFormatsTest.java
new file mode 100644
index 0000000..2a47013
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/SalesforceTimeFormatsTest.java
@@ -0,0 +1,199 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Objects;
+
+import static java.lang.String.format;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(Parameterized.class)
+public class SalesforceTimeFormatsTest {
+
+    @XStreamAlias("Dto")
+    public static class DateTransferObject<T> {
+
+        private T value;
+
+        public DateTransferObject() {
+        }
+
+        public DateTransferObject(final T value) {
+            this.value = value;
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if (obj == this) {
+                return true;
+            }
+
+            if (!(obj instanceof DateTransferObject)) {
+                return false;
+            }
+
+            final DateTransferObject<?> dto = (DateTransferObject<?>) obj;
+
+            return Objects.equals(value, dto.value);
+        }
+
+        public T getValue() {
+            return value;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(value, value);
+        }
+
+        public void setValue(final T value) {
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return String.valueOf(value);
+        }
+    }
+
+    private static final String JSON_FMT = "{\"value\":\"%s\"}";
+
+    private static final String XML_FMT = "<Dto><value>%s</value></Dto>";
+
+    private static final DateTimeFormatter ZONE_OFFSET_FORMATTER = new DateTimeFormatterBuilder()//
+        .appendOffset("+HHMM", "Z")//
+        .toFormatter();
+
+    @Parameter(0)
+    public DateTransferObject<?> dto;
+
+    @Parameter(1)
+    public String json;
+
+    @Parameter(3)
+    public Class<?> parameterType;
+
+    @Parameter(2)
+    public String xml;
+
+    private final ObjectMapper objectMapper = JsonUtils.createObjectMapper();
+
+    private final XStream xStream = XStreamUtils.createXStream(DateTransferObject.class);
+
+    @Test
+    public void shouldDeserializeJson() throws IOException {
+        final JavaType javaType = TypeFactory.defaultInstance().constructParametricType(DateTransferObject.class,
+            parameterType);
+
+        final DateTransferObject<?> deserialized = objectMapper.readerFor(javaType).readValue(json);
+
+        assertDeserializationResult(deserialized);
+    }
+
+    @Test
+    public void shouldDeserializeXml() {
+        xStream.addDefaultImplementation(parameterType, Object.class);
+
+        final DateTransferObject<?> deserialized = (DateTransferObject<?>) xStream.fromXML(xml);
+
+        assertDeserializationResult(deserialized);
+    }
+
+    @Test
+    public void shouldSerializeJson() throws JsonProcessingException {
+        assertThat(objectMapper.writeValueAsString(dto)).isEqualTo(json);
+    }
+
+    @Test
+    public void shouldSerializeXml() {
+        assertThat(xStream.toXML(dto)).isEqualTo(xml);
+    }
+
+    private void assertDeserializationResult(final DateTransferObject<?> deserialized) {
+        if (dto.value instanceof ZonedDateTime) {
+            // Salesforce expresses time in UTC+offset (ISO-8601 , with this we
+            // loose time zone information
+            final ZonedDateTime dtoValue = (ZonedDateTime) dto.value;
+            final ZonedDateTime deserializedValue = (ZonedDateTime) deserialized.value;
+
+            assertThat(deserializedValue).isEqualTo(dtoValue.withFixedOffsetZone());
+        } else {
+            assertThat(deserialized.value).isEqualTo(dto.value);
+        }
+    }
+
+    @Parameters
+    public static Iterable<Object[]> cases() {
+        final LocalDate localDate = LocalDate.of(2007, 03, 19);
+        final ZonedDateTime zonedDateTime = ZonedDateTime.of(localDate.atTime(10, 54, 57), ZoneId.of("Z"));
+        final Instant instant = zonedDateTime.toInstant();
+
+        final String zone = ZONE_OFFSET_FORMATTER.format(ZonedDateTime.now());
+
+        return Arrays.asList(//
+            dto(Date.from(instant), "2007-03-19T10:54:57.000+0000"), // 0
+            dto(Date.from(localDate.atStartOfDay().toInstant(ZoneOffset.UTC)), "2007-03-19T00:00:00.000+0000"), // 1
+            dto(localDate, "2007-03-19"), // 2
+            dto(zonedDateTime.toLocalDateTime(), "2007-03-19T10:54:57.000" + zone), // 3
+            dto(zonedDateTime.toOffsetDateTime(), "2007-03-19T10:54:57.000Z"), // 4
+            dto(zonedDateTime.toOffsetDateTime(), "2007-03-19T10:54:57.000Z"), // 5
+            dto(zonedDateTime.toOffsetDateTime().withOffsetSameInstant(ZoneOffset.of("-7")),
+                "2007-03-19T03:54:57.000-0700"), // 6
+            dto(zonedDateTime, "2007-03-19T10:54:57.000Z"), // 7
+            dto(zonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Kolkata")), "2007-03-19T16:24:57.000+0530"), // 8
+            dto(zonedDateTime.withZoneSameInstant(ZoneId.of("+3")), "2007-03-19T13:54:57.000+0300"), // 9
+            dto(instant,
+                instant.atZone(ZoneId.systemDefault())
+                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"))), // 10
+            dto(ZonedDateTime.of(2018, 03, 22, 9, 58, 8, 5000000, ZoneId.of("Z")), "2018-03-22T09:58:08.005Z") // 11
+        );
+    }
+
+    private static Object[] dto(final Object value, final String serialized) {
+        final DateTransferObject<?> dto = new DateTransferObject<>(value);
+
+        final String json = format(JSON_FMT, serialized);
+
+        final String xml = format(XML_FMT, serialized);
+
+        return new Object[] {dto, json, xml, value.getClass()};
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
zregvart@apache.org.

[camel] 01/05: CAMEL-12334: Mapped date to LocalDate and time to LocalTime

Posted by zr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit e9dac47a755b45e998abade0b5fc8476295646ef
Author: Ajmera, Hemang /External <he...@teliacompany.com>
AuthorDate: Wed Mar 14 12:55:32 2018 +0530

    CAMEL-12334: Mapped date to LocalDate and time to LocalTime
---
 .../salesforce/api/utils/DateConverter.java        | 56 ++++++++++++++++++++++
 .../salesforce/api/utils/DateDeserializer.java     | 48 +++++++++++++++++++
 .../component/salesforce/api/utils/DateModule.java | 31 ++++++++++++
 .../salesforce/api/utils/DateSerializer.java       | 50 +++++++++++++++++++
 .../salesforce/api/utils/DateTimeUtils.java        | 22 +++++++++
 .../component/salesforce/api/utils/JsonUtils.java  | 12 ++++-
 .../salesforce/api/utils/TimeConverter.java        | 56 ++++++++++++++++++++++
 .../salesforce/api/utils/TimeDeserializer.java     | 48 +++++++++++++++++++
 .../component/salesforce/api/utils/TimeModule.java | 31 ++++++++++++
 .../salesforce/api/utils/TimeSerializer.java       | 50 +++++++++++++++++++
 .../internal/client/DefaultCompositeApiClient.java |  4 ++
 .../salesforce/api/utils/DateTimeUtilsTest.java    | 31 ++++++++++++
 .../java/org/apache/camel/maven/GenerateMojo.java  |  4 +-
 13 files changed, 439 insertions(+), 4 deletions(-)

diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateConverter.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateConverter.java
new file mode 100644
index 0000000..6fa5ede
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateConverter.java
@@ -0,0 +1,56 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.time.LocalDate;
+
+import com.thoughtworks.xstream.converters.ConversionException;
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+/**
+ * XStream converter for handling {@link LocalDate} fields.
+ */
+public class DateConverter implements Converter {
+
+    @Override
+    public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) {
+        LocalDate date = (LocalDate) o;
+        writer.setValue(DateTimeUtils.formatDate(date));
+    }
+
+    @Override
+    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+        try {
+            return DateTimeUtils.parseDate(reader.getValue());
+        } catch (Exception e) {
+            throw new ConversionException(
+                    String.format("Error reading LocalDate from value %s: %s",
+                        reader.getValue(), e.getMessage()),
+                    e);
+        }
+    }
+
+    @Override
+    public boolean canConvert(Class aClass) {
+        return LocalDate.class.isAssignableFrom(aClass);
+    }
+
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateDeserializer.java
new file mode 100644
index 0000000..e39a695
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateDeserializer.java
@@ -0,0 +1,48 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.io.IOException;
+import java.time.LocalDate;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonMappingException;
+
+
+public class DateDeserializer extends JsonDeserializer<LocalDate> {
+
+    public DateDeserializer() {
+        super();
+    }
+
+    @Override
+    public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+        JsonToken currentToken = jsonParser.getCurrentToken();
+        if (currentToken == JsonToken.VALUE_STRING) {
+            return DateTimeUtils.parseDate(jsonParser.getText().trim());
+        }
+        throw JsonMappingException.from(deserializationContext, "Expected String value, got: " + currentToken);
+    }
+
+    @Override
+    public Class<?> handledType() {
+        return LocalDate.class;
+    }
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateModule.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateModule.java
new file mode 100644
index 0000000..7a2d5ad
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateModule.java
@@ -0,0 +1,31 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+
+import java.time.LocalDate;
+
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+public class DateModule extends SimpleModule {
+
+    public DateModule() {
+        super();
+        addSerializer(LocalDate.class, new DateSerializer());
+        addDeserializer(LocalDate.class, new DateDeserializer());
+    }
+}
\ No newline at end of file
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateSerializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateSerializer.java
new file mode 100644
index 0000000..4f21d6e
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateSerializer.java
@@ -0,0 +1,50 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.io.IOException;
+import java.time.LocalDate;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+
+
+public class DateSerializer extends JsonSerializer<LocalDate> {
+
+    public DateSerializer() {
+        super();
+    }
+
+    @Override
+    public void serialize(LocalDate date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+        jsonGenerator.writeString(DateTimeUtils.formatDate(date));
+    }
+
+    @Override
+    public Class<LocalDate> handledType() {
+        return LocalDate.class;
+    }
+
+    @Override
+    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException {
+        visitor.expectStringFormat(type);
+    }
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java
index 0da515e..518a78a 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java
@@ -17,12 +17,17 @@
 package org.apache.camel.component.salesforce.api.utils;
 
 import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.LocalTime;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DateTimeParseException;
 import java.util.regex.Pattern;
 
+import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME;
+import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE;
+
 /**
  * Utility class for working with DateTime fields.
  */
@@ -53,4 +58,21 @@ public abstract class DateTimeUtils {
         }
         return dateTimeAsString;
     }
+    
+    public static String formatDate(LocalDate date) {
+        return ISO_LOCAL_DATE.format(date);
+    }
+    
+    public static LocalDate parseDate(String date) {
+        return ISO_LOCAL_DATE.parse(date,LocalDate::from);
+    }
+        
+    public static String formatTime(LocalTime time) {
+        return ISO_LOCAL_TIME.format(time);
+    }
+    
+    public static LocalTime parseTime(String time) {
+        return ISO_LOCAL_TIME.parse(time, LocalTime::from);
+    }
+ 
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/JsonUtils.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/JsonUtils.java
index d3619da..4fbe8765 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/JsonUtils.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/JsonUtils.java
@@ -76,7 +76,9 @@ public abstract class JsonUtils {
         // enable date time support including Java 1.8 ZonedDateTime
         ObjectMapper objectMapper = new ObjectMapper();
         objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+        objectMapper.registerModule(new DateModule());
         objectMapper.registerModule(new DateTimeModule());
+        objectMapper.registerModule(new TimeModule());
         return objectMapper;
     }
 
@@ -190,13 +192,19 @@ public abstract class JsonUtils {
                 fieldSchema = new BooleanSchema();
                 break;
 
-            case "dateTime":
-            case "time":
             case "date":
+                fieldSchema = new StringSchema();
+                ((StringSchema) fieldSchema).setFormat(JsonValueFormat.DATE);
+                break;
+            case "dateTime": 
             case "g":
                 fieldSchema = new StringSchema();
                 ((StringSchema) fieldSchema).setFormat(JsonValueFormat.DATE_TIME);
                 break;
+            case "time":
+                fieldSchema = new StringSchema();
+                ((StringSchema) fieldSchema).setFormat(JsonValueFormat.TIME);
+                break;
 
             case "address":
                 if (addressSchema == null) {
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeConverter.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeConverter.java
new file mode 100644
index 0000000..e12d7e6
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeConverter.java
@@ -0,0 +1,56 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.time.LocalTime;
+
+import com.thoughtworks.xstream.converters.ConversionException;
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+/**
+ * XStream converter for handling {@link LocalTime} fields.
+ */
+public class TimeConverter implements Converter {
+
+    @Override
+    public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) {
+        LocalTime time = (LocalTime) o;
+        writer.setValue(DateTimeUtils.formatTime(time));
+    }
+
+    @Override
+    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+        try {
+            return DateTimeUtils.parseTime(reader.getValue());
+        } catch (Exception e) {
+            throw new ConversionException(
+                    String.format("Error reading LocalTime from value %s: %s",
+                        reader.getValue(), e.getMessage()),
+                    e);
+        }
+    }
+
+    @Override
+    public boolean canConvert(Class aClass) {
+        return LocalTime.class.isAssignableFrom(aClass);
+    }
+
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeDeserializer.java
new file mode 100644
index 0000000..5085254
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeDeserializer.java
@@ -0,0 +1,48 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.io.IOException;
+import java.time.LocalTime;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonMappingException;
+
+
+public class TimeDeserializer extends JsonDeserializer<LocalTime> {
+
+    public TimeDeserializer() {
+        super();
+    }
+
+    @Override
+    public LocalTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+        JsonToken currentToken = jsonParser.getCurrentToken();
+        if (currentToken == JsonToken.VALUE_STRING) {
+            return DateTimeUtils.parseTime(jsonParser.getText().trim());
+        }
+        throw JsonMappingException.from(deserializationContext, "Expected String value, got: " + currentToken);
+    }
+
+    @Override
+    public Class<?> handledType() {
+        return LocalTime.class;
+    }
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
new file mode 100644
index 0000000..cdd5b88
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
@@ -0,0 +1,31 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+
+import java.time.LocalTime;
+
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+public class TimeModule extends SimpleModule {
+
+    public TimeModule() {
+        super();
+        addSerializer(LocalTime.class, new TimeSerializer());
+        addDeserializer(LocalTime.class, new TimeDeserializer());
+    }
+}
\ No newline at end of file
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeSerializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeSerializer.java
new file mode 100644
index 0000000..1c83b8a
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeSerializer.java
@@ -0,0 +1,50 @@
+/**
+ * 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.component.salesforce.api.utils;
+
+import java.io.IOException;
+import java.time.LocalTime;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+
+
+public class TimeSerializer extends JsonSerializer<LocalTime> {
+
+    public TimeSerializer() {
+        super();
+    }
+
+    @Override
+    public void serialize(LocalTime time, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+        jsonGenerator.writeString(DateTimeUtils.formatTime(time));
+    }
+
+    @Override
+    public Class<LocalTime> handledType() {
+        return LocalTime.class;
+    }
+
+    @Override
+    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException {
+        visitor.expectStringFormat(type);
+    }
+}
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java
index 9efc74b..bc682d3 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java
@@ -52,7 +52,9 @@ import org.apache.camel.component.salesforce.api.dto.composite.SObjectComposite;
 import org.apache.camel.component.salesforce.api.dto.composite.SObjectCompositeResponse;
 import org.apache.camel.component.salesforce.api.dto.composite.SObjectTree;
 import org.apache.camel.component.salesforce.api.dto.composite.SObjectTreeResponse;
+import org.apache.camel.component.salesforce.api.utils.DateConverter;
 import org.apache.camel.component.salesforce.api.utils.DateTimeConverter;
+import org.apache.camel.component.salesforce.api.utils.TimeConverter;
 import org.apache.camel.component.salesforce.api.utils.JsonUtils;
 import org.apache.camel.component.salesforce.api.utils.Version;
 import org.apache.camel.component.salesforce.internal.PayloadFormat;
@@ -307,7 +309,9 @@ public class DefaultCompositeApiClient extends AbstractClientBase implements Com
         xStream.aliasSystemAttribute(null, "class");
         xStream.ignoreUnknownElements();
         XStreamUtils.addDefaultPermissions(xStream);
+        xStream.registerConverter(new DateConverter());
         xStream.registerConverter(new DateTimeConverter());
+        xStream.registerConverter(new TimeConverter());
         xStream.setMarshallingStrategy(new TreeMarshallingStrategy());
         xStream.processAnnotations(additionalTypes);
 
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java
index a08f73b..d50ba79 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.salesforce.api.utils;
 
+import java.time.LocalDate;
+import java.time.LocalTime;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
 
@@ -44,4 +46,33 @@ public class DateTimeUtilsTest {
         assertEquals(ZonedDateTime.of(1700, 1, 1, 1, 13, 14, 7000000, ZoneId.of("+00:19")), DateTimeUtils.parseDateTime("1700-01-01T01:13:14.007+00:19"));
         assertEquals(ZonedDateTime.of(1700, 2, 3, 2, 13, 14, 7000000, ZoneId.of("Z")), DateTimeUtils.parseDateTime("1700-02-03T02:13:14.007Z"));
     }
+
+    @Test
+    public void testFormatDate() {
+        assertEquals("1991-12-10", DateTimeUtils.formatDate(LocalDate.of(1991, 12, 10)));
+        assertEquals("2100-12-10", DateTimeUtils.formatDate(LocalDate.of(2100, 12, 10)));
+        assertEquals("1700-01-01", DateTimeUtils.formatDate(LocalDate.of(1700,  1,  1)));
+        }
+
+    @Test
+    public void testParseDate() {
+        assertEquals(LocalDate.of(1700, 01, 01), DateTimeUtils.parseDate("1700-01-01"));
+        assertEquals(LocalDate.of(2100, 12, 10), DateTimeUtils.parseDate("2100-12-10"));
+        assertEquals(LocalDate.of(1700,  1,  1), DateTimeUtils.parseDate("1700-01-01"));
+    }
+
+    @Test
+    public void testFormatTime() {
+        assertEquals("12:13:14.007", DateTimeUtils.formatTime(LocalTime.of(12, 13, 14, 7000000)));
+        assertEquals("01:00:00", DateTimeUtils.formatTime(LocalTime.of(1, 0, 0, 0)));
+        assertEquals("00:00:00", DateTimeUtils.formatTime(LocalTime.of(0, 0, 0)));
+    }
+
+    @Test
+    public void testParseTime() {
+        assertEquals(LocalTime.of(0,0,0), DateTimeUtils.parseTime("00:00:00.000"));
+        assertEquals(LocalTime.of(1,0,0,100), DateTimeUtils.parseTime("01:00:00.0000001"));
+        assertEquals(LocalTime.of(12,13,14,7000000), DateTimeUtils.parseTime("12:13:14.007"));
+        assertEquals(LocalTime.of(12,13,0), DateTimeUtils.parseTime("12:13"));
+    }
 }
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
index 7d1c452..9c40e8d 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
@@ -475,8 +475,8 @@ public class GenerateMojo extends AbstractSalesforceMojo {
             {"unsignedInt", "Long"}, //
             {"unsignedShort", "Integer"}, //
             {"unsignedByte", "Short"}, //
-            {"time", "java.time.ZonedDateTime"}, //
-            {"date", "java.time.ZonedDateTime"}, //
+            {"time", "java.time.LocalTime"}, //
+            {"date", "java.time.LocalDate"}, //
             {"g", "java.time.ZonedDateTime"}, //
             // Salesforce maps any types like string, picklist, reference, etc.
             // to string

-- 
To stop receiving notification emails like this one, please contact
zregvart@apache.org.

[camel] 04/05: CAMEL-12334: allow customization of types in ge...

Posted by zr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit c6c5621e1846211f9a3036201605e080bdc50939
Author: Zoran Regvart <zr...@apache.org>
AuthorDate: Thu Mar 22 15:31:44 2018 +0100

    CAMEL-12334: allow customization of types in ge...
    
    ...nerated source files
    
    With this customized types can be used instead of default ones for
    fields in generated Java DTO classes. The Salesforce Maven plugin now
    supports specifying `customTypes` property, for instance:
    
    ```xml
    <plugin>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-salesforce-maven-plugin</artifactId>
      <configuration>
        <!-- ... -->
        <customTypes>
          <date>java.time.LocalDateTime</date>
        </customTypes>
      </configuration>
    </plugin>
    ````
---
 .../src/main/docs/salesforce-component.adoc        |  24 ++-
 .../camel-salesforce-maven-plugin/README.md        |  20 ++-
 .../src/it/{simple-it => customized-types}/pom.xml |  15 +-
 .../src/it/customized-types/verify.groovy          |  21 +++
 .../src/it/simple-it/pom.xml                       |   8 +-
 .../apache/camel/maven/AbstractSalesforceMojo.java |   5 +
 .../java/org/apache/camel/maven/GenerateMojo.java  |  48 +++---
 .../camel/maven/CamelSalesforceMojoOutputTest.java |  65 +++++---
 .../src/test/resources/asset.json                  | 176 +++++++++++++++++++++
 .../src/test/resources/generated/Asset.java        | 107 +++++++++++++
 .../resources/generated/Asset_LocalDateTime.java   | 107 +++++++++++++
 11 files changed, 536 insertions(+), 60 deletions(-)

diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc b/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc
index 1cbb4e8..f1656e5 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc
@@ -535,7 +535,27 @@ final SObjectCompositeResult contactCreationResult = results.stream().filter(r -
 
 === Camel Salesforce Maven Plugin
 
-This Maven plugin generates DTOs for the Camel. Please refer to https://github.com/apache/camel/tree/master/components/camel-salesforce/camel-salesforce-maven-plugin[README.md] for details on how to generated the DTO.
+This Maven plugin generates DTOs for the Camel. 
+
+For obvious security reasons it is recommended that the clientId,
+clientSecret, userName and password fields be not set in the pom.xml.  
+The plugin should be configured for the rest of the properties, and can
+be executed using the following command:
+
+[source,java]
+----
+mvn camel-salesforce:generate -DcamelSalesforce.clientId=<clientid> -DcamelSalesforce.clientSecret=<clientsecret> \
+    -DcamelSalesforce.userName=<username> -DcamelSalesforce.password=<password>
+----
+
+The generated DTOs use Jackson and XStream annotations. All Salesforce
+field types are supported. Date and time fields are mapped to
+`java.time.ZonedDateTime` by default, and picklist fields are mapped to
+generated Java Enumerations.
+
+Please refer to
+https://github.com/apache/camel/tree/master/components/camel-salesforce/camel-salesforce-maven-plugin[README.md]
+for details on how to generated the DTO.
 
 === Options
 
@@ -665,4 +685,4 @@ with the following path and query parameters:
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. |  | ExchangePattern
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
 |===
-// endpoint options: END
\ No newline at end of file
+// endpoint options: END
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/README.md b/components/camel-salesforce/camel-salesforce-maven-plugin/README.md
index 67bbeeb..c90f904 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/README.md
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/README.md
@@ -18,8 +18,7 @@ The plugin configuration has the following properties.
 * includePattern - Java RegEx for SObject types to include
 * excludePattern - Java RegEx for SObject types to exclude
 * packageName - Java package name for generated DTOs, defaults to org.apache.camel.salesforce.dto.
-* useZonedTimeDateForDate - it will use ZonedTimeDate for Date if set to true. By default it will use LocalDate.
-* useZonedTimeDateForTime - it will use ZonedTimeDate for Time if set to true. By default it will use OffsetTime, with timezone offset set to UTC.
+* customTypes - override default types in generated DTOs
 
 Additonal properties to provide proxy information, if behind a firewall.
 
@@ -91,4 +90,19 @@ The plugin should be configured for the rest of the properties, and can be execu
 
 	mvn camel-salesforce:generate -DcamelSalesforce.clientId=<clientid> -DcamelSalesforce.clientSecret=<clientsecret> -DcamelSalesforce.userName=<username> -DcamelSalesforce.password=<password>
 
-The generated DTOs use Jackson and XStream annotations. All Salesforce field types are supported. DateTime and Timestamp fields are mapped to java.time.ZonedDateTime, and picklist fields are mapped to generated Java Enumerations.
+The generated DTOs use Jackson and XStream annotations. All Salesforce field types are supported. Date and time fields are mapped to java.time.ZonedDateTime, and picklist fields are mapped to generated Java Enumerations.
+
+You can customize types, i.e. use java.time.LocalDateTime instead of the default java.time.ZonedDateTime by specifying the `customTypes` property like:
+
+```xml
+<plugin>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-salesforce-maven-plugin</artifactId>
+  <configuration>
+    <!-- ... -->
+    <customTypes>
+      <date>java.time.LocalDateTime</date>
+    </customTypes>
+  </configuration>
+</plugin>
+````
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/customized-types/pom.xml
similarity index 85%
copy from components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml
copy to components/camel-salesforce/camel-salesforce-maven-plugin/src/it/customized-types/pom.xml
index 98ad9d6..4f60f88 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/customized-types/pom.xml
@@ -25,7 +25,7 @@
   <artifactId>camel-salesforce-maven-plugin-it</artifactId>
   <version>1.0-SNAPSHOT</version>
 
-  <description>A simple IT verifying the basic use case.</description>
+  <description>A IT verifying the customization of the plugin.</description>
 
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -68,12 +68,15 @@
                 <maxConnectionsPerAddress>10</maxConnectionsPerAddress>
                 <removeIdleDestinations>true</removeIdleDestinations>
               </httpClientProperties>
-              <includePattern>(.*__c)</includePattern>
+              <includePattern>Asset</includePattern>
               <!-- Salesforce login info -->
-              <clientId>${clientId}</clientId>
-              <clientSecret>${clientSecret}</clientSecret>
-              <userName>${userName}</userName>
-              <password>${password}</password>
+              <clientId>${salesforce.client.id}</clientId>
+              <clientSecret>${salesforce.client.secret}</clientSecret>
+              <userName>${salesforce.username}</userName>
+              <password>${salesforce.password}</password>
+              <customTypes>
+                <date>java.time.LocalDateTime</date>
+              </customTypes>
             </configuration>
           </execution>
         </executions>
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/customized-types/verify.groovy b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/customized-types/verify.groovy
new file mode 100644
index 0000000..c76629d
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/customized-types/verify.groovy
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+// assert that the generated files directory exists
+File sourceDir = new File(basedir, "target/generated-sources/camel-salesforce");
+
+assert sourceDir.isDirectory()
+assert new File(sourceDir, "org/apache/camel/salesforce/dto/Asset.java").text.contains("java.time.LocalDateTime")
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml
index 98ad9d6..95a3614 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml
@@ -70,10 +70,10 @@
               </httpClientProperties>
               <includePattern>(.*__c)</includePattern>
               <!-- Salesforce login info -->
-              <clientId>${clientId}</clientId>
-              <clientSecret>${clientSecret}</clientSecret>
-              <userName>${userName}</userName>
-              <password>${password}</password>
+              <clientId>${salesforce.client.id}</clientId>
+              <clientSecret>${salesforce.client.secret}</clientSecret>
+              <userName>${salesforce.username}</userName>
+              <password>${salesforce.password}</password>
             </configuration>
           </execution>
         </executions>
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/AbstractSalesforceMojo.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/AbstractSalesforceMojo.java
index 5289bcf..b84e0f4 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/AbstractSalesforceMojo.java
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/AbstractSalesforceMojo.java
@@ -175,6 +175,8 @@ abstract class AbstractSalesforceMojo extends AbstractMojo {
 
     @Override
     public final void execute() throws MojoExecutionException, MojoFailureException {
+        setup();
+
         final RestClient restClient = connectToSalesforce();
         try {
             executeWithClient(restClient);
@@ -314,4 +316,7 @@ abstract class AbstractSalesforceMojo extends AbstractMojo {
     }
 
     protected abstract void executeWithClient(RestClient client) throws MojoExecutionException;
+
+    protected void setup() {
+    }
 }
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
index 32ac514..ef9031c 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
@@ -116,14 +116,14 @@ public class GenerateMojo extends AbstractSalesforceMojo {
                 return description.getName() + "_" + enumTypeName(field.getName()) + "[]";
             } else {
                 // map field to Java type
-                final String soapType = field.getSoapType().split(":",2)[1];
-                final String type = (
-                        (soapType.equals("date")&&useZonedTimeDateForDate) ||
-                        (soapType.equals("time")&&useZonedTimeDateForTime) )
-                        ? "java.time.ZonedDateTime" : LOOKUP_MAP.get(soapType);
+                final String soapType = field.getSoapType();
+                final String lookupType = soapType.substring(soapType.indexOf(':') + 1);
+                final String type = types.get(lookupType);
                 if (type == null) {
-                    getLog().warn(String.format("Unsupported field type %s in field %s of object %s", soapType,
+                    getLog().warn(String.format("Unsupported field type `%s` in field `%s` of object `%s`", soapType,
                         field.getName(), description.getName()));
+                    getLog().debug("Currently known types:\n " + types.entrySet().stream()
+                        .map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining("\n")));
                 }
                 return type;
             }
@@ -245,6 +245,8 @@ public class GenerateMojo extends AbstractSalesforceMojo {
         }
     }
 
+    public static final Map<String, String> DEFAULT_TYPES = defineLookupMap();
+
     private static final Set<String> BASE_FIELDS = defineBaseFields();
 
     private static final String BASE64BINARY = "base64Binary";
@@ -255,8 +257,6 @@ public class GenerateMojo extends AbstractSalesforceMojo {
 
     // used for velocity logging, to avoid creating velocity.log
     private static final Logger LOG = Logger.getLogger(GenerateMojo.class.getName());
-
-    private static final Map<String, String> LOOKUP_MAP = defineLookupMap();
     private static final String MULTIPICKLIST = "multipicklist";
 
     private static final String PACKAGE_NAME_PATTERN = "(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*\\.)+\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*";
@@ -271,6 +271,9 @@ public class GenerateMojo extends AbstractSalesforceMojo {
 
     private static final String UTF_8 = "UTF-8";
 
+    @Parameter
+    Map<String, String> customTypes;
+
     VelocityEngine engine;
 
     /**
@@ -313,26 +316,17 @@ public class GenerateMojo extends AbstractSalesforceMojo {
     @Parameter
     private String[] includes;
 
+    private final Map<String, String> types = new HashMap<>(DEFAULT_TYPES);
+
     @Parameter(property = "camelSalesforce.useOptionals", defaultValue = "false")
     private boolean useOptionals;
 
     @Parameter(property = "camelSalesforce.useStringsForPicklists", defaultValue = "false")
     private Boolean useStringsForPicklists;
 
-    /**
-     * Generator will use java.time.ZonedTimeDate for Date if set to true, else it will default to java.time.LocalDate
-     */
-    @Parameter(property = "camelSalesforce.useZonedTimeDateForDate", defaultValue = "false")
-    private boolean useZonedTimeDateForDate;
- 
-    /**
-     * Generator will use java.time.ZonedTimeDate for Time if set to true, else it will default to java.time.OffsetTime
-     */
-    @Parameter(property = "camelSalesforce.useZonedTimeDateForTime", defaultValue = "false")
-    private boolean useZonedTimeDateForTime;
-    
     void processDescription(final File pkgDir, final SObjectDescription description, final GeneratorUtility utility,
         final String generatedDate) throws IOException {
+
         // generate a source file for SObject
         final VelocityContext context = new VelocityContext();
         context.put("packageName", packageName);
@@ -447,6 +441,13 @@ public class GenerateMojo extends AbstractSalesforceMojo {
         getLog().info(String.format("Successfully generated %s Java Classes", descriptions.count() * 2));
     }
 
+    @Override
+    protected void setup() {
+        if (customTypes != null) {
+            types.putAll(customTypes);
+        }
+    }
+
     static VelocityEngine createVelocityEngine() {
         // initialize velocity to load resources from class loader and use Log4J
         final Properties velocityProperties = new Properties();
@@ -490,8 +491,8 @@ public class GenerateMojo extends AbstractSalesforceMojo {
             {"unsignedInt", "Long"}, //
             {"unsignedShort", "Integer"}, //
             {"unsignedByte", "Short"}, //
-            {"time", "java.time.OffsetTime"}, //
-            {"date", "java.time.LocalDate"}, //
+            {"time", "java.time.ZonedDateTime"}, //
+            {"date", "java.time.ZonedDateTime"}, //
             {"g", "java.time.ZonedDateTime"}, //
             // Salesforce maps any types like string, picklist, reference, etc.
             // to string
@@ -506,7 +507,6 @@ public class GenerateMojo extends AbstractSalesforceMojo {
             lookupMap.put(entry[0], entry[1]);
         }
 
-        return lookupMap;
+        return Collections.unmodifiableMap(lookupMap);
     }
-
 }
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoOutputTest.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoOutputTest.java
index 8251684..5000b26 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoOutputTest.java
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoOutputTest.java
@@ -21,6 +21,8 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.function.Consumer;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 
@@ -30,7 +32,6 @@ import org.apache.camel.test.junit4.TestSupport;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -48,28 +49,27 @@ public class CamelSalesforceMojoOutputTest {
     @Parameter(1)
     public SObjectDescription description;
 
+    @Parameter(3)
+    public String expected;
+
     @Parameter(0)
     public String json;
 
+    @Parameter(4)
+    public GenerateMojo mojo;
+
     @Parameter(2)
     public String source;
 
     @Rule
     public TemporaryFolder temp = new TemporaryFolder();
 
-    private GenerateMojo mojo;
-    private final GenerateMojo.GeneratorUtility utility = new GenerateMojo().new GeneratorUtility();
-
-    @Before
-    public void setUp() throws Exception {
-        mojo = new GenerateMojo();
-        mojo.engine = GenerateMojo.createVelocityEngine();
-    }
-
     @Test
-    public void testProcessDescriptionPickLists() throws Exception {
+    public void testProcessDescription() throws Exception {
         final File pkgDir = temp.newFolder();
 
+        final GenerateMojo.GeneratorUtility utility = mojo.new GeneratorUtility();
+
         mojo.processDescription(pkgDir, description, utility, FIXED_DATE);
 
         final File generatedFile = new File(pkgDir, source);
@@ -80,8 +80,8 @@ public class CamelSalesforceMojoOutputTest {
             // Content is the same, the ordering is a bit different.
             source += "-Java9";
         }
-        final String expectedContent = IOUtils
-            .toString(CamelSalesforceMojoOutputTest.class.getResource("/generated/" + source), StandardCharsets.UTF_8);
+        final String expectedContent = IOUtils.toString(
+            CamelSalesforceMojoOutputTest.class.getResource("/generated/" + expected), StandardCharsets.UTF_8);
 
         Assert.assertEquals(
             "Generated source file in " + source + " must be equal to the one present in test/resources",
@@ -90,12 +90,27 @@ public class CamelSalesforceMojoOutputTest {
 
     @Parameters(name = "json = {0}, source = {2}")
     public static Iterable<Object[]> parameters() throws IOException {
-        return Arrays.asList(pair(TEST_CASE_FILE, "Case.java"),
-            pair(TEST_CASE_FILE, "Case_PickListAccentMarkEnum.java"),
-            pair(TEST_CASE_FILE, "Case_PickListQuotationMarkEnum.java"),
-            pair(TEST_CASE_FILE, "Case_PickListSlashEnum.java"), pair(TEST_CASE_FILE, "QueryRecordsCase.java"),
-            pair(TEST_CALCULATED_FORMULA_FILE, "ComplexCalculatedFormula.java"),
-            pair(TEST_CALCULATED_FORMULA_FILE, "QueryRecordsComplexCalculatedFormula.java"));
+        return Arrays.asList(testCase(TEST_CASE_FILE, "Case.java"),
+            testCase(TEST_CASE_FILE, "Case_PickListAccentMarkEnum.java"),
+            testCase(TEST_CASE_FILE, "Case_PickListQuotationMarkEnum.java"),
+            testCase(TEST_CASE_FILE, "Case_PickListSlashEnum.java"), //
+            testCase(TEST_CASE_FILE, "QueryRecordsCase.java"),
+            testCase(TEST_CALCULATED_FORMULA_FILE, "ComplexCalculatedFormula.java"),
+            testCase(TEST_CALCULATED_FORMULA_FILE, "QueryRecordsComplexCalculatedFormula.java"),
+            testCase("asset.json", "Asset.java"), //
+            testCase("asset.json", "Asset.java", "Asset_LocalDateTime.java", mojo -> {
+                mojo.customTypes = new HashMap<>();
+                mojo.customTypes.put("date", "java.time.LocalDateTime");
+
+                mojo.setup();
+            }));
+    }
+
+    static GenerateMojo createMojo() {
+        final GenerateMojo mojo = new GenerateMojo();
+        mojo.engine = GenerateMojo.createVelocityEngine();
+
+        return mojo;
     }
 
     static SObjectDescription createSObjectDescription(final String name) throws IOException {
@@ -106,7 +121,15 @@ public class CamelSalesforceMojoOutputTest {
         }
     }
 
-    static Object[] pair(final String json, final String source) throws IOException {
-        return new Object[] {json, createSObjectDescription(json), source};
+    static Object[] testCase(final String json, final String source) throws IOException {
+        return testCase(json, source, source, String::valueOf);
+    }
+
+    static Object[] testCase(final String json, final String source, final String expected,
+        final Consumer<GenerateMojo> mojoConfigurator) throws IOException {
+        final GenerateMojo mojo = createMojo();
+        mojoConfigurator.accept(mojo);
+
+        return new Object[] {json, createSObjectDescription(json), source, expected, mojo};
     }
 }
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/asset.json b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/asset.json
new file mode 100644
index 0000000..2caa54c
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/asset.json
@@ -0,0 +1,176 @@
+{
+  "actionOverrides": [],
+  "activateable": false,
+  "compactLayoutable": true,
+  "createable": true,
+  "custom": false,
+  "customSetting": false,
+  "deletable": true,
+  "deprecatedAndHidden": false,
+  "feedEnabled": false,
+  "fields": [
+    {
+      "aggregatable": true,
+      "autoNumber": false,
+      "byteLength": 18,
+      "calculated": false,
+      "calculatedFormula": null,
+      "cascadeDelete": false,
+      "caseSensitive": false,
+      "compoundFieldName": null,
+      "controllerName": null,
+      "createable": false,
+      "custom": false,
+      "defaultValue": null,
+      "defaultValueFormula": null,
+      "defaultedOnCreate": true,
+      "dependentPicklist": false,
+      "deprecatedAndHidden": false,
+      "digits": 0,
+      "displayLocationInDecimal": false,
+      "encrypted": false,
+      "externalId": false,
+      "extraTypeInfo": null,
+      "filterable": true,
+      "filteredLookupInfo": null,
+      "groupable": true,
+      "highScaleNumber": false,
+      "htmlFormatted": false,
+      "idLookup": true,
+      "inlineHelpText": null,
+      "label": "Asset ID",
+      "length": 18,
+      "mask": null,
+      "maskType": null,
+      "name": "Id",
+      "nameField": false,
+      "namePointing": false,
+      "nillable": false,
+      "permissionable": false,
+      "picklistValues": [],
+      "polymorphicForeignKey": false,
+      "precision": 0,
+      "queryByDistance": false,
+      "referenceTargetField": null,
+      "referenceTo": [],
+      "relationshipName": null,
+      "relationshipOrder": null,
+      "restrictedDelete": false,
+      "restrictedPicklist": false,
+      "scale": 0,
+      "searchPrefilterable": false,
+      "soapType": "tns:ID",
+      "sortable": true,
+      "type": "id",
+      "unique": false,
+      "updateable": false,
+      "writeRequiresMasterRead": false
+    },
+    {
+      "aggregatable": true,
+      "autoNumber": false,
+      "byteLength": 0,
+      "calculated": false,
+      "calculatedFormula": null,
+      "cascadeDelete": false,
+      "caseSensitive": false,
+      "compoundFieldName": null,
+      "controllerName": null,
+      "createable": true,
+      "custom": false,
+      "defaultValue": null,
+      "defaultValueFormula": null,
+      "defaultedOnCreate": false,
+      "dependentPicklist": false,
+      "deprecatedAndHidden": false,
+      "digits": 0,
+      "displayLocationInDecimal": false,
+      "encrypted": false,
+      "externalId": false,
+      "extraTypeInfo": null,
+      "filterable": true,
+      "filteredLookupInfo": null,
+      "groupable": true,
+      "highScaleNumber": false,
+      "htmlFormatted": false,
+      "idLookup": false,
+      "inlineHelpText": null,
+      "label": "Install Date",
+      "length": 0,
+      "mask": null,
+      "maskType": null,
+      "name": "InstallDate",
+      "nameField": false,
+      "namePointing": false,
+      "nillable": true,
+      "permissionable": true,
+      "picklistValues": [],
+      "polymorphicForeignKey": false,
+      "precision": 0,
+      "queryByDistance": false,
+      "referenceTargetField": null,
+      "referenceTo": [],
+      "relationshipName": null,
+      "relationshipOrder": null,
+      "restrictedDelete": false,
+      "restrictedPicklist": false,
+      "scale": 0,
+      "searchPrefilterable": false,
+      "soapType": "xsd:date",
+      "sortable": true,
+      "type": "date",
+      "unique": false,
+      "updateable": true,
+      "writeRequiresMasterRead": false
+    }
+  ],
+  "hasSubtypes": false,
+  "isSubtype": false,
+  "keyPrefix": "02i",
+  "label": "Asset",
+  "labelPlural": "Assets",
+  "layoutable": true,
+  "listviewable": null,
+  "lookupLayoutable": null,
+  "mergeable": false,
+  "mruEnabled": true,
+  "name": "Asset",
+  "namedLayoutInfos": [],
+  "networkScopeFieldName": null,
+  "queryable": true,
+  "replicateable": true,
+  "retrieveable": true,
+  "searchLayoutable": true,
+  "searchable": true,
+  "supportedScopes": [
+    {
+      "label": "All assets",
+      "name": "everything"
+    },
+    {
+      "label": "My assets",
+      "name": "mine"
+    },
+    {
+      "label": "My team's assets",
+      "name": "team"
+    }
+  ],
+  "triggerable": true,
+  "undeletable": true,
+  "updateable": true,
+  "urls": {
+    "compactLayouts": "/services/data/v42.0/sobjects/Asset/describe/compactLayouts",
+    "rowTemplate": "/services/data/v42.0/sobjects/Asset/{ID}",
+    "approvalLayouts": "/services/data/v42.0/sobjects/Asset/describe/approvalLayouts",
+    "uiDetailTemplate": "https://eu11.salesforce.com/{ID}",
+    "uiEditTemplate": "https://eu11.salesforce.com/{ID}/e",
+    "defaultValues": "/services/data/v42.0/sobjects/Asset/defaultValues?recordTypeId&fields",
+    "listviews": "/services/data/v42.0/sobjects/Asset/listviews",
+    "describe": "/services/data/v42.0/sobjects/Asset/describe",
+    "uiNewRecord": "https://eu11.salesforce.com/02i/e",
+    "quickActions": "/services/data/v42.0/sobjects/Asset/quickActions",
+    "layouts": "/services/data/v42.0/sobjects/Asset/describe/layouts",
+    "sobject": "/services/data/v42.0/sobjects/Asset"
+  }
+}
\ No newline at end of file
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset.java
new file mode 100644
index 0000000..00468ec
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset.java
@@ -0,0 +1,107 @@
+/*
+ * Salesforce DTO generated by camel-salesforce-maven-plugin
+ * Generated on: Thu Mar 09 16:15:49 ART 2017
+ */
+package $packageName;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+import org.apache.camel.component.salesforce.api.dto.AbstractDescribedSObjectBase;
+import org.apache.camel.component.salesforce.api.dto.ChildRelationShip;
+import org.apache.camel.component.salesforce.api.dto.InfoUrls;
+import org.apache.camel.component.salesforce.api.dto.NamedLayoutInfo;
+import org.apache.camel.component.salesforce.api.dto.RecordTypeInfo;
+import org.apache.camel.component.salesforce.api.dto.SObjectDescription;
+import org.apache.camel.component.salesforce.api.dto.SObjectDescriptionUrls;
+import org.apache.camel.component.salesforce.api.dto.SObjectField;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Salesforce DTO for SObject Asset
+ */
+@Generated("org.apache.camel.maven.CamelSalesforceMojo")
+@XStreamAlias("Asset")
+public class Asset extends AbstractDescribedSObjectBase {
+
+    private static final SObjectDescription DESCRIPTION = createSObjectDescription();
+
+    // InstallDate
+    private java.time.ZonedDateTime InstallDate;
+
+    @JsonProperty("InstallDate")
+    public java.time.ZonedDateTime getInstallDate() {
+        return this.InstallDate;
+    }
+
+    @JsonProperty("InstallDate")
+    public void setInstallDate(java.time.ZonedDateTime InstallDate) {
+        this.InstallDate = InstallDate;
+    }
+
+
+    @Override
+    public final SObjectDescription description() {
+        return DESCRIPTION;
+    }
+
+    private static SObjectDescription createSObjectDescription() {
+        final SObjectDescription description = new SObjectDescription();
+
+
+        description.setMergeable(false);
+        description.setCreateable(true);
+        description.setQueryable(true);
+        description.setLabel("Asset");
+        description.setReplicateable(true);
+        description.setName("Asset");
+        description.setLayoutable(true);
+        description.setDeprecatedAndHidden(false);
+        description.setMruEnabled(true);
+        description.setSearchable(true);
+        description.setFeedEnabled(false);
+        description.setRetrieveable(true);
+        description.setCustomSetting(false);
+        description.setKeyPrefix("02i");
+        description.setUndeletable(true);
+        description.setSearchLayoutable("true");
+        description.setTriggerable(true);
+        description.setCustom(false);
+
+        final SObjectDescriptionUrls sObjectDescriptionUrls1 = new SObjectDescriptionUrls();
+        sObjectDescriptionUrls1.setDescribe("/services/data/v42.0/sobjects/Asset/describe");
+        sObjectDescriptionUrls1.setLayouts("/services/data/v42.0/sobjects/Asset/describe/layouts");
+        sObjectDescriptionUrls1.setSobject("/services/data/v42.0/sobjects/Asset");
+        sObjectDescriptionUrls1.setQuickActions("/services/data/v42.0/sobjects/Asset/quickActions");
+        sObjectDescriptionUrls1.setUiEditTemplate("https://eu11.salesforce.com/{ID}/e");
+        sObjectDescriptionUrls1.setDefaultValues("/services/data/v42.0/sobjects/Asset/defaultValues?recordTypeId&fields");
+        sObjectDescriptionUrls1.setRowTemplate("/services/data/v42.0/sobjects/Asset/{ID}");
+        sObjectDescriptionUrls1.setListviews("/services/data/v42.0/sobjects/Asset/listviews");
+        sObjectDescriptionUrls1.setCompactLayouts("/services/data/v42.0/sobjects/Asset/describe/compactLayouts");
+        sObjectDescriptionUrls1.setApprovalLayouts("/services/data/v42.0/sobjects/Asset/describe/approvalLayouts");
+        sObjectDescriptionUrls1.setUiNewRecord("https://eu11.salesforce.com/02i/e");
+        sObjectDescriptionUrls1.setUiDetailTemplate("https://eu11.salesforce.com/{ID}");
+        description.setUrls(sObjectDescriptionUrls1);
+        description.setCompactLayoutable(true);
+
+        final List<SObjectField> fields1 = new ArrayList<>();
+        description.setFields(fields1);
+
+        final SObjectField sObjectField1 = createField("Id", "Asset ID", "id", "tns:ID", 18, false, false, false, false, false, false, true);
+        fields1.add(sObjectField1);
+        final SObjectField sObjectField2 = createField("InstallDate", "Install Date", "date", "xsd:date", 0, false, true, false, false, false, false, false);
+        fields1.add(sObjectField2);
+
+        description.setActivateable(false);
+        description.setLabelPlural("Assets");
+        description.setUpdateable(true);
+        description.setDeletable(true);
+
+        return description;
+    }
+}
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset_LocalDateTime.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset_LocalDateTime.java
new file mode 100644
index 0000000..a0c6830
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/Asset_LocalDateTime.java
@@ -0,0 +1,107 @@
+/*
+ * Salesforce DTO generated by camel-salesforce-maven-plugin
+ * Generated on: Thu Mar 09 16:15:49 ART 2017
+ */
+package $packageName;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+import org.apache.camel.component.salesforce.api.dto.AbstractDescribedSObjectBase;
+import org.apache.camel.component.salesforce.api.dto.ChildRelationShip;
+import org.apache.camel.component.salesforce.api.dto.InfoUrls;
+import org.apache.camel.component.salesforce.api.dto.NamedLayoutInfo;
+import org.apache.camel.component.salesforce.api.dto.RecordTypeInfo;
+import org.apache.camel.component.salesforce.api.dto.SObjectDescription;
+import org.apache.camel.component.salesforce.api.dto.SObjectDescriptionUrls;
+import org.apache.camel.component.salesforce.api.dto.SObjectField;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Salesforce DTO for SObject Asset
+ */
+@Generated("org.apache.camel.maven.CamelSalesforceMojo")
+@XStreamAlias("Asset")
+public class Asset extends AbstractDescribedSObjectBase {
+
+    private static final SObjectDescription DESCRIPTION = createSObjectDescription();
+
+    // InstallDate
+    private java.time.LocalDateTime InstallDate;
+
+    @JsonProperty("InstallDate")
+    public java.time.LocalDateTime getInstallDate() {
+        return this.InstallDate;
+    }
+
+    @JsonProperty("InstallDate")
+    public void setInstallDate(java.time.LocalDateTime InstallDate) {
+        this.InstallDate = InstallDate;
+    }
+
+
+    @Override
+    public final SObjectDescription description() {
+        return DESCRIPTION;
+    }
+
+    private static SObjectDescription createSObjectDescription() {
+        final SObjectDescription description = new SObjectDescription();
+
+
+        description.setMergeable(false);
+        description.setCreateable(true);
+        description.setQueryable(true);
+        description.setLabel("Asset");
+        description.setReplicateable(true);
+        description.setName("Asset");
+        description.setLayoutable(true);
+        description.setDeprecatedAndHidden(false);
+        description.setMruEnabled(true);
+        description.setSearchable(true);
+        description.setFeedEnabled(false);
+        description.setRetrieveable(true);
+        description.setCustomSetting(false);
+        description.setKeyPrefix("02i");
+        description.setUndeletable(true);
+        description.setSearchLayoutable("true");
+        description.setTriggerable(true);
+        description.setCustom(false);
+
+        final SObjectDescriptionUrls sObjectDescriptionUrls1 = new SObjectDescriptionUrls();
+        sObjectDescriptionUrls1.setDescribe("/services/data/v42.0/sobjects/Asset/describe");
+        sObjectDescriptionUrls1.setLayouts("/services/data/v42.0/sobjects/Asset/describe/layouts");
+        sObjectDescriptionUrls1.setSobject("/services/data/v42.0/sobjects/Asset");
+        sObjectDescriptionUrls1.setQuickActions("/services/data/v42.0/sobjects/Asset/quickActions");
+        sObjectDescriptionUrls1.setUiEditTemplate("https://eu11.salesforce.com/{ID}/e");
+        sObjectDescriptionUrls1.setDefaultValues("/services/data/v42.0/sobjects/Asset/defaultValues?recordTypeId&fields");
+        sObjectDescriptionUrls1.setRowTemplate("/services/data/v42.0/sobjects/Asset/{ID}");
+        sObjectDescriptionUrls1.setListviews("/services/data/v42.0/sobjects/Asset/listviews");
+        sObjectDescriptionUrls1.setCompactLayouts("/services/data/v42.0/sobjects/Asset/describe/compactLayouts");
+        sObjectDescriptionUrls1.setApprovalLayouts("/services/data/v42.0/sobjects/Asset/describe/approvalLayouts");
+        sObjectDescriptionUrls1.setUiNewRecord("https://eu11.salesforce.com/02i/e");
+        sObjectDescriptionUrls1.setUiDetailTemplate("https://eu11.salesforce.com/{ID}");
+        description.setUrls(sObjectDescriptionUrls1);
+        description.setCompactLayoutable(true);
+
+        final List<SObjectField> fields1 = new ArrayList<>();
+        description.setFields(fields1);
+
+        final SObjectField sObjectField1 = createField("Id", "Asset ID", "id", "tns:ID", 18, false, false, false, false, false, false, true);
+        fields1.add(sObjectField1);
+        final SObjectField sObjectField2 = createField("InstallDate", "Install Date", "date", "xsd:date", 0, false, true, false, false, false, false, false);
+        fields1.add(sObjectField2);
+
+        description.setActivateable(false);
+        description.setLabelPlural("Assets");
+        description.setUpdateable(true);
+        description.setDeletable(true);
+
+        return description;
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
zregvart@apache.org.

[camel] 02/05: CAMEL-12334: Mapped date to LocalDate and time to OffsetTime. Added properties to control the behavior

Posted by zr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 9499be837d2f2ca3d79e5c678fa4111c51ddb1b6
Author: Ajmera, Hemang /External <he...@teliacompany.com>
AuthorDate: Tue Mar 20 11:05:12 2018 +0530

    CAMEL-12334: Mapped date to LocalDate and time to OffsetTime. Added properties to control the behavior
---
 .../camel-salesforce-component/README.md           |  2 +-
 .../src/main/docs/salesforce-component.adoc        | 32 ++--------------------
 .../salesforce/api/utils/DateTimeUtils.java        | 12 +++++---
 .../salesforce/api/utils/TimeConverter.java        | 10 +++----
 .../salesforce/api/utils/TimeDeserializer.java     |  8 +++---
 .../component/salesforce/api/utils/TimeModule.java |  6 ++--
 .../salesforce/api/utils/TimeSerializer.java       | 10 +++----
 .../salesforce/api/utils/DateTimeUtilsTest.java    | 16 ++++++-----
 .../camel-salesforce-maven-plugin/README.md        |  6 ++--
 .../java/org/apache/camel/maven/GenerateMojo.java  | 21 ++++++++++++--
 10 files changed, 60 insertions(+), 63 deletions(-)

diff --git a/components/camel-salesforce/camel-salesforce-component/README.md b/components/camel-salesforce/camel-salesforce-component/README.md
index b923dfa..00c65cc 100644
--- a/components/camel-salesforce/camel-salesforce-component/README.md
+++ b/components/camel-salesforce/camel-salesforce-component/README.md
@@ -1,7 +1,7 @@
 # Camel Salesforce component #
 
 This component supports producer and consumer endpoints to communicate with Salesforce using Java DTOs. 
-There is a companion maven plugin [camel-salesforce-plugin](https://github.com/dhirajsb/camel-salesforce-maven-plugin) that generates these DTOs. 
+There is a companion maven plugin [camel-salesforce-plugin](https://github.com/apache/camel/tree/master/components/camel-salesforce/camel-salesforce-maven-plugin) that generates these DTOs. 
 
 The component supports the following Salesforce APIs
 
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc b/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc
index 5926d6f..1cbb4e8 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc
@@ -22,7 +22,7 @@ for this component:
 ----
 
 NOTE: Developers wishing to contribute to the component are instructed
-to look at the README.md file on instructions on how to get started and
+to look at the https://github.com/apache/camel/tree/master/components/camel-salesforce/camel-salesforce-component/README.md[README.md] file on instructions on how to get started and
 setup your environment for running integration tests.
 
 === Authenticating to Salesforce
@@ -535,8 +535,7 @@ final SObjectCompositeResult contactCreationResult = results.stream().filter(r -
 
 === Camel Salesforce Maven Plugin
 
-This Maven plugin generates DTOs for the Camel
-<<salesforce-component,Salesforce>>.
+This Maven plugin generates DTOs for the Camel. Please refer to https://github.com/apache/camel/tree/master/components/camel-salesforce/camel-salesforce-maven-plugin[README.md] for details on how to generated the DTO.
 
 === Options
 
@@ -666,29 +665,4 @@ with the following path and query parameters:
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. |  | ExchangePattern
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
 |===
-// endpoint options: END
-
-
-
-
-For obvious security reasons it is recommended that the clientId,
-clientSecret, userName and password fields be not set in the pom.xml.  
-The plugin should be configured for the rest of the properties, and can
-be executed using the following command:
-
-[source,java]
-----
-mvn camel-salesforce:generate -DcamelSalesforce.clientId=<clientid> -DcamelSalesforce.clientSecret=<clientsecret> \
-    -DcamelSalesforce.userName=<username> -DcamelSalesforce.password=<password>
-----
-
-The generated DTOs use Jackson and XStream annotations. All Salesforce
-field types are supported. Date and time fields are mapped to Joda
-DateTime, and picklist fields are mapped to generated Java Enumerations.
-
-=== See Also
-
-* Configuring Camel
-* Component
-* Endpoint
-* Getting Started
+// endpoint options: END
\ No newline at end of file
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java
index 518a78a..881da39 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtils.java
@@ -19,6 +19,8 @@ package org.apache.camel.component.salesforce.api.utils;
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalTime;
+import java.time.OffsetTime;
+import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
@@ -67,12 +69,14 @@ public abstract class DateTimeUtils {
         return ISO_LOCAL_DATE.parse(date,LocalDate::from);
     }
         
-    public static String formatTime(LocalTime time) {
-        return ISO_LOCAL_TIME.format(time);
+    public static String formatTime(OffsetTime time) {
+        // Sets the timezone as UTC for the time before sending to salesforce
+        return ISO_LOCAL_TIME.format(time.withOffsetSameInstant(ZoneOffset.UTC).toLocalTime());
     }
     
-    public static LocalTime parseTime(String time) {
-        return ISO_LOCAL_TIME.parse(time, LocalTime::from);
+    public static OffsetTime parseTime(String time) {
+        // Sets the timezone as UTC for the time which comes from salesforce
+        return OffsetTime.of(ISO_LOCAL_TIME.parse(time, LocalTime::from), ZoneOffset.UTC);
     }
  
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeConverter.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeConverter.java
index e12d7e6..4f87b59 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeConverter.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeConverter.java
@@ -16,7 +16,7 @@
  */
 package org.apache.camel.component.salesforce.api.utils;
 
-import java.time.LocalTime;
+import java.time.OffsetTime;
 
 import com.thoughtworks.xstream.converters.ConversionException;
 import com.thoughtworks.xstream.converters.Converter;
@@ -26,13 +26,13 @@ import com.thoughtworks.xstream.io.HierarchicalStreamReader;
 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
 
 /**
- * XStream converter for handling {@link LocalTime} fields.
+ * XStream converter for handling {@link OffsetTime} fields.
  */
 public class TimeConverter implements Converter {
 
     @Override
     public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) {
-        LocalTime time = (LocalTime) o;
+        OffsetTime time = (OffsetTime) o;
         writer.setValue(DateTimeUtils.formatTime(time));
     }
 
@@ -42,7 +42,7 @@ public class TimeConverter implements Converter {
             return DateTimeUtils.parseTime(reader.getValue());
         } catch (Exception e) {
             throw new ConversionException(
-                    String.format("Error reading LocalTime from value %s: %s",
+                    String.format("Error reading OffsetTime from value %s: %s",
                         reader.getValue(), e.getMessage()),
                     e);
         }
@@ -50,7 +50,7 @@ public class TimeConverter implements Converter {
 
     @Override
     public boolean canConvert(Class aClass) {
-        return LocalTime.class.isAssignableFrom(aClass);
+        return OffsetTime.class.isAssignableFrom(aClass);
     }
 
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeDeserializer.java
index 5085254..7363db4 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeDeserializer.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeDeserializer.java
@@ -17,7 +17,7 @@
 package org.apache.camel.component.salesforce.api.utils;
 
 import java.io.IOException;
-import java.time.LocalTime;
+import java.time.OffsetTime;
 
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.core.JsonToken;
@@ -26,14 +26,14 @@ import com.fasterxml.jackson.databind.JsonDeserializer;
 import com.fasterxml.jackson.databind.JsonMappingException;
 
 
-public class TimeDeserializer extends JsonDeserializer<LocalTime> {
+public class TimeDeserializer extends JsonDeserializer<OffsetTime> {
 
     public TimeDeserializer() {
         super();
     }
 
     @Override
-    public LocalTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+    public OffsetTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
         JsonToken currentToken = jsonParser.getCurrentToken();
         if (currentToken == JsonToken.VALUE_STRING) {
             return DateTimeUtils.parseTime(jsonParser.getText().trim());
@@ -43,6 +43,6 @@ public class TimeDeserializer extends JsonDeserializer<LocalTime> {
 
     @Override
     public Class<?> handledType() {
-        return LocalTime.class;
+        return OffsetTime.class;
     }
 }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
index cdd5b88..3cfea55 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeModule.java
@@ -17,7 +17,7 @@
 package org.apache.camel.component.salesforce.api.utils;
 
 
-import java.time.LocalTime;
+import java.time.OffsetTime;
 
 import com.fasterxml.jackson.databind.module.SimpleModule;
 
@@ -25,7 +25,7 @@ public class TimeModule extends SimpleModule {
 
     public TimeModule() {
         super();
-        addSerializer(LocalTime.class, new TimeSerializer());
-        addDeserializer(LocalTime.class, new TimeDeserializer());
+        addSerializer(OffsetTime.class, new TimeSerializer());
+        addDeserializer(OffsetTime.class, new TimeDeserializer());
     }
 }
\ No newline at end of file
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeSerializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeSerializer.java
index 1c83b8a..f8d684a 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeSerializer.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/utils/TimeSerializer.java
@@ -17,7 +17,7 @@
 package org.apache.camel.component.salesforce.api.utils;
 
 import java.io.IOException;
-import java.time.LocalTime;
+import java.time.OffsetTime;
 
 import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.databind.JavaType;
@@ -27,20 +27,20 @@ import com.fasterxml.jackson.databind.SerializerProvider;
 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
 
 
-public class TimeSerializer extends JsonSerializer<LocalTime> {
+public class TimeSerializer extends JsonSerializer<OffsetTime> {
 
     public TimeSerializer() {
         super();
     }
 
     @Override
-    public void serialize(LocalTime time, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+    public void serialize(OffsetTime time, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
         jsonGenerator.writeString(DateTimeUtils.formatTime(time));
     }
 
     @Override
-    public Class<LocalTime> handledType() {
-        return LocalTime.class;
+    public Class<OffsetTime> handledType() {
+        return OffsetTime.class;
     }
 
     @Override
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java
index d50ba79..f2bb8fe 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/utils/DateTimeUtilsTest.java
@@ -18,7 +18,9 @@ package org.apache.camel.component.salesforce.api.utils;
 
 import java.time.LocalDate;
 import java.time.LocalTime;
+import java.time.OffsetTime;
 import java.time.ZoneId;
+import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 
 import org.junit.Test;
@@ -63,16 +65,16 @@ public class DateTimeUtilsTest {
 
     @Test
     public void testFormatTime() {
-        assertEquals("12:13:14.007", DateTimeUtils.formatTime(LocalTime.of(12, 13, 14, 7000000)));
-        assertEquals("01:00:00", DateTimeUtils.formatTime(LocalTime.of(1, 0, 0, 0)));
-        assertEquals("00:00:00", DateTimeUtils.formatTime(LocalTime.of(0, 0, 0)));
+        assertEquals("12:13:14.007", DateTimeUtils.formatTime(OffsetTime.of(12, 13, 14, 7000000,ZoneOffset.UTC)));
+        assertEquals("01:00:00", DateTimeUtils.formatTime(OffsetTime.of(1, 0, 0, 0,ZoneOffset.UTC)));
+        assertEquals("00:00:00", DateTimeUtils.formatTime(OffsetTime.of(LocalTime.MIDNIGHT,ZoneOffset.UTC)));
     }
 
     @Test
     public void testParseTime() {
-        assertEquals(LocalTime.of(0,0,0), DateTimeUtils.parseTime("00:00:00.000"));
-        assertEquals(LocalTime.of(1,0,0,100), DateTimeUtils.parseTime("01:00:00.0000001"));
-        assertEquals(LocalTime.of(12,13,14,7000000), DateTimeUtils.parseTime("12:13:14.007"));
-        assertEquals(LocalTime.of(12,13,0), DateTimeUtils.parseTime("12:13"));
+        assertEquals(OffsetTime.of(LocalTime.MIDNIGHT, ZoneOffset.UTC), DateTimeUtils.parseTime("00:00:00.000"));
+        assertEquals(OffsetTime.of(1, 0, 0, 100, ZoneOffset.UTC), DateTimeUtils.parseTime("01:00:00.0000001"));
+        assertEquals(OffsetTime.of(12, 13, 14, 7000000, ZoneOffset.UTC), DateTimeUtils.parseTime("12:13:14.007"));
+        assertEquals(OffsetTime.of(12, 13, 0, 0, ZoneOffset.UTC), DateTimeUtils.parseTime("12:13"));
     }
 }
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/README.md b/components/camel-salesforce/camel-salesforce-maven-plugin/README.md
index 54f42c4..67bbeeb 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/README.md
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/README.md
@@ -1,6 +1,6 @@
 # Maven plugin for camel-salesforce component #
 
-This plugin generates DTOs for the [Camel Salesforce Component](https://github.com/dhirajsb/camel-salesforce). 
+This plugin generates DTOs for the [Camel Salesforce Component](https://github.com/apache/camel/tree/master/components/camel-salesforce/camel-salesforce-component). 
 
 ## Usage ##
 
@@ -18,6 +18,8 @@ The plugin configuration has the following properties.
 * includePattern - Java RegEx for SObject types to include
 * excludePattern - Java RegEx for SObject types to exclude
 * packageName - Java package name for generated DTOs, defaults to org.apache.camel.salesforce.dto.
+* useZonedTimeDateForDate - it will use ZonedTimeDate for Date if set to true. By default it will use LocalDate.
+* useZonedTimeDateForTime - it will use ZonedTimeDate for Time if set to true. By default it will use OffsetTime, with timezone offset set to UTC.
 
 Additonal properties to provide proxy information, if behind a firewall.
 
@@ -89,4 +91,4 @@ The plugin should be configured for the rest of the properties, and can be execu
 
 	mvn camel-salesforce:generate -DcamelSalesforce.clientId=<clientid> -DcamelSalesforce.clientSecret=<clientsecret> -DcamelSalesforce.userName=<username> -DcamelSalesforce.password=<password>
 
-The generated DTOs use Jackson and XStream annotations. All Salesforce field types are supported. Date and time fields are mapped to java.time.ZonedDateTime, and picklist fields are mapped to generated Java Enumerations.
+The generated DTOs use Jackson and XStream annotations. All Salesforce field types are supported. DateTime and Timestamp fields are mapped to java.time.ZonedDateTime, and picklist fields are mapped to generated Java Enumerations.
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
index 9c40e8d..32ac514 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java
@@ -116,8 +116,11 @@ public class GenerateMojo extends AbstractSalesforceMojo {
                 return description.getName() + "_" + enumTypeName(field.getName()) + "[]";
             } else {
                 // map field to Java type
-                final String soapType = field.getSoapType();
-                final String type = LOOKUP_MAP.get(soapType.substring(soapType.indexOf(':') + 1));
+                final String soapType = field.getSoapType().split(":",2)[1];
+                final String type = (
+                        (soapType.equals("date")&&useZonedTimeDateForDate) ||
+                        (soapType.equals("time")&&useZonedTimeDateForTime) )
+                        ? "java.time.ZonedDateTime" : LOOKUP_MAP.get(soapType);
                 if (type == null) {
                     getLog().warn(String.format("Unsupported field type %s in field %s of object %s", soapType,
                         field.getName(), description.getName()));
@@ -316,6 +319,18 @@ public class GenerateMojo extends AbstractSalesforceMojo {
     @Parameter(property = "camelSalesforce.useStringsForPicklists", defaultValue = "false")
     private Boolean useStringsForPicklists;
 
+    /**
+     * Generator will use java.time.ZonedTimeDate for Date if set to true, else it will default to java.time.LocalDate
+     */
+    @Parameter(property = "camelSalesforce.useZonedTimeDateForDate", defaultValue = "false")
+    private boolean useZonedTimeDateForDate;
+ 
+    /**
+     * Generator will use java.time.ZonedTimeDate for Time if set to true, else it will default to java.time.OffsetTime
+     */
+    @Parameter(property = "camelSalesforce.useZonedTimeDateForTime", defaultValue = "false")
+    private boolean useZonedTimeDateForTime;
+    
     void processDescription(final File pkgDir, final SObjectDescription description, final GeneratorUtility utility,
         final String generatedDate) throws IOException {
         // generate a source file for SObject
@@ -475,7 +490,7 @@ public class GenerateMojo extends AbstractSalesforceMojo {
             {"unsignedInt", "Long"}, //
             {"unsignedShort", "Integer"}, //
             {"unsignedByte", "Short"}, //
-            {"time", "java.time.LocalTime"}, //
+            {"time", "java.time.OffsetTime"}, //
             {"date", "java.time.LocalDate"}, //
             {"g", "java.time.ZonedDateTime"}, //
             // Salesforce maps any types like string, picklist, reference, etc.

-- 
To stop receiving notification emails like this one, please contact
zregvart@apache.org.