diff --git a/common/src/main/java/org/apache/sqoop/model/ConfigurationClass.java b/common/src/main/java/org/apache/sqoop/model/ConfigurationClass.java index 5a281466..5323bd99 100644 --- a/common/src/main/java/org/apache/sqoop/model/ConfigurationClass.java +++ b/common/src/main/java/org/apache/sqoop/model/ConfigurationClass.java @@ -17,14 +17,25 @@ */ package org.apache.sqoop.model; +import org.apache.sqoop.validation.validators.Validator; + +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * Class annotation. Each class that is used a configuration object where user * is expected to provide input need to have this annotation. */ @Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) public @interface ConfigurationClass { + /** + * List of validators associated with this Configuration class. + * + * @return + */ + Class[] validators() default {}; } diff --git a/common/src/main/java/org/apache/sqoop/model/FormClass.java b/common/src/main/java/org/apache/sqoop/model/FormClass.java index d510ca02..48bff3c5 100644 --- a/common/src/main/java/org/apache/sqoop/model/FormClass.java +++ b/common/src/main/java/org/apache/sqoop/model/FormClass.java @@ -17,13 +17,18 @@ */ package org.apache.sqoop.model; +import org.apache.sqoop.validation.validators.Validator; + +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * Denote configuration class */ @Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) public @interface FormClass { /** @@ -32,4 +37,11 @@ * @return */ short defaultSize() default -1; + + /** + * List of validators associated with this form. + * + * @return + */ + Class[] validators() default {}; } diff --git a/common/src/main/java/org/apache/sqoop/model/Input.java b/common/src/main/java/org/apache/sqoop/model/Input.java index 6df2b9f5..61fc01aa 100644 --- a/common/src/main/java/org/apache/sqoop/model/Input.java +++ b/common/src/main/java/org/apache/sqoop/model/Input.java @@ -17,14 +17,19 @@ */ package org.apache.sqoop.model; +import org.apache.sqoop.validation.validators.Validator; + +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * Field annotation. Each field that user might change in configuration object * need to have this annotation. */ @Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) public @interface Input { /** * Sqoop framework will ensure that sensitive information will not be easily @@ -40,4 +45,11 @@ * @return Maximal length */ short size() default -1; + + /** + * List of validators associated with this input. + * + * @return + */ + Class[] validators() default {}; } diff --git a/common/src/main/java/org/apache/sqoop/validation/Message.java b/common/src/main/java/org/apache/sqoop/validation/Message.java new file mode 100644 index 00000000..cb55b6a0 --- /dev/null +++ b/common/src/main/java/org/apache/sqoop/validation/Message.java @@ -0,0 +1,68 @@ +/** + * 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.validation; + +/** + * Validation message. + * + * Validation message have always two parts - severity and textual information about what + * is wrong. It can be associated with Input, Form or Configuration class. + */ +public class Message { + private Status status; + private String message; + + public Message(Status status, String message) { + this.status = status; + this.message = message; + } + + public Status getStatus() { + return status; + } + + public String getMessage() { + return message; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Message)) return false; + + Message message1 = (Message) o; + + if (message != null ? !message.equals(message1.message) : message1.message != null) + return false; + if (status != message1.status) return false; + + return true; + } + + @Override + public int hashCode() { + int result = status != null ? status.hashCode() : 0; + result = 31 * result + (message != null ? message.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "{" + status.name() + ": " + message + "}"; + } +} diff --git a/common/src/main/java/org/apache/sqoop/validation/Status.java b/common/src/main/java/org/apache/sqoop/validation/Status.java index c6f25f0c..ae89e594 100644 --- a/common/src/main/java/org/apache/sqoop/validation/Status.java +++ b/common/src/main/java/org/apache/sqoop/validation/Status.java @@ -19,24 +19,26 @@ /** * Status modes of a validation process. + * + * TODO: This should really be renamed to "severity" */ public enum Status { /** * There are no issues, no warnings. Everything is correct. */ - FINE, + FINE, // TODO: Rename to "OK" /** * Validated entity is correct enough to be processed. There might be some * warnings, but no errors. */ - ACCEPTABLE, + ACCEPTABLE, // TODO: Rename to "WARNING" /** * There are serious issues with validated entity. We can't proceed until * reported issues will be resolved. */ - UNACCEPTABLE, + UNACCEPTABLE, // TODO: Rename to "ERROR" ; diff --git a/common/src/main/java/org/apache/sqoop/validation/validators/ClassAvailable.java b/common/src/main/java/org/apache/sqoop/validation/validators/ClassAvailable.java new file mode 100644 index 00000000..2adfe6c8 --- /dev/null +++ b/common/src/main/java/org/apache/sqoop/validation/validators/ClassAvailable.java @@ -0,0 +1,35 @@ +/** + * 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.validation.validators; + +import org.apache.sqoop.validation.Message; +import org.apache.sqoop.validation.Status; + +/** + * Ensure that given String Input is a class that is available to this JVM. + */ +public class ClassAvailable extends Validator { + @Override + public void validate(String klass) { + try { + Class.forName(klass); + } catch (ClassNotFoundException e) { + addMessage(new Message(Status.UNACCEPTABLE, "Class not found")); + } + } +} diff --git a/common/src/main/java/org/apache/sqoop/validation/validators/NotEmpty.java b/common/src/main/java/org/apache/sqoop/validation/validators/NotEmpty.java new file mode 100644 index 00000000..520beea3 --- /dev/null +++ b/common/src/main/java/org/apache/sqoop/validation/validators/NotEmpty.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.sqoop.validation.validators; + +import org.apache.sqoop.validation.Status; + +/** + * Ensure that given String is not empty. + * + * Will also ensure that the string is not null. + */ +public class NotEmpty extends Validator { + @Override + public void validate(String instance) { + if (instance == null || instance.isEmpty()) { + addMessage(Status.UNACCEPTABLE, "Can't be null nor empty"); + } + } +} diff --git a/common/src/main/java/org/apache/sqoop/validation/validators/NotNull.java b/common/src/main/java/org/apache/sqoop/validation/validators/NotNull.java new file mode 100644 index 00000000..fb8a9267 --- /dev/null +++ b/common/src/main/java/org/apache/sqoop/validation/validators/NotNull.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.sqoop.validation.validators; + +import org.apache.sqoop.validation.Status; + +/** + * Ensure that given object is never null. + */ +public class NotNull extends Validator { + @Override + public void validate(T instance) { + if (instance == null) { + addMessage(Status.UNACCEPTABLE, "Can't be null"); + } + } +} diff --git a/common/src/main/java/org/apache/sqoop/validation/validators/Validator.java b/common/src/main/java/org/apache/sqoop/validation/validators/Validator.java new file mode 100644 index 00000000..5c24b1ad --- /dev/null +++ b/common/src/main/java/org/apache/sqoop/validation/validators/Validator.java @@ -0,0 +1,69 @@ +/** + * 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.validation.validators; + +import org.apache.sqoop.validation.Message; +import org.apache.sqoop.validation.Status; + +import java.util.LinkedList; +import java.util.List; + +/** + * Abstract validator class. + * + * Can be used to validate inputs, forms and configuration classes. + */ +abstract public class Validator { + + /** + * Validation check. + * + * To be implemented by our children. + * + * @param instance Object to validate (depending on what we are validating) + */ + abstract public void validate(T instance); + + /** + * Messages generated during validation. + */ + private List messages; + + public Validator() { + reset(); + } + + protected void addMessage(Message msg) { + messages.add(msg); + } + + protected void addMessage(Status status, String msg) { + messages.add(new Message(status, msg)); + } + + public List getMessages() { + return messages; + } + + /** + * Reset validator state (all previous messages). + */ + public void reset() { + messages = new LinkedList(); + } +} diff --git a/common/src/test/java/org/apache/sqoop/validation/validators/TestClassAvailable.java b/common/src/test/java/org/apache/sqoop/validation/validators/TestClassAvailable.java new file mode 100644 index 00000000..511b3b4a --- /dev/null +++ b/common/src/test/java/org/apache/sqoop/validation/validators/TestClassAvailable.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.sqoop.validation.validators; + +import org.apache.sqoop.validation.Message; +import org.apache.sqoop.validation.Status; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +/** + */ +public class TestClassAvailable { + + Validator validator = new ClassAvailable(); + + @Test + public void test() { + List messages; + assertEquals(0, validator.getMessages().size()); + + validator.validate(ClassAvailable.class.getCanonicalName()); + assertEquals(0, validator.getMessages().size()); + + validator.validate("java.lang.String"); + assertEquals(0, validator.getMessages().size()); + + validator.validate("net.jarcec.super.private.project.Main"); + assertEquals(1, validator.getMessages().size()); + messages = validator.getMessages(); + assertEquals(Status.UNACCEPTABLE, messages.get(0).getStatus()); + } +} diff --git a/common/src/test/java/org/apache/sqoop/validation/validators/TestNotEmpty.java b/common/src/test/java/org/apache/sqoop/validation/validators/TestNotEmpty.java new file mode 100644 index 00000000..d225b063 --- /dev/null +++ b/common/src/test/java/org/apache/sqoop/validation/validators/TestNotEmpty.java @@ -0,0 +1,55 @@ +/** + * 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.validation.validators; + +import org.apache.sqoop.validation.Message; +import org.apache.sqoop.validation.Status; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +/** + */ +public class TestNotEmpty { + + Validator validator = new NotEmpty(); + + @Test + public void test() { + List messages; + assertEquals(0, validator.getMessages().size()); + + validator.validate("Non empty"); + assertEquals(0, validator.getMessages().size()); + + validator.validate(""); + assertEquals(1, validator.getMessages().size()); + messages = validator.getMessages(); + assertEquals(Status.UNACCEPTABLE, messages.get(0).getStatus()); + + validator.reset(); + assertEquals(0, validator.getMessages().size()); + + validator.validate(null); + assertEquals(1, validator.getMessages().size()); + messages = validator.getMessages(); + assertEquals(Status.UNACCEPTABLE, messages.get(0).getStatus()); + } +} diff --git a/common/src/test/java/org/apache/sqoop/validation/validators/TestNotNull.java b/common/src/test/java/org/apache/sqoop/validation/validators/TestNotNull.java new file mode 100644 index 00000000..9c5bed53 --- /dev/null +++ b/common/src/test/java/org/apache/sqoop/validation/validators/TestNotNull.java @@ -0,0 +1,51 @@ +/** + * 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.validation.validators; + +import org.apache.sqoop.validation.Message; +import org.apache.sqoop.validation.Status; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +/** + */ +public class TestNotNull { + + Validator validator = new NotNull(); + + @Test + public void test() { + assertEquals(0, validator.getMessages().size()); + + validator.validate(""); + assertEquals(0, validator.getMessages().size()); + + validator.validate("Non empty"); + assertEquals(0, validator.getMessages().size()); + + validator.validate(null); + assertEquals(1, validator.getMessages().size()); + + List messages = validator.getMessages(); + Message msg = messages.get(0); + assertEquals(Status.UNACCEPTABLE, msg.getStatus()); + } +} diff --git a/common/src/test/java/org/apache/sqoop/validation/validators/TestValidator.java b/common/src/test/java/org/apache/sqoop/validation/validators/TestValidator.java new file mode 100644 index 00000000..1a5dbddb --- /dev/null +++ b/common/src/test/java/org/apache/sqoop/validation/validators/TestValidator.java @@ -0,0 +1,57 @@ +/** + * 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.validation.validators; + +import org.apache.sqoop.validation.Message; +import org.apache.sqoop.validation.Status; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * + */ +public class TestValidator { + public static class ValidatorImpl extends Validator { + @Override + public void validate(String msg) { + addMessage(Status.FINE, msg); + addMessage(new Message(Status.UNACCEPTABLE, "Prefix: " + msg)); + } + } + + @Test + public void test() { + ValidatorImpl validator = new ValidatorImpl(); + + assertEquals(0, validator.getMessages().size()); + validator.validate("X"); + assertEquals(2, validator.getMessages().size()); + + Message msg = validator.getMessages().get(0); + assertEquals(Status.FINE, msg.getStatus()); + assertEquals("X", msg.getMessage()); + + msg = validator.getMessages().get(1); + assertEquals(Status.UNACCEPTABLE, msg.getStatus()); + assertEquals("Prefix: X", msg.getMessage()); + + validator.reset(); + assertEquals(0, validator.getMessages().size()); + } +} diff --git a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/ConnectionForm.java b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/ConnectionForm.java index c3544946..e5137707 100644 --- a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/ConnectionForm.java +++ b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/ConnectionForm.java @@ -19,17 +19,44 @@ import org.apache.sqoop.model.FormClass; import org.apache.sqoop.model.Input; +import org.apache.sqoop.validation.Status; +import org.apache.sqoop.validation.validators.NotEmpty; +import org.apache.sqoop.validation.validators.Validator; +import org.apache.sqoop.validation.validators.ClassAvailable; +import java.sql.DriverManager; +import java.sql.SQLException; import java.util.Map; /** * */ -@FormClass +@FormClass(validators = {ConnectionForm.FormValidator.class}) public class ConnectionForm { - @Input(size = 128) public String jdbcDriver; - @Input(size = 128) public String connectionString; - @Input(size = 40) public String username; - @Input(size = 40, sensitive = true) public String password; - @Input public Map jdbcProperties; + @Input(size = 128, validators = {NotEmpty.class, ClassAvailable.class} ) + public String jdbcDriver; + + @Input(size = 128, validators = {NotEmpty.class} ) + public String connectionString; + + @Input(size = 40) + public String username; + + @Input(size = 40, sensitive = true) + public String password; + + @Input + public Map jdbcProperties; + + public static class FormValidator extends Validator { + @Override + public void validate(ConnectionForm form) { + // See if we can connect to the database + try { + DriverManager.getConnection(form.connectionString, form.username, form.password); + } catch (SQLException e) { + addMessage(Status.ACCEPTABLE, "Can't connect to the database with given credentials: " + e.getMessage()); + } + } + } } diff --git a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/FromTableForm.java b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/FromTableForm.java index 8f6fb60e..1c0b4293 100644 --- a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/FromTableForm.java +++ b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/FromTableForm.java @@ -17,19 +17,59 @@ */ package org.apache.sqoop.connector.jdbc.configuration; +import org.apache.sqoop.connector.jdbc.GenericJdbcConnectorConstants; import org.apache.sqoop.model.FormClass; import org.apache.sqoop.model.Input; +import org.apache.sqoop.validation.Status; +import org.apache.sqoop.validation.validators.Validator; /** * */ -@FormClass +@FormClass( validators = {FromTableForm.FormValidator.class}) public class FromTableForm { - @Input(size = 50) public String schemaName; - @Input(size = 50) public String tableName; - @Input(size = 2000) public String sql; - @Input(size = 50) public String columns; - @Input(size = 50) public String partitionColumn; - @Input public Boolean partitionColumnNull; - @Input(size = 50) public String boundaryQuery; + @Input(size = 50) + public String schemaName; + + @Input(size = 50) + public String tableName; + + @Input(size = 2000, validators = {SqlConditionTokenValidator.class}) + public String sql; + + @Input(size = 50) + public String columns; + + @Input(size = 50) + public String partitionColumn; + + @Input + public Boolean partitionColumnNull; + + @Input(size = 50) + public String boundaryQuery; + + public static class FormValidator extends Validator { + @Override + public void validate(FromTableForm form) { + if(form.tableName == null && form.sql == null) { + addMessage(Status.UNACCEPTABLE, "Either fromTable name or SQL must be specified"); + } + if(form.tableName != null && form.sql != null) { + addMessage(Status.UNACCEPTABLE, "Both fromTable name and SQL cannot be specified"); + } + if(form.schemaName != null && form.sql != null) { + addMessage(Status.UNACCEPTABLE, "Both schema name and SQL cannot be specified"); + } + } + } + + public static class SqlConditionTokenValidator extends Validator { + @Override + public void validate(String sql) { + if(sql != null && !sql.contains(GenericJdbcConnectorConstants.SQL_CONDITIONS_TOKEN)) { + addMessage(Status.UNACCEPTABLE, "SQL statement must contain placeholder for auto generated conditions - " + GenericJdbcConnectorConstants.SQL_CONDITIONS_TOKEN); + } + } + } } diff --git a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/ToTableForm.java b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/ToTableForm.java index dca0bf94..0601a398 100644 --- a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/ToTableForm.java +++ b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/configuration/ToTableForm.java @@ -19,11 +19,13 @@ import org.apache.sqoop.model.FormClass; import org.apache.sqoop.model.Input; +import org.apache.sqoop.validation.Status; +import org.apache.sqoop.validation.validators.Validator; /** * */ -@FormClass +@FormClass(validators = {ToTableForm.FormValidator.class}) public class ToTableForm { @Input(size = 50) public String schemaName; @Input(size = 2000) public String tableName; @@ -31,4 +33,22 @@ public class ToTableForm { @Input(size = 50) public String columns; @Input(size = 2000) public String stageTableName; @Input public Boolean clearStageTable; + + public static class FormValidator extends Validator { + @Override + public void validate(ToTableForm form) { + if(form.tableName == null && form.sql == null) { + addMessage(Status.UNACCEPTABLE, "Either fromTable name or SQL must be specified"); + } + if(form.tableName != null && form.sql != null) { + addMessage(Status.UNACCEPTABLE, "Both fromTable name and SQL cannot be specified"); + } + if(form.tableName == null && form.stageTableName != null) { + addMessage(Status.UNACCEPTABLE, "Stage fromTable name cannot be specified without specifying fromTable name"); + } + if(form.stageTableName == null && form.clearStageTable != null) { + addMessage(Status.UNACCEPTABLE, "Clear stage fromTable cannot be specified without specifying name of the stage fromTable."); + } + } + } }