Repository: sqoop Updated Branches: refs/heads/sqoop2 c6047c4f2 -> 00ada83b7
SQOOP-2559: Sqoop2: Provide DateTime type for configuration objects (Dian Fu via Jarek Jarcec Cecho) Project: http://git-wip-us.apache.org/repos/asf/sqoop/repo Commit: http://git-wip-us.apache.org/repos/asf/sqoop/commit/00ada83b Tree: http://git-wip-us.apache.org/repos/asf/sqoop/tree/00ada83b Diff: http://git-wip-us.apache.org/repos/asf/sqoop/diff/00ada83b Branch: refs/heads/sqoop2 Commit: 00ada83b792de31784195bfd018a71e9b3508887 Parents: c6047c4 Author: Jarek Jarcec Cecho <[email protected]> Authored: Sun Sep 13 05:24:13 2015 -0700 Committer: Jarek Jarcec Cecho <[email protected]> Committed: Sun Sep 13 05:24:13 2015 -0700 ---------------------------------------------------------------------- common/pom.xml | 5 + .../json/util/ConfigInputSerialization.java | 5 + .../org/apache/sqoop/model/ConfigUtils.java | 3 + .../java/org/apache/sqoop/model/MConfig.java | 4 + .../org/apache/sqoop/model/MConfigList.java | 4 + .../org/apache/sqoop/model/MDateTimeInput.java | 94 ++++++++++++++ .../java/org/apache/sqoop/model/MInputType.java | 3 + .../json/util/TestConfigSerialization.java | 9 ++ .../org/apache/sqoop/model/TestMConfig.java | 3 + .../org/apache/sqoop/model/TestMConfigList.java | 3 + .../apache/sqoop/model/TestMDateTimeInput.java | 122 +++++++++++++++++++ connector/connector-sdk/pom.xml | 4 - .../common/CommonRepositoryHandler.java | 7 ++ .../sqoop/shell/utils/ConfigDisplayer.java | 13 ++ .../apache/sqoop/shell/utils/ConfigFiller.java | 108 ++++++++++++++++ 15 files changed, 383 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/common/pom.xml ---------------------------------------------------------------------- diff --git a/common/pom.xml b/common/pom.xml index ecd42bc..748fa7a 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -76,6 +76,11 @@ limitations under the License. <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> + + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + </dependency> </dependencies> <build> http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/common/src/main/java/org/apache/sqoop/json/util/ConfigInputSerialization.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/sqoop/json/util/ConfigInputSerialization.java b/common/src/main/java/org/apache/sqoop/json/util/ConfigInputSerialization.java index e2e5b67..eb42da3 100644 --- a/common/src/main/java/org/apache/sqoop/json/util/ConfigInputSerialization.java +++ b/common/src/main/java/org/apache/sqoop/json/util/ConfigInputSerialization.java @@ -23,6 +23,7 @@ import org.apache.sqoop.classification.InterfaceStability; import org.apache.sqoop.common.SqoopException; import org.apache.sqoop.model.InputEditable; import org.apache.sqoop.model.MBooleanInput; +import org.apache.sqoop.model.MDateTimeInput; import org.apache.sqoop.model.MEnumInput; import org.apache.sqoop.model.MConfig; import org.apache.sqoop.model.MConfigType; @@ -187,6 +188,10 @@ public final class ConfigInputSerialization { mInput = new MListInput(name, sensitive.booleanValue(), editable, overrides); break; } + case DATETIME: { + mInput = new MDateTimeInput(name, sensitive.booleanValue(), editable, overrides); + break; + } default: // do nothing break; http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/common/src/main/java/org/apache/sqoop/model/ConfigUtils.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/sqoop/model/ConfigUtils.java b/common/src/main/java/org/apache/sqoop/model/ConfigUtils.java index 5d53437..cf48425 100644 --- a/common/src/main/java/org/apache/sqoop/model/ConfigUtils.java +++ b/common/src/main/java/org/apache/sqoop/model/ConfigUtils.java @@ -27,6 +27,7 @@ import org.apache.sqoop.utils.ClassUtils; import org.apache.sqoop.validation.ConfigValidationRunner; import org.apache.sqoop.validation.Message; import org.apache.sqoop.validation.ConfigValidationResult; +import org.joda.time.DateTime; import org.json.simple.JSONObject; import java.lang.reflect.Field; @@ -169,6 +170,8 @@ public class ConfigUtils { ClassUtils.getEnumStrings(type)); } else if (type.isAssignableFrom(List.class)) { input = new MListInput(inputName, sensitive, editable, overrides); + } else if (type == DateTime.class) { + input = new MDateTimeInput(inputName, sensitive, editable, overrides); } else { throw new SqoopException(ModelError.MODEL_004, "Unsupported type " + type.getName() + " for input " + fieldName); http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/common/src/main/java/org/apache/sqoop/model/MConfig.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/sqoop/model/MConfig.java b/common/src/main/java/org/apache/sqoop/model/MConfig.java index 6f11d92..b618946 100644 --- a/common/src/main/java/org/apache/sqoop/model/MConfig.java +++ b/common/src/main/java/org/apache/sqoop/model/MConfig.java @@ -102,6 +102,10 @@ public final class MConfig extends MValidatedElement implements MClonable { return (MListInput)getInput(inputName); } + public MDateTimeInput getDateTimeInput(String inputName) { + return (MDateTimeInput)getInput(inputName); + } + @Override public String toString() { StringBuilder sb = new StringBuilder("config-").append(getName()); http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/common/src/main/java/org/apache/sqoop/model/MConfigList.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/sqoop/model/MConfigList.java b/common/src/main/java/org/apache/sqoop/model/MConfigList.java index 2a3c3e4..35cb17a 100644 --- a/common/src/main/java/org/apache/sqoop/model/MConfigList.java +++ b/common/src/main/java/org/apache/sqoop/model/MConfigList.java @@ -93,6 +93,10 @@ public class MConfigList implements MClonable { return (MListInput) getInput(name); } + public MDateTimeInput getDateTimeInput(String name) { + return (MDateTimeInput) getInput(name); + } + @Override public boolean equals(Object o) { if (this == o) { http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/common/src/main/java/org/apache/sqoop/model/MDateTimeInput.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/sqoop/model/MDateTimeInput.java b/common/src/main/java/org/apache/sqoop/model/MDateTimeInput.java new file mode 100644 index 0000000..7ce2558 --- /dev/null +++ b/common/src/main/java/org/apache/sqoop/model/MDateTimeInput.java @@ -0,0 +1,94 @@ +/** + * 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.model; + +import org.joda.time.DateTime; + +import org.apache.sqoop.classification.InterfaceAudience; +import org.apache.sqoop.classification.InterfaceStability; + [email protected] [email protected] +public class MDateTimeInput extends MInput<DateTime> { + + public MDateTimeInput(String name, boolean sensitive, InputEditable editable, String overrides) { + super(name, sensitive, editable, overrides); + } + + @Override + public String getUrlSafeValueString() { + if (isEmpty()) { + return ""; + } + + return String.valueOf(getValue().getMillis()); + } + + @Override + public void restoreFromUrlSafeValueString(String valueString) { + if (valueString == null || valueString.isEmpty()) { + setValue(null); + } else { + setValue(new DateTime(Long.parseLong(valueString))); + } + } + + @Override + public MInputType getType() { + return MInputType.DATETIME; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof MDateTimeInput)) { + return false; + } + + MDateTimeInput mdi = (MDateTimeInput) other; + return getName().equals(mdi.getName()); + } + + @Override + public int hashCode() { + return 23 + 31 * getName().hashCode(); + } + + @Override + public boolean isEmpty() { + return getValue() == null; + } + + @Override + public void setEmpty() { + setValue(null); + } + + @Override + public MDateTimeInput clone(boolean cloneWithValue) { + MDateTimeInput copy = new MDateTimeInput(getName(), isSensitive(), getEditable(), getOverrides()); + copy.setPersistenceId(getPersistenceId()); + if(cloneWithValue && this.getValue() != null) { + copy.setValue(new DateTime(this.getValue())); + } + return copy; + } +} http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/common/src/main/java/org/apache/sqoop/model/MInputType.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/sqoop/model/MInputType.java b/common/src/main/java/org/apache/sqoop/model/MInputType.java index 0f1fe0a..bc9d34f 100644 --- a/common/src/main/java/org/apache/sqoop/model/MInputType.java +++ b/common/src/main/java/org/apache/sqoop/model/MInputType.java @@ -51,5 +51,8 @@ public enum MInputType { /** List input type */ LIST, + /** DateTime input type */ + DATETIME + ; } http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/common/src/test/java/org/apache/sqoop/json/util/TestConfigSerialization.java ---------------------------------------------------------------------- diff --git a/common/src/test/java/org/apache/sqoop/json/util/TestConfigSerialization.java b/common/src/test/java/org/apache/sqoop/json/util/TestConfigSerialization.java index 2a2cfe8..ab4f258 100644 --- a/common/src/test/java/org/apache/sqoop/json/util/TestConfigSerialization.java +++ b/common/src/test/java/org/apache/sqoop/json/util/TestConfigSerialization.java @@ -33,6 +33,7 @@ import org.apache.sqoop.model.InputEditable; import org.apache.sqoop.model.MBooleanInput; import org.apache.sqoop.model.MConfig; import org.apache.sqoop.model.MConfigType; +import org.apache.sqoop.model.MDateTimeInput; import org.apache.sqoop.model.MEnumInput; import org.apache.sqoop.model.MInput; import org.apache.sqoop.model.MIntegerInput; @@ -40,6 +41,7 @@ import org.apache.sqoop.model.MListInput; import org.apache.sqoop.model.MLongInput; import org.apache.sqoop.model.MMapInput; import org.apache.sqoop.model.MStringInput; +import org.joda.time.DateTime; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.testng.annotations.Test; @@ -130,6 +132,8 @@ public class TestConfigSerialization { List<String> list = new LinkedList<String>(); list.add("C"); + DateTime dt = new DateTime(12345678L); + // Fill config with all values MConfig config = getConfig(); config.getStringInput("String").setValue("A"); @@ -138,6 +142,7 @@ public class TestConfigSerialization { config.getBooleanInput("Boolean").setValue(true); config.getEnumInput("Enum").setValue("YES"); config.getListInput("List").setValue(list); + config.getDateTimeInput("DateTime").setValue(dt); // Serialize that into JSON JSONObject jsonObject = ConfigInputSerialization.extractConfig(config, MConfigType.JOB, false); @@ -174,6 +179,7 @@ public class TestConfigSerialization { assertEquals(true, retrieved.getBooleanInput("Boolean").getValue().booleanValue()); assertEquals("YES", retrieved.getEnumInput("Enum").getValue()); assertEquals(list, retrieved.getListInput("List").getValue()); + assertEquals(dt, retrieved.getDateTimeInput("DateTime").getValue()); } protected MConfig getMapConfig() { @@ -220,6 +226,9 @@ public class TestConfigSerialization { input = new MListInput("List", false, InputEditable.ANY, StringUtils.EMPTY); inputs.add(input); + input = new MDateTimeInput("DateTime", false, InputEditable.ANY, StringUtils.EMPTY); + inputs.add(input); + return new MConfig("c", inputs); } } http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/common/src/test/java/org/apache/sqoop/model/TestMConfig.java ---------------------------------------------------------------------- diff --git a/common/src/test/java/org/apache/sqoop/model/TestMConfig.java b/common/src/test/java/org/apache/sqoop/model/TestMConfig.java index 2cb3989..f18b069 100644 --- a/common/src/test/java/org/apache/sqoop/model/TestMConfig.java +++ b/common/src/test/java/org/apache/sqoop/model/TestMConfig.java @@ -75,6 +75,7 @@ public class TestMConfig { MEnumInput enumInput = new MEnumInput("Config.D", false, InputEditable.ANY, StringUtils.EMPTY, new String[] { "I", "V" }); MListInput listInput = new MListInput("Config.E", false, InputEditable.ANY, StringUtils.EMPTY ); + MDateTimeInput dtInput = new MDateTimeInput("Config.F", false, InputEditable.ANY, StringUtils.EMPTY ); List<MInput<?>> inputs = new ArrayList<MInput<?>>(); inputs.add(intInput); @@ -83,6 +84,7 @@ public class TestMConfig { inputs.add(stringInput); inputs.add(enumInput); inputs.add(listInput); + inputs.add(dtInput); MConfig config = new MConfig("Config", inputs); assertEquals(intInput, config.getIntegerInput("Config.A")); @@ -91,5 +93,6 @@ public class TestMConfig { assertEquals(stringInput, config.getStringInput("Config.C")); assertEquals(enumInput, config.getEnumInput("Config.D")); assertEquals(listInput, config.getListInput("Config.E")); + assertEquals(dtInput, config.getDateTimeInput("Config.F")); } } http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/common/src/test/java/org/apache/sqoop/model/TestMConfigList.java ---------------------------------------------------------------------- diff --git a/common/src/test/java/org/apache/sqoop/model/TestMConfigList.java b/common/src/test/java/org/apache/sqoop/model/TestMConfigList.java index fd100b1..d0847fe 100644 --- a/common/src/test/java/org/apache/sqoop/model/TestMConfigList.java +++ b/common/src/test/java/org/apache/sqoop/model/TestMConfigList.java @@ -44,11 +44,13 @@ public class TestMConfigList { MEnumInput enumInput = new MEnumInput("Config2.D", false, InputEditable.ANY, StringUtils.EMPTY, new String[] { "I", "V" }); MListInput listInput = new MListInput("Config2.E", false, InputEditable.ANY, StringUtils.EMPTY); + MDateTimeInput dtInput = new MDateTimeInput("Config2.F", false, InputEditable.ANY, StringUtils.EMPTY); inputs = new ArrayList<MInput<?>>(); inputs.add(stringInput); inputs.add(enumInput); inputs.add(listInput); + inputs.add(dtInput); configs.add(new MConfig("Config2", inputs)); MConfigList config = new MConfigList(configs, MConfigType.JOB); @@ -57,5 +59,6 @@ public class TestMConfigList { assertEquals(stringInput, config.getStringInput("Config2.C")); assertEquals(enumInput, config.getEnumInput("Config2.D")); assertEquals(listInput, config.getListInput("Config2.E")); + assertEquals(dtInput, config.getDateTimeInput("Config2.F")); } } http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/common/src/test/java/org/apache/sqoop/model/TestMDateTimeInput.java ---------------------------------------------------------------------- diff --git a/common/src/test/java/org/apache/sqoop/model/TestMDateTimeInput.java b/common/src/test/java/org/apache/sqoop/model/TestMDateTimeInput.java new file mode 100644 index 0000000..9c110cd --- /dev/null +++ b/common/src/test/java/org/apache/sqoop/model/TestMDateTimeInput.java @@ -0,0 +1,122 @@ +/** + * 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.model; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.DateTime; +import org.testng.annotations.Test; + +/** + * Test class for org.apache.sqoop.model.MDateTimeInput + */ +public class TestMDateTimeInput { + /** + * Test for class initialization + */ + @Test + public void testInitialization() { + MDateTimeInput input = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY); + assertEquals("sqoopsqoop", input.getName()); + assertEquals(MInputType.DATETIME, input.getType()); + } + + /** + * Test for equals() method + */ + @Test + public void testEquals() { + // Positive test + MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY); + MDateTimeInput input2 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY); + assertTrue(input1.equals(input2)); + + // Negative test + MDateTimeInput input3 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY); + MDateTimeInput input4 = new MDateTimeInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY); + assertFalse(input3.equals(input4)); + } + + /** + * Test for value + */ + @Test + public void testValue() { + MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY); + + // Test for long format + DateTime dt = new DateTime(1234567L); + input1.setValue(dt); + assertEquals(dt, input1.getValue()); + + // Test for ISO8601 format + dt = DateTime.parse("2010-06-30T01:20"); + input1.setValue(dt); + assertEquals(dt, input1.getValue()); + + input1.setEmpty(); + assertNull(input1.getValue()); + } + + /** + * Test for getUrlSafeValueString() and restoreFromUrlSafeValueString() + */ + @Test + public void testUrlSafe() { + MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY); + DateTime dt = new DateTime(1234567L); + input1.setValue(dt); + // Getting URL safe string + String tmp = input1.getUrlSafeValueString(); + // Restore to actual value + input1.restoreFromUrlSafeValueString(tmp); + assertNotNull(input1.getValue()); + assertEquals(dt, input1.getValue()); + + input1.setValue(null); + tmp = input1.getUrlSafeValueString(); + input1.restoreFromUrlSafeValueString(tmp); + assertNull(input1.getValue()); + } + + /** + * Test case for MNamedElement.getLabelKey() and MNamedElement.getHelpKey() + */ + @Test + public void testNamedElement() { + MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY); + assertEquals("sqoopsqoop.label", input1.getLabelKey()); + assertEquals("sqoopsqoop.help", input1.getHelpKey()); + } + + /** + * Test for sensitivity + */ + @Test + public void testSensitivity() { + MDateTimeInput input1 = new MDateTimeInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY ); + MDateTimeInput input2 = new MDateTimeInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY ); + assertFalse(input1.isSensitive()); + assertTrue(input2.isSensitive()); + } +} http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/connector/connector-sdk/pom.xml ---------------------------------------------------------------------- diff --git a/connector/connector-sdk/pom.xml b/connector/connector-sdk/pom.xml index c888aa0..0cbbb04 100644 --- a/connector/connector-sdk/pom.xml +++ b/connector/connector-sdk/pom.xml @@ -33,10 +33,6 @@ limitations under the License. <dependencies> <dependency> - <groupId>joda-time</groupId> - <artifactId>joda-time</artifactId> - </dependency> - <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/repository/repository-common/src/main/java/org/apache/sqoop/repository/common/CommonRepositoryHandler.java ---------------------------------------------------------------------- diff --git a/repository/repository-common/src/main/java/org/apache/sqoop/repository/common/CommonRepositoryHandler.java b/repository/repository-common/src/main/java/org/apache/sqoop/repository/common/CommonRepositoryHandler.java index 6d303c8..c2ba6e3 100644 --- a/repository/repository-common/src/main/java/org/apache/sqoop/repository/common/CommonRepositoryHandler.java +++ b/repository/repository-common/src/main/java/org/apache/sqoop/repository/common/CommonRepositoryHandler.java @@ -49,6 +49,7 @@ import org.apache.sqoop.model.MConfigType; import org.apache.sqoop.model.MConfigUpdateEntityType; import org.apache.sqoop.model.MConfigurableType; import org.apache.sqoop.model.MConnector; +import org.apache.sqoop.model.MDateTimeInput; import org.apache.sqoop.model.MDriver; import org.apache.sqoop.model.MDriverConfig; import org.apache.sqoop.model.MEnumInput; @@ -1982,6 +1983,9 @@ public abstract class CommonRepositoryHandler extends JdbcRepositoryHandler { case LIST: input = new MListInput(inputName, inputSensitivity, editableEnum, overrides); break; + case DATETIME: + input = new MDateTimeInput(inputName, inputSensitivity, editableEnum, overrides); + break; default: throw new SqoopException(CommonRepositoryError.COMMON_0003, "input-" + inputName + ":" + inputId + ":" @@ -2128,6 +2132,9 @@ public abstract class CommonRepositoryHandler extends JdbcRepositoryHandler { case LIST: input = new MListInput(inputName, inputSensitivity, editableEnum, overrides); break; + case DATETIME: + input = new MDateTimeInput(inputName, inputSensitivity, editableEnum, overrides); + break; default: throw new SqoopException(CommonRepositoryError.COMMON_0003, "input-" + inputName + ":" + inputId + ":" + "config-" + inputConfig + ":" + mit.name()); http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigDisplayer.java ---------------------------------------------------------------------- diff --git a/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigDisplayer.java b/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigDisplayer.java index ab442fe..8414fe8 100644 --- a/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigDisplayer.java +++ b/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigDisplayer.java @@ -33,6 +33,7 @@ import org.apache.sqoop.model.MAccountableEntity; import org.apache.sqoop.model.MBooleanInput; import org.apache.sqoop.model.MConfig; import org.apache.sqoop.model.MConnector; +import org.apache.sqoop.model.MDateTimeInput; import org.apache.sqoop.model.MDriverConfig; import org.apache.sqoop.model.MEnumInput; import org.apache.sqoop.model.MInput; @@ -206,6 +207,9 @@ public final class ConfigDisplayer { case LIST: displayInputList((MListInput) input); break; + case DATETIME: + displayInputDateTime((MDateTimeInput) input); + break; default: print("\n%s " + input.getType(), resourceString(Constants.RES_CONFIG_DISPLAYER_UNSUPPORTED_DATATYPE)); return; @@ -289,6 +293,15 @@ public final class ConfigDisplayer { } } + /** + * Display content of DateTime input + * + * @param input DateTime input + */ + private static void displayInputDateTime(MDateTimeInput input) { + print(input.getValue()); + } + private ConfigDisplayer() { // Do not instantiate } http://git-wip-us.apache.org/repos/asf/sqoop/blob/00ada83b/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigFiller.java ---------------------------------------------------------------------- diff --git a/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigFiller.java b/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigFiller.java index 6f1af94..39bc914 100644 --- a/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigFiller.java +++ b/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigFiller.java @@ -24,6 +24,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.sqoop.common.Direction; import org.apache.sqoop.model.InputEditable; import org.apache.sqoop.model.MBooleanInput; +import org.apache.sqoop.model.MDateTimeInput; import org.apache.sqoop.model.MLink; import org.apache.sqoop.model.MEnumInput; import org.apache.sqoop.model.MConfig; @@ -38,6 +39,7 @@ import org.apache.sqoop.model.MStringInput; import org.apache.sqoop.model.MValidatedElement; import org.apache.sqoop.validation.Message; import org.apache.sqoop.validation.Status; +import org.joda.time.DateTime; import java.io.IOException; import java.util.LinkedList; @@ -202,6 +204,9 @@ public final class ConfigFiller { case LIST: assert input instanceof MListInput; return fillInputList(prefix, (MListInput) input, line); + case DATETIME: + assert input instanceof MDateTimeInput; + return fillInputDateTime(prefix, (MDateTimeInput) input, line); default: println("Unsupported data type " + input.getType()); return true; @@ -209,6 +214,55 @@ public final class ConfigFiller { } /** + * Load CLI options for datetime type. + * + * Supports the following two types of format: + * <ul> + * <li> ISO8601 format (yyyy-MM-ddTHH:mm:ss.SSSZZ) + * <li> Long which represents the milliseconds from 1970-01-01T00:00:00Z + * </ul> + * + * @param prefix placed at the beginning of the CLI option key + * @param input Input that we should read or edit + * @param line CLI options container + * @return + * @throws IOException + */ + private static boolean fillInputDateTime(String prefix, + MDateTimeInput input, + CommandLine line) + throws IOException { + String opt = ConfigOptions.getOptionKey(prefix, input); + if (line.hasOption(opt)) { + DateTime dt = parseDateTime(line.getOptionValue(opt)); + if (dt == null) { + errorMessage(input, "Input is not valid DateTime format"); + return false; + } + input.setValue(dt); + } else { + input.setEmpty(); + } + return true; + } + + private static DateTime parseDateTime(String value) { + DateTime dt = null; + try { + dt = DateTime.parse(value); + } catch (IllegalArgumentException iae) { + // value is not valid ISO8601 format + try { + long a = Long.parseLong(value); + dt = new DateTime(a); + } catch (NumberFormatException nfe) { + // value is not numeric string + } + } + return dt; + } + + /** * Load CLI options for list type. * * Parses elements that take the config "<element1>&<element2>&...". @@ -542,6 +596,8 @@ public final class ConfigFiller { return fillInputEnumWithBundle((MEnumInput) input, reader, bundle); case LIST: return fillInputListWithBundle((MListInput) input, reader, bundle); + case DATETIME: + return fillInputDateTimeWithBundle((MDateTimeInput) input, reader, bundle); default: println("Unsupported data type " + input.getType()); return true; @@ -549,6 +605,58 @@ public final class ConfigFiller { } /** + * Load user input for datetime type. + * + * This implementation supports the following two types of format: + * <ul> + * <li> ISO8601 format (yyyy-MM-ddTHH:mm:ss.SSSZZ) + * <li> Long which represents the milliseconds from 1970-01-01T00:00:00Z + * </ul> + * + * If user did not enter anything (empty input) finish loading and return from function. + * + * @param input Input that we should read or edit + * @param reader Associated console reader + * @param bundle Resource bundle + * @return True if user wish to continue with loading additional inputs + * @throws IOException + */ + private static boolean fillInputDateTimeWithBundle(MDateTimeInput input, + ConsoleReader reader, + ResourceBundle bundle) + throws IOException { + generatePrompt(reader, bundle, input); + + if (!input.isEmpty() && !input.isSensitive()) { + reader.putString(input.getValue().toString()); + } + + // Get the data + String userTyped; + if (input.isSensitive()) { + userTyped = reader.readLine('*'); + } else { + userTyped = reader.readLine(); + } + + if (userTyped == null) { + return false; + } else if (userTyped.isEmpty()) { + input.setEmpty(); + } else { + DateTime dt = parseDateTime(userTyped); + if (dt == null) { + errorMessage("Input is not a valid DateTime"); + return fillInputDateTimeWithBundle(input, reader, bundle); + } + + input.setValue(dt); + } + + return true; + } + + /** * Load user input for list type. * * This implementation will load one element at a time. If user did not
