Repository: camel Updated Branches: refs/heads/master 47c95399f -> 7ea7d1b69
Fix multi select picklist fields Signed-off-by: Sune Keller <abs...@almbrand.dk> Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/7ea7d1b6 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/7ea7d1b6 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/7ea7d1b6 Branch: refs/heads/master Commit: 7ea7d1b691360f317b928feda89ea5d6a8ce859e Parents: 47c9539 Author: Sune Keller <abs...@almbrand.dk> Authored: Tue Jun 14 12:32:15 2016 +0200 Committer: Sune Keller <abs...@almbrand.dk> Committed: Tue Jun 14 12:51:11 2016 +0200 ---------------------------------------------------------------------- .../api/StringMultiSelectPicklistConverter.java | 84 ++++++++++++++++++++ .../StringMultiSelectPicklistDeserializer.java | 67 ++++++++++++++++ .../StringMultiSelectPicklistSerializer.java | 56 +++++++++++++ .../apache/camel/maven/CamelSalesforceMojo.java | 4 +- .../src/main/resources/sobject-pojo.vm | 28 +++++-- 5 files changed, 230 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/7ea7d1b6/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistConverter.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistConverter.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistConverter.java new file mode 100644 index 0000000..f56ee05 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistConverter.java @@ -0,0 +1,84 @@ +/** + * 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; + +import java.lang.reflect.Array; + +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 MSPs mapped to String array fields. + */ +public class StringMultiSelectPicklistConverter implements Converter { + + @Override + public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) { + try { + final int length = Array.getLength(o); + + // construct a string of form value1;value2;... + final StringBuilder buffer = new StringBuilder(); + for (int i = 0; i < length; i++) { + buffer.append((String) o); + if (i < (length - 1)) { + buffer.append(';'); + } + } + writer.setValue(buffer.toString()); + } catch (Exception e) { + throw new ConversionException( + String.format("Exception writing pick list value %s of type %s: %s", + o, o.getClass().getName(), e.getMessage()), e); + } + } + + @Override + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + final String listValue = reader.getValue(); + final Class<?> requiredArrayType = context.getRequiredType(); + + try { + // parse the string of the form value1;value2;... + final String[] value = listValue.split(";"); + final int length = value.length; + final String[] resultArray = new String[length]; + for (int i = 0; i < length; i++) { + // use factory method to create object + resultArray[i] = value[i].trim(); + Array.set(resultArray, i, value[i].trim()); + } + return resultArray; + } catch (Exception e) { + throw new ConversionException( + String.format("Exception reading pick list value %s of type %s: %s", + listValue, requiredArrayType.getName(), e.getMessage()), e); + } + } + + @Override + public boolean canConvert(Class aClass) { + // check whether the Class is an array, and whether the array element is a String + final Class<?> componentType = aClass.getComponentType(); + return componentType != null && String.class == componentType; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/7ea7d1b6/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistDeserializer.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistDeserializer.java new file mode 100644 index 0000000..5fe86ae --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistDeserializer.java @@ -0,0 +1,67 @@ +/** + * 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; + +import java.io.IOException; +import java.lang.reflect.Array; + +import org.codehaus.jackson.JsonParseException; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.map.BeanProperty; +import org.codehaus.jackson.map.ContextualDeserializer; +import org.codehaus.jackson.map.DeserializationConfig; +import org.codehaus.jackson.map.DeserializationContext; +import org.codehaus.jackson.map.JsonDeserializer; +import org.codehaus.jackson.map.JsonMappingException; + +/** + * Jackson deserializer base class for reading ';' separated strings for MultiSelect pick-lists. + */ +public class StringMultiSelectPicklistDeserializer + extends JsonDeserializer<Object> implements ContextualDeserializer<Object> { + + @Override + public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + + final String listValue = jp.getText(); + + try { + // parse the string of the form value1;value2;... + final String[] value = listValue.split(";"); + final int length = value.length; + final Object resultArray = Array.newInstance(String.class, length); + for (int i = 0; i < length; i++) { + // use factory method to create object + Array.set(resultArray, i, value[i].trim()); + } + + return resultArray; + } catch (Exception e) { + throw new JsonParseException("Exception reading multi-select pick list value", jp.getCurrentLocation(), e); + } + } + + @Override + public JsonDeserializer<Object> createContextual(DeserializationConfig config, BeanProperty property) throws JsonMappingException { + final Class<?> rawClass = property.getType().getRawClass(); + final Class<?> componentType = rawClass.getComponentType(); + if (componentType == null || componentType != String.class) { + throw new JsonMappingException("Pick list String array expected for " + rawClass); + } + return new StringMultiSelectPicklistDeserializer(); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/7ea7d1b6/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistSerializer.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistSerializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistSerializer.java new file mode 100644 index 0000000..a3b15e4 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/StringMultiSelectPicklistSerializer.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; + +import java.io.IOException; +import java.lang.reflect.Array; + +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.JsonGenerator; +import org.codehaus.jackson.map.JsonSerializer; +import org.codehaus.jackson.map.SerializerProvider; + +/** + * Jackson Serializer for generating ';' separated strings for MultiSelect pick-lists. + */ +public class StringMultiSelectPicklistSerializer extends JsonSerializer<Object> { + + @Override + public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException { + try { + + String[] a = (String[]) value; + final int length = a.length; + + // construct a string of form value1;value2;... + final StringBuilder buffer = new StringBuilder(); + for (int i = 0; i < length; i++) { + buffer.append((String) a[i].trim()); + if (i < (length - 1)) { + buffer.append(';'); + } + } + + jgen.writeString(buffer.toString()); + + } catch (Exception e) { + throw new JsonGenerationException( + String.format("Exception writing pick list value %s of type %s: %s", + value, value.getClass().getName(), e.getMessage()), e); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/7ea7d1b6/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java index c58e56a..5d3d40e 100644 --- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java +++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java @@ -717,10 +717,10 @@ public class CamelSalesforceMojo extends AbstractMojo { } } else if (isMultiSelectPicklist(field)) { if (useStringsForPicklists) { - return description.getName() + "_" + enumTypeName(field.getName()) + "[]"; + return String.class.getName() + "[]"; } else { // use a pick list enum array, enum will be created after generating the SObject class - return enumTypeName(field.getName()) + "[]"; + return description.getName() + "_" + enumTypeName(field.getName()) + "[]"; } } else { // map field to Java type http://git-wip-us.apache.org/repos/asf/camel/blob/7ea7d1b6/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-pojo.vm ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-pojo.vm b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-pojo.vm index 438d7f5..6e1c47a 100644 --- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-pojo.vm +++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-pojo.vm @@ -21,20 +21,22 @@ */ package $packageName; -#if ( !$useStringsForPicklists ) ## add imports for XStreamConverter and PicklistEnumConverter if needed #set ( $hasPicklists = $utility.hasPicklists($desc) ) #set ( $hasMultiSelectPicklists = $utility.hasMultiSelectPicklists($desc) ) -#end import com.thoughtworks.xstream.annotations.XStreamAlias; -#if ( !$useStringsForPicklists ) -#if ( $hasPicklists || $hasMultiSelectPicklists ) +#if ( ($hasPicklists && !$useStringsForPicklists) || $hasMultiSelectPicklists ) import com.thoughtworks.xstream.annotations.XStreamConverter; #end -#if ( $hasPicklists ) +#if ( $hasPicklists && !$useStringsForPicklists ) import org.apache.camel.component.salesforce.api.PicklistEnumConverter; #end #if ( $hasMultiSelectPicklists ) +#if ( $useStringsForPicklists ) +import org.apache.camel.component.salesforce.api.StringMultiSelectPicklistConverter; +import org.apache.camel.component.salesforce.api.StringMultiSelectPicklistDeserializer; +import org.apache.camel.component.salesforce.api.StringMultiSelectPicklistSerializer; +#else import org.apache.camel.component.salesforce.api.MultiSelectPicklistConverter; import org.apache.camel.component.salesforce.api.MultiSelectPicklistDeserializer; import org.apache.camel.component.salesforce.api.MultiSelectPicklistSerializer; @@ -42,7 +44,7 @@ import org.apache.camel.component.salesforce.api.MultiSelectPicklistSerializer; #end import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase; import org.codehaus.jackson.annotate.JsonProperty; -#if ( !$useStringsForPicklists && $hasMultiSelectPicklists ) +#if ( $hasMultiSelectPicklists ) import org.codehaus.jackson.map.annotate.JsonDeserialize; import org.codehaus.jackson.map.annotate.JsonSerialize; #end @@ -67,8 +69,12 @@ public class $desc.Name extends AbstractSObjectBase { ## add a converter annotation if needed #if ( !$useStringsForPicklists && !$isMultiSelectPicklist && $utility.isPicklist($field) ) @XStreamConverter(PicklistEnumConverter.class) -#elseif ( !$useStringsForPicklists && $isMultiSelectPicklist ) +#elseif ( $isMultiSelectPicklist ) +#if ( $useStringsForPicklists ) + @XStreamConverter(StringMultiSelectPicklistConverter.class) +#else @XStreamConverter(MultiSelectPicklistConverter.class) +#end #else ## add an alias for blob field url if needed #if ( $propertyName != $fieldName ) @@ -80,16 +86,24 @@ public class $desc.Name extends AbstractSObjectBase { @JsonProperty("$fieldName") #if ( $isMultiSelectPicklist ) +#if ( $useStringsForPicklists ) + @JsonSerialize(using = StringMultiSelectPicklistSerializer.class) +#else @JsonSerialize(using = MultiSelectPicklistSerializer.class) #end +#end public $fieldType get$propertyName() { return this.$propertyName; } @JsonProperty("$fieldName") #if ( $isMultiSelectPicklist ) +#if ( $useStringsForPicklists ) + @JsonDeserialize(using = StringMultiSelectPicklistDeserializer.class) +#else @JsonDeserialize(using = MultiSelectPicklistDeserializer.class) #end +#end public void set$propertyName($fieldType $propertyName) { this.$propertyName = $propertyName; }