diff --git a/common/src/main/java/org/apache/sqoop/json/util/FormSerialization.java b/common/src/main/java/org/apache/sqoop/json/util/FormSerialization.java index 98768d6c..f01bc578 100644 --- a/common/src/main/java/org/apache/sqoop/json/util/FormSerialization.java +++ b/common/src/main/java/org/apache/sqoop/json/util/FormSerialization.java @@ -18,6 +18,7 @@ package org.apache.sqoop.json.util; import org.apache.commons.lang.StringUtils; +import org.apache.sqoop.common.SqoopException; import org.apache.sqoop.model.MBooleanInput; import org.apache.sqoop.model.MEnumInput; import org.apache.sqoop.model.MForm; @@ -32,6 +33,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * Convenient static methods for serializing forms. @@ -113,7 +115,11 @@ public static JSONObject extractForm(MForm mForm, boolean skipSensitive) { // Serialize value if is there // Skip if sensitive if (!mInput.isEmpty() && !(skipSensitive && mInput.isSensitive())) { - input.put(FORM_INPUT_VALUE, mInput.getUrlSafeValueString()); + if (mInput.getType() == MInputType.MAP) { + input.put(FORM_INPUT_VALUE, mInput.getValue()); + } else { + input.put(FORM_INPUT_VALUE, mInput.getUrlSafeValueString()); + } } mInputs.add(input); @@ -185,8 +191,19 @@ public static MForm restoreForm(JSONObject form) { // Propagate form optional value if(input.containsKey(FORM_INPUT_VALUE)) { - mInput.restoreFromUrlSafeValueString( - (String) input.get(FORM_INPUT_VALUE)); + switch (type) { + case MAP: + try { + mInput.setValue((Map)input.get(FORM_INPUT_VALUE)); + } catch (ClassCastException e) { + throw new SqoopException(SerializationError.SERIALIZATION_001, name + " requires a 'map' value."); + } + break; + default: + mInput.restoreFromUrlSafeValueString( + (String) input.get(FORM_INPUT_VALUE)); + break; + } } mInputs.add(mInput); } diff --git a/common/src/main/java/org/apache/sqoop/json/util/SerializationError.java b/common/src/main/java/org/apache/sqoop/json/util/SerializationError.java new file mode 100644 index 00000000..13989a37 --- /dev/null +++ b/common/src/main/java/org/apache/sqoop/json/util/SerializationError.java @@ -0,0 +1,41 @@ +/** + * 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.sqoop.json.util; + +import org.apache.sqoop.common.ErrorCode; + +public enum SerializationError implements ErrorCode { + + SERIALIZATION_001("Attempt to pass a non-map object to MAP type."), + + ; + + private final String message; + + private SerializationError(String message) { + this.message = message; + } + + public String getCode() { + return name(); + } + + public String getMessage() { + return message; + } +} diff --git a/common/src/test/java/org/apache/sqoop/json/util/TestFormSerialization.java b/common/src/test/java/org/apache/sqoop/json/util/TestFormSerialization.java index 98a70f1d..c4223ecd 100644 --- a/common/src/test/java/org/apache/sqoop/json/util/TestFormSerialization.java +++ b/common/src/test/java/org/apache/sqoop/json/util/TestFormSerialization.java @@ -17,6 +17,7 @@ */ package org.apache.sqoop.json.util; +import org.apache.sqoop.common.SqoopException; import org.apache.sqoop.model.MBooleanInput; import org.apache.sqoop.model.MEnumInput; import org.apache.sqoop.model.MForm; @@ -74,6 +75,57 @@ public void testAllDataTypes() { assertEquals("YES", retrieved.getEnumInput("Enum").getValue()); } + @Test + public void testMapDataType() { + MForm form = getMapForm(); + + // Inserted values + Map map = new HashMap(); + map.put("A", "B"); + form.getMapInput("Map").setValue(map); + + // Serialize + JSONObject jsonObject = FormSerialization.extractForm(form, false); + String serializedJson = jsonObject.toJSONString(); + + // Deserialize + JSONObject retrievedJson = (JSONObject) JSONValue.parse(serializedJson); + MForm retrieved = FormSerialization.restoreForm(retrievedJson); + assertEquals(map, retrieved.getMapInput("Map").getValue()); + } + + @Test(expected=SqoopException.class) + public void testMapDataTypeException() { + MForm form = getMapForm(); + + // Inserted values + Map map = new HashMap(); + map.put("A", "B"); + form.getMapInput("Map").setValue(map); + + // Serialize + JSONObject jsonObject = FormSerialization.extractForm(form, false); + String serializedJson = jsonObject.toJSONString(); + + // Replace map value with a fake string to force exception + String badSerializedJson = serializedJson.replace("{\"A\":\"B\"}", "\"nonsensical string\""); + System.out.println(badSerializedJson); + JSONObject retrievedJson = (JSONObject) JSONValue.parse(badSerializedJson); + FormSerialization.restoreForm(retrievedJson); + } + + protected MForm getMapForm() { + List> inputs; + MInput input; + + inputs = new LinkedList>(); + + input = new MMapInput("Map", false); + inputs.add(input); + + return new MForm("f", inputs); + } + /** * Return form with all data types. *