You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sqoop.apache.org by ab...@apache.org on 2014/10/10 04:52:15 UTC
[46/52] [abbrv] SQOOP-1498: Sqoop2: Repository Object refactoring
(objects prefixed with M)
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MConnector.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MConnector.java b/common/src/main/java/org/apache/sqoop/model/MConnector.java
index 7999b08..2f42191 100644
--- a/common/src/main/java/org/apache/sqoop/model/MConnector.java
+++ b/common/src/main/java/org/apache/sqoop/model/MConnector.java
@@ -23,28 +23,27 @@ import org.apache.sqoop.common.SqoopException;
import org.apache.sqoop.common.SupportedDirections;
/**
- * Connector metadata.
- *
- * Includes unique id that identifies connector in metadata store, unique human
- * readable name, corresponding name and all forms for all supported job types.
+ * Connector entity supports the FROM/TO {@link Transferable} Includes unique id
+ * that identifies connector in the repository, unique human readable name,
+ * corresponding name and all configs to support the from and to data sources
*/
public final class MConnector extends MPersistableEntity implements MClonable {
private final String uniqueName;
private final String className;
- private final MConnectionForms connectionForms;
- private final MJobForms fromJobForms;
- private final MJobForms toJobForms;
- String version;
-
- public MConnector(String uniqueName, String className,
- String version, MConnectionForms connectionForms,
- MJobForms fromJobForms, MJobForms toJobForms) {
+ private final String version;
+ private final MLinkConfig linkConfig;
+ private final MFromConfig fromConfig;
+ private final MToConfig toConfig;
+
+ public MConnector(String uniqueName, String className, String version, MLinkConfig linkConfig,
+ MFromConfig fromConfig, MToConfig toConfig) {
this.version = version;
- this.connectionForms = connectionForms;
- this.fromJobForms = fromJobForms;
- this.toJobForms = toJobForms;
+ this.linkConfig = linkConfig;
+ this.fromConfig = fromConfig;
+ this.toConfig = toConfig;
+ // Why are we abusing NPE?
if (uniqueName == null || className == null) {
throw new NullPointerException();
}
@@ -63,17 +62,15 @@ public final class MConnector extends MPersistableEntity implements MClonable {
@Override
public String toString() {
- MJobForms fromJobForms = this.getJobForms(Direction.FROM);
- MJobForms toJobForms = this.getJobForms(Direction.TO);
StringBuilder sb = new StringBuilder("connector-");
sb.append(uniqueName).append(":").append(getPersistenceId()).append(":");
sb.append(className);
- sb.append(", ").append(getConnectionForms().toString());
- if (fromJobForms != null) {
- sb.append(", ").append(fromJobForms.toString());
+ sb.append(", ").append(getLinkConfig().toString());
+ if (getConfig(Direction.FROM) != null) {
+ sb.append(", ").append(getConfig(Direction.FROM).toString());
}
- if (toJobForms != null) {
- sb.append(", ").append(toJobForms.toString());
+ if (getConfig(Direction.TO) != null) {
+ sb.append(", ").append(getConfig(Direction.TO).toString());
}
return sb.toString();
}
@@ -94,41 +91,39 @@ public final class MConnector extends MPersistableEntity implements MClonable {
if (supportedDirections.isDirectionSupported(Direction.FROM)
&& mcSupportedDirections.isDirectionSupported(Direction.FROM)
- && !getJobForms(Direction.FROM).equals(mc.getJobForms(Direction.FROM))) {
+ && !getFromConfig().equals(mc.getFromConfig())) {
return false;
}
- if (supportedDirections.isDirectionSupported(Direction.FROM)
- != mcSupportedDirections.isDirectionSupported(Direction.FROM)) {
+ if (supportedDirections.isDirectionSupported(Direction.FROM) != mcSupportedDirections
+ .isDirectionSupported(Direction.FROM)) {
return false;
}
if (supportedDirections.isDirectionSupported(Direction.TO)
&& mcSupportedDirections.isDirectionSupported(Direction.TO)
- && !getJobForms(Direction.TO).equals(mc.getJobForms(Direction.TO))) {
+ && !getToConfig().equals(mc.getToConfig())) {
return false;
}
- if (supportedDirections.isDirectionSupported(Direction.TO)
- != mcSupportedDirections.isDirectionSupported(Direction.TO)) {
+ if (supportedDirections.isDirectionSupported(Direction.TO) != mcSupportedDirections
+ .isDirectionSupported(Direction.TO)) {
return false;
}
- return uniqueName.equals(mc.uniqueName)
- && className.equals(mc.className)
- && version.equals(mc.version)
- && connectionForms.equals(mc.getConnectionForms());
+ return uniqueName.equals(mc.uniqueName) && className.equals(mc.className)
+ && version.equals(mc.version) && linkConfig.equals((mc.getLinkConfig()));
}
@Override
public int hashCode() {
SupportedDirections supportedDirections = getSupportedDirections();
- int result = getConnectionForms().hashCode();
+ int result = getLinkConfig().hashCode();
if (supportedDirections.isDirectionSupported(Direction.FROM)) {
- result = 31 * result + getJobForms(Direction.FROM).hashCode();
+ result = 31 * result + getFromConfig().hashCode();
}
if (supportedDirections.isDirectionSupported(Direction.TO)) {
- result = 31 * result + getJobForms(Direction.TO).hashCode();
+ result = 31 * result + getToConfig().hashCode();
}
result = 31 * result + version.hashCode();
result = 31 * result + uniqueName.hashCode();
@@ -137,58 +132,57 @@ public final class MConnector extends MPersistableEntity implements MClonable {
}
public MConnector clone(boolean cloneWithValue) {
- //Connector never have any values filled
+ // Connector never have any values filled
cloneWithValue = false;
- MJobForms fromJobForms = this.getJobForms(Direction.FROM);
- MJobForms toJobForms = this.getJobForms(Direction.TO);
+ MFromConfig fromConfig = this.getFromConfig();
+ MToConfig toConfig = this.getToConfig();
- if (fromJobForms != null) {
- fromJobForms = fromJobForms.clone(cloneWithValue);
+ if (fromConfig != null) {
+ fromConfig = fromConfig.clone(cloneWithValue);
}
- if (toJobForms != null) {
- toJobForms = toJobForms.clone(cloneWithValue);
+ if (toConfig != null) {
+ toConfig = toConfig.clone(cloneWithValue);
}
- MConnector copy = new MConnector(
- this.getUniqueName(),
- this.getClassName(),
- this.getVersion(),
- this.getConnectionForms().clone(cloneWithValue),
- fromJobForms,
- toJobForms);
+ MConnector copy = new MConnector(this.getUniqueName(), this.getClassName(), this.getVersion(),
+ this.getLinkConfig().clone(cloneWithValue), fromConfig, toConfig);
copy.setPersistenceId(this.getPersistenceId());
return copy;
}
- public MConnectionForms getConnectionForms() {
- return connectionForms;
+ public MLinkConfig getLinkConfig() {
+ return linkConfig;
}
- public MJobForms getJobForms(Direction type) {
- switch(type) {
- case FROM:
- return fromJobForms;
+ public MConfigList getConfig(Direction type) {
+ switch (type) {
+ case FROM:
+ return fromConfig;
- case TO:
- return toJobForms;
+ case TO:
+ return toConfig;
- default:
- throw new SqoopException(DirectionError.DIRECTION_0000, "Direction: " + type);
+ default:
+ throw new SqoopException(DirectionError.DIRECTION_0000, "Direction: " + type);
}
}
- public String getVersion() {
- return version;
+ public MFromConfig getFromConfig() {
+ return fromConfig;
}
- public void setVersion(String version) {
- this.version = version;
+ public MToConfig getToConfig() {
+ return toConfig;
+ }
+
+ public String getVersion() {
+ return version;
}
public SupportedDirections getSupportedDirections() {
- return new SupportedDirections(this.getJobForms(Direction.FROM) != null,
- this.getJobForms(Direction.TO) != null);
+ return new SupportedDirections(this.getConfig(Direction.FROM) != null,
+ this.getConfig(Direction.TO) != null);
}
}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MDriver.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MDriver.java b/common/src/main/java/org/apache/sqoop/model/MDriver.java
new file mode 100644
index 0000000..685439e
--- /dev/null
+++ b/common/src/main/java/org/apache/sqoop/model/MDriver.java
@@ -0,0 +1,82 @@
+/**
+ * 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 java.sql.Driver;
+
+/**
+ * Describes the configs associated with the {@link Driver} for executing sqoop jobs.
+ */
+public class MDriver extends MPersistableEntity implements MClonable {
+
+ private final MDriverConfig driverConfig;
+ private final String version;
+
+ public MDriver(MDriverConfig driverConfig, String version) {
+ this.driverConfig = driverConfig;
+ this.version = version;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("driver-");
+ sb.append(getPersistenceId()).append(":");
+ sb.append("version = " + version);
+ sb.append(", ").append(driverConfig.toString());
+
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof MDriver)) {
+ return false;
+ }
+
+ MDriver driver = (MDriver) other;
+ return version.equals(driver.getVersion()) &&
+ driverConfig.equals(driver.driverConfig);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = driverConfig.hashCode();
+ result = 31 * result + version.hashCode();
+ return result;
+ }
+
+ public MDriverConfig getDriverConfig() {
+ return driverConfig;
+ }
+
+ @Override
+ public MDriver clone(boolean cloneWithValue) {
+ cloneWithValue = false;
+ MDriver copy = new MDriver(this.driverConfig.clone(cloneWithValue), this.version);
+ copy.setPersistenceId(this.getPersistenceId());
+ return copy;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MDriverConfig.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MDriverConfig.java b/common/src/main/java/org/apache/sqoop/model/MDriverConfig.java
index 62eb197..679859a 100644
--- a/common/src/main/java/org/apache/sqoop/model/MDriverConfig.java
+++ b/common/src/main/java/org/apache/sqoop/model/MDriverConfig.java
@@ -17,29 +17,23 @@
*/
package org.apache.sqoop.model;
-/**
- * Describes the configs associated with the {@link Driver} for executing sqoop jobs.
- */
-public class MDriverConfig extends MPersistableEntity implements MClonable {
+import java.util.List;
- private final MConnectionForms connectionForms;
- private final MJobForms jobForms;
- String version;
+/**
+ * Config describing all required information for the driver
+ * NOTE: It extends a config list since {@link MToConfig} could consist of a related config groups
+ * In future this could be simplified to hold a single list of all configs for the driver
- public MDriverConfig(MConnectionForms connectionForms, MJobForms jobForms, String version) {
- this.connectionForms = connectionForms;
- this.jobForms = jobForms;
- this.version = version;
+ */
+public class MDriverConfig extends MConfigList {
+ public MDriverConfig(List<MConfig> configs) {
+ super(configs);
}
@Override
public String toString() {
- StringBuilder sb = new StringBuilder("driver-");
- sb.append(getPersistenceId()).append(":");
- sb.append("version = " + version);
- sb.append(", ").append(connectionForms.toString());
- sb.append(jobForms.toString());
-
+ StringBuilder sb = new StringBuilder("Driver:");
+ sb.append(super.toString());
return sb.toString();
}
@@ -53,45 +47,18 @@ public class MDriverConfig extends MPersistableEntity implements MClonable {
return false;
}
- MDriverConfig mo = (MDriverConfig) other;
- return version.equals(mo.getVersion()) &&
- connectionForms.equals(mo.connectionForms) &&
- jobForms.equals(mo.jobForms);
+ MDriverConfig mDriver = (MDriverConfig) other;
+ return super.equals(mDriver);
}
@Override
public int hashCode() {
- int result = connectionForms.hashCode();
- result = 31 * result + jobForms.hashCode();
- result = 31 * result + version.hashCode();
- return result;
- }
-
- public MConnectionForms getConnectionForms() {
- return connectionForms;
- }
-
- public MJobForms getJobForms() {
- return jobForms;
+ return super.hashCode();
}
@Override
public MDriverConfig clone(boolean cloneWithValue) {
- //Framework never have any values filled
- cloneWithValue = false;
- MDriverConfig copy = new MDriverConfig(this.getConnectionForms().clone(cloneWithValue),
- this.getJobForms().clone(cloneWithValue), this.version);
- copy.setPersistenceId(this.getPersistenceId());
+ MDriverConfig copy = new MDriverConfig(super.clone(cloneWithValue).getConfigs());
return copy;
}
-
- public String getVersion() {
- return version;
- }
-
- public void setVersion(String version) {
- this.version = version;
- }
-
-}
-
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MForm.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MForm.java b/common/src/main/java/org/apache/sqoop/model/MForm.java
deleted file mode 100644
index ff94660..0000000
--- a/common/src/main/java/org/apache/sqoop/model/MForm.java
+++ /dev/null
@@ -1,117 +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.sqoop.model;
-
-import org.apache.sqoop.common.SqoopException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Represents a group of inputs that are processed together. This allows the
- * input gathering process to be broken down into multiple steps that can be
- * then paged through by the user interface.
- */
-public final class MForm extends MValidatedElement implements MClonable {
-
- private final List<MInput<?>> inputs;
-
- public MForm(String name, List<MInput<?>> inputs) {
- super(name);
-
- this.inputs = inputs;
- }
-
- public List<MInput<?>> getInputs() {
- return inputs;
- }
-
- public MInput<?> getInput(String inputName) {
- for(MInput<?> input: inputs) {
- if(inputName.equals(input.getName())) {
- return input;
- }
- }
-
- throw new SqoopException(ModelError.MODEL_011, "Input name: " + inputName);
- }
-
- public MStringInput getStringInput(String inputName) {
- return (MStringInput)getInput(inputName);
- }
-
- public MEnumInput getEnumInput(String inputName) {
- return (MEnumInput)getInput(inputName);
- }
-
- public MIntegerInput getIntegerInput(String inputName) {
- return (MIntegerInput)getInput(inputName);
- }
-
- public MBooleanInput getBooleanInput(String inputName) {
- return (MBooleanInput)getInput(inputName);
- }
-
- public MMapInput getMapInput(String inputName) {
- return (MMapInput)getInput(inputName);
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("form-").append(getName());
- sb.append(":").append(getPersistenceId()).append(":").append(inputs);
-
- return sb.toString();
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- if (!(other instanceof MForm)) {
- return false;
- }
-
- MForm mf = (MForm) other;
- return getName().equals(mf.getName())
- && inputs.equals(mf.inputs);
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + getName().hashCode();
- for (MInput<?> mi : inputs) {
- result = 31 * result + mi.hashCode();
- }
-
- return result;
- }
-
- @Override
- public MForm clone(boolean cloneWithValue) {
- List<MInput<?>> copyInputs = new ArrayList<MInput<?>>();
- for(MInput<?> itr : this.getInputs()) {
- copyInputs.add((MInput<?>)itr.clone(cloneWithValue));
- }
- MForm copyForm = new MForm(this.getName(), copyInputs);
- return copyForm;
- }
-}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MFormList.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MFormList.java b/common/src/main/java/org/apache/sqoop/model/MFormList.java
deleted file mode 100644
index 9130ada..0000000
--- a/common/src/main/java/org/apache/sqoop/model/MFormList.java
+++ /dev/null
@@ -1,124 +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.sqoop.model;
-
-import org.apache.sqoop.common.SqoopException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Arbitrary list of forms.
- */
-public class MFormList implements MClonable {
-
- private final List<MForm> forms;
-
- public MFormList(List<MForm> forms) {
- this.forms = forms;
- }
-
- public List<MForm> getForms() {
- return forms;
- }
-
- public MForm getForm(String formName) {
- for(MForm form: forms) {
- if(formName.equals(form.getName())) {
- return form;
- }
- }
-
- throw new SqoopException(ModelError.MODEL_010, "Form name: " + formName);
- }
-
- public MInput getInput(String name) {
- String []parts = name.split("\\.");
- if(parts.length != 2) {
- throw new SqoopException(ModelError.MODEL_009, name);
- }
-
- return getForm(parts[0]).getInput(name);
- }
-
- public MStringInput getStringInput(String name) {
- return (MStringInput)getInput(name);
- }
-
- public MEnumInput getEnumInput(String name) {
- return (MEnumInput)getInput(name);
- }
-
- public MIntegerInput getIntegerInput(String name) {
- return (MIntegerInput)getInput(name);
- }
-
- public MMapInput getMapInput(String name) {
- return (MMapInput)getInput(name);
- }
-
- public MBooleanInput getBooleanInput(String name) {
- return (MBooleanInput)getInput(name);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof MFormList)) return false;
-
- MFormList mFormList = (MFormList) o;
-
- if (!forms.equals(mFormList.forms)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- for(MForm form : forms) {
- result = 31 * result + form.hashCode();
- }
-
- return result;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("Forms: ");
- for(MForm form : forms) {
- sb.append(form.toString());
- }
- return sb.toString();
- }
-
- @Override
- public MFormList clone(boolean cloneWithValue) {
- List<MForm> copyForms = null;
- if(this.getForms() != null) {
- copyForms = new ArrayList<MForm>();
- for(MForm itr : this.getForms()) {
- MForm newForm = itr.clone(cloneWithValue);
- newForm.setPersistenceId(itr.getPersistenceId());
- copyForms.add(newForm);
- }
- }
- MFormList copyFormList = new MFormList(copyForms);
- return copyFormList;
- }
-}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MFormType.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MFormType.java b/common/src/main/java/org/apache/sqoop/model/MFormType.java
deleted file mode 100644
index 2f403df..0000000
--- a/common/src/main/java/org/apache/sqoop/model/MFormType.java
+++ /dev/null
@@ -1,34 +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.sqoop.model;
-
-/**
- * Represents the various form types supported by the system.
- */
-public enum MFormType {
-
- /** Unknown form type */
- OTHER,
-
- /** Connection form type */
- CONNECTION,
-
- /** Job form type */
- JOB;
-
-}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MFromConfig.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MFromConfig.java b/common/src/main/java/org/apache/sqoop/model/MFromConfig.java
new file mode 100644
index 0000000..1b450d6
--- /dev/null
+++ b/common/src/main/java/org/apache/sqoop/model/MFromConfig.java
@@ -0,0 +1,64 @@
+/**
+ * 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 java.util.List;
+
+/**
+ * Config describing all required information to build the FROM part of the job
+ * NOTE: It extends a config list since {@link MFromConfig} could consist of a related config groups
+ * In future this could be simplified to hold a single list of all configs for the FROM object
+
+ */
+public class MFromConfig extends MConfigList {
+ public MFromConfig(List<MConfig> configs) {
+ super(configs);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("From: ");
+ sb.append(super.toString());
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof MFromConfig)) {
+ return false;
+ }
+
+ MFromConfig mj = (MFromConfig) other;
+ return super.equals(mj);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ @Override
+ public MFromConfig clone(boolean cloneWithValue) {
+ MFromConfig copy = new MFromConfig(super.clone(cloneWithValue).getConfigs());
+ return copy;
+ }
+}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MJob.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MJob.java b/common/src/main/java/org/apache/sqoop/model/MJob.java
index c9b45a5..b3dec27 100644
--- a/common/src/main/java/org/apache/sqoop/model/MJob.java
+++ b/common/src/main/java/org/apache/sqoop/model/MJob.java
@@ -22,29 +22,23 @@ import org.apache.sqoop.common.DirectionError;
import org.apache.sqoop.common.SqoopException;
/**
- * Model describing entire job object including both connector and
- * framework part.
+ * Model describing entire job object including the from/to and driver config information
+ * to execute the job
*/
public class MJob extends MAccountableEntity implements MClonable {
/**
- * Connector reference.
- *
- * Job object do not immediately depend on connector as there is indirect
+ * NOTE : Job object do not immediately depend on connector as there is indirect
* dependency through link object, but having this dependency explicitly
- * carried along helps a lot.
+ * carried along helps with not having to make the DB call everytime
*/
private final long fromConnectorId;
private final long toConnectorId;
-
- /**
- * Corresponding link objects for connector.
- */
private final long fromLinkId;
private final long toLinkId;
- private final MJobForms fromConnectorPart;
- private final MJobForms toConnectorPart;
- private final MJobForms frameworkPart;
+ private final MFromConfig fromConfig;
+ private final MToConfig toConfig;
+ private final MDriverConfig driverConfig;
/**
* Default constructor to build new MJob model.
@@ -53,24 +47,24 @@ public class MJob extends MAccountableEntity implements MClonable {
* @param toConnectorId TO Connector id
* @param fromLinkId FROM Link id
* @param toLinkId TO Link id
- * @param fromPart FROM Connector forms
- * @param toPart TO Connector forms
- * @param frameworkPart Framework forms
+ * @param fromConfig FROM job config
+ * @param toConfig TO job config
+ * @param driverConfig driver config
*/
public MJob(long fromConnectorId,
long toConnectorId,
- long fromConnectionId,
- long toConnectionId,
- MJobForms fromPart,
- MJobForms toPart,
- MJobForms frameworkPart) {
+ long fromLinkId,
+ long toLinkId,
+ MFromConfig fromConfig,
+ MToConfig toConfig,
+ MDriverConfig driverConfig) {
this.fromConnectorId = fromConnectorId;
this.toConnectorId = toConnectorId;
- this.fromLinkId = fromConnectionId;
- this.toLinkId = toConnectionId;
- this.fromConnectorPart = fromPart;
- this.toConnectorPart = toPart;
- this.frameworkPart = frameworkPart;
+ this.fromLinkId = fromLinkId;
+ this.toLinkId = toLinkId;
+ this.fromConfig = fromConfig;
+ this.toConfig = toConfig;
+ this.driverConfig = driverConfig;
}
/**
@@ -80,9 +74,9 @@ public class MJob extends MAccountableEntity implements MClonable {
*/
public MJob(MJob other) {
this(other,
- other.getConnectorPart(Direction.FROM).clone(true),
- other.getConnectorPart(Direction.TO).clone(true),
- other.frameworkPart.clone(true));
+ other.getFromJobConfig().clone(true),
+ other.getToJobConfig().clone(true),
+ other.driverConfig.clone(true));
}
/**
@@ -92,29 +86,29 @@ public class MJob extends MAccountableEntity implements MClonable {
* used otherwise.
*
* @param other MJob model to copy
- * @param fromPart FROM Connector forms
- * @param toPart TO Connector forms
- * @param frameworkPart Framework forms
+ * @param fromConfig FROM Job config
+ * @param toConfig TO Job config
+ * @param driverConfig driverConfig
*/
- public MJob(MJob other, MJobForms fromPart, MJobForms toPart, MJobForms frameworkPart) {
+ public MJob(MJob other, MFromConfig fromConfig, MToConfig toConfig, MDriverConfig driverConfig) {
super(other);
this.fromConnectorId = other.getConnectorId(Direction.FROM);
this.toConnectorId = other.getConnectorId(Direction.TO);
this.fromLinkId = other.getLinkId(Direction.FROM);
this.toLinkId = other.getLinkId(Direction.TO);
- this.fromConnectorPart = fromPart;
- this.toConnectorPart = toPart;
- this.frameworkPart = frameworkPart;
+ this.fromConfig = fromConfig;
+ this.toConfig = toConfig;
+ this.driverConfig = driverConfig;
this.setPersistenceId(other.getPersistenceId());
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("job");
- sb.append(" connector-from-part: ").append(getConnectorPart(Direction.FROM));
- sb.append(", connector-to-part: ").append(getConnectorPart(Direction.TO));
- sb.append(", framework-part: ").append(frameworkPart);
+ sb.append("From job config: ").append(getJobConfig(Direction.FROM));
+ sb.append(", To job config: ").append(getJobConfig(Direction.TO));
+ sb.append(", Driver config: ").append(driverConfig);
return sb.toString();
}
@@ -145,21 +139,29 @@ public class MJob extends MAccountableEntity implements MClonable {
}
}
- public MJobForms getConnectorPart(Direction type) {
+ public MConfigList getJobConfig(Direction type) {
switch(type) {
case FROM:
- return fromConnectorPart;
+ return fromConfig;
case TO:
- return toConnectorPart;
+ return toConfig;
default:
throw new SqoopException(DirectionError.DIRECTION_0000, "Direction: " + type);
}
}
- public MJobForms getFrameworkPart() {
- return frameworkPart;
+ public MFromConfig getFromJobConfig() {
+ return fromConfig;
+ }
+
+ public MToConfig getToJobConfig() {
+ return toConfig;
+ }
+
+ public MDriverConfig getDriverConfig() {
+ return driverConfig;
}
@Override
@@ -172,9 +174,9 @@ public class MJob extends MAccountableEntity implements MClonable {
getConnectorId(Direction.TO),
getLinkId(Direction.FROM),
getLinkId(Direction.TO),
- getConnectorPart(Direction.FROM).clone(false),
- getConnectorPart(Direction.TO).clone(false),
- frameworkPart.clone(false));
+ getFromJobConfig().clone(false),
+ getToJobConfig().clone(false),
+ getDriverConfig().clone(false));
}
}
@@ -194,8 +196,8 @@ public class MJob extends MAccountableEntity implements MClonable {
&& (job.getLinkId(Direction.FROM) == this.getLinkId(Direction.FROM))
&& (job.getLinkId(Direction.TO) == this.getLinkId(Direction.TO))
&& (job.getPersistenceId() == this.getPersistenceId())
- && (job.getConnectorPart(Direction.FROM).equals(this.getConnectorPart(Direction.FROM)))
- && (job.getConnectorPart(Direction.TO).equals(this.getConnectorPart(Direction.TO)))
- && (job.frameworkPart.equals(this.frameworkPart));
+ && (job.getFromJobConfig().equals(this.getJobConfig(Direction.FROM)))
+ && (job.getToJobConfig().equals(this.getJobConfig(Direction.TO)))
+ && (job.getDriverConfig().equals(this.driverConfig));
}
}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MJobForms.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MJobForms.java b/common/src/main/java/org/apache/sqoop/model/MJobForms.java
deleted file mode 100644
index 08b9a78..0000000
--- a/common/src/main/java/org/apache/sqoop/model/MJobForms.java
+++ /dev/null
@@ -1,55 +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.sqoop.model;
-
-import java.util.List;
-
-/**
- * Metadata describing all required information to build a job
- * object with two connectors and a framework.
- */
-public class MJobForms extends MFormList {
- public MJobForms(List<MForm> forms) {
- super(forms);
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- if (!(other instanceof MJobForms)) {
- return false;
- }
-
- MJobForms mj = (MJobForms) other;
- return super.equals(mj);
- }
-
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
- @Override
- public MJobForms clone(boolean cloneWithValue) {
- MJobForms copy = new MJobForms(super.clone(cloneWithValue).getForms());
- return copy;
- }
-}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MLink.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MLink.java b/common/src/main/java/org/apache/sqoop/model/MLink.java
index 6a8c424..7a9f538 100644
--- a/common/src/main/java/org/apache/sqoop/model/MLink.java
+++ b/common/src/main/java/org/apache/sqoop/model/MLink.java
@@ -22,57 +22,49 @@ package org.apache.sqoop.model;
*/
public class MLink extends MAccountableEntity implements MClonable {
private long connectorId;
-
- private final MConnectionForms connectorPart;
- private final MConnectionForms frameworkPart;
+ // NOTE: we hold this in the model for easy access to the link config object, it might as well be retrieved on the fly using the connectorId
+ private final MLinkConfig connectorLinkConfig;
/**
- * Default constructor to build new MConnection model.
+ * Default constructor to build new MLink model.
*
* @param connectorId Connector id
- * @param connectorPart Connector forms
- * @param frameworkPart Framework forms
+ * @param linkConfig Connector forms
*/
- public MLink(long connectorId,
- MConnectionForms connectorPart,
- MConnectionForms frameworkPart) {
+ public MLink(long connectorId, MLinkConfig linkConfig) {
this.connectorId = connectorId;
- this.connectorPart = connectorPart;
- this.frameworkPart = frameworkPart;
+ this.connectorLinkConfig = linkConfig;
}
/**
- * Constructor to create deep copy of another MConnection model.
+ * Constructor to create deep copy of another MLink model.
*
- * @param other MConnection model to copy
+ * @param other MLink model to copy
*/
public MLink(MLink other) {
- this(other, other.connectorPart.clone(true), other.frameworkPart.clone(true));
+ this(other, other.connectorLinkConfig.clone(true));
}
/**
- * Construct new MConnection model as a copy of another with replaced forms.
+ * Construct new MLink model as a copy of another with replaced forms.
*
- * This method is suitable only for metadata upgrade path and should not be
+ * This method is suitable only for link upgrade path and should not be
* used otherwise.
*
- * @param other MConnection model to copy
- * @param connectorPart Connector forms
- * @param frameworkPart Framework forms
+ * @param other MLink model to copy
+ * @param linkConfig link config
*/
- public MLink(MLink other, MConnectionForms connectorPart, MConnectionForms frameworkPart) {
+ public MLink(MLink other, MLinkConfig linkConfig) {
super(other);
this.connectorId = other.connectorId;
- this.connectorPart = connectorPart;
- this.frameworkPart = frameworkPart;
+ this.connectorLinkConfig = linkConfig;
this.setPersistenceId(other.getPersistenceId());
}
@Override
public String toString() {
- StringBuilder sb = new StringBuilder("connection: ").append(getName());
- sb.append(" connector-part: ").append(connectorPart);
- sb.append(", framework-part: ").append(frameworkPart);
+ StringBuilder sb = new StringBuilder("link: ").append(getName());
+ sb.append(" link-config: ").append(connectorLinkConfig);
return sb.toString();
}
@@ -85,20 +77,11 @@ public class MLink extends MAccountableEntity implements MClonable {
this.connectorId = connectorId;
}
- public MConnectionForms getConnectorPart() {
- return connectorPart;
- }
-
- public MConnectionForms getFrameworkPart() {
- return frameworkPart;
- }
-
- public MForm getConnectorForm(String formName) {
- return connectorPart.getForm(formName);
+ public MLinkConfig getConnectorLinkConfig() {
+ return connectorLinkConfig;
}
-
- public MForm getFrameworkForm(String formName) {
- return frameworkPart.getForm(formName);
+ public MConfig getConnectorLinkConfig(String formName) {
+ return connectorLinkConfig.getConfig(formName);
}
@Override
@@ -106,7 +89,7 @@ public class MLink extends MAccountableEntity implements MClonable {
if(cloneWithValue) {
return new MLink(this);
} else {
- return new MLink(connectorId, connectorPart.clone(false), frameworkPart.clone(false));
+ return new MLink(connectorId, connectorLinkConfig.clone(false));
}
}
@@ -120,10 +103,9 @@ public class MLink extends MAccountableEntity implements MClonable {
return false;
}
- MLink mc = (MLink)object;
- return (mc.connectorId == this.connectorId)
- && (mc.getPersistenceId() == this.getPersistenceId())
- && (mc.connectorPart.equals(this.connectorPart))
- && (mc.frameworkPart.equals(this.frameworkPart));
- }
+ MLink mLink = (MLink)object;
+ return (mLink.connectorId == this.connectorId)
+ && (mLink.getPersistenceId() == this.getPersistenceId())
+ && (mLink.connectorLinkConfig.equals(this.connectorLinkConfig));
+ }
}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MLinkConfig.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MLinkConfig.java b/common/src/main/java/org/apache/sqoop/model/MLinkConfig.java
new file mode 100644
index 0000000..318b63c
--- /dev/null
+++ b/common/src/main/java/org/apache/sqoop/model/MLinkConfig.java
@@ -0,0 +1,54 @@
+/**
+ * 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 java.util.List;
+
+/**
+ * Config describing all required information to build up an link object
+ * NOTE: It extends a config list since {@link MLink} could consist of a related config groups
+ * In future this could be simplified to hold a single list of all configs for the link object
+ */
+public class MLinkConfig extends MConfigList {
+
+ public MLinkConfig(List<MConfig> configs) {
+ super(configs);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("Link: ");
+ sb.append(super.toString());
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ return super.equals(other);
+ }
+
+ @Override
+ public MLinkConfig clone(boolean cloneWithValue) {
+ MLinkConfig copy = new MLinkConfig(super.clone(cloneWithValue).getConfigs());
+ return copy;
+ }
+}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/MToConfig.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MToConfig.java b/common/src/main/java/org/apache/sqoop/model/MToConfig.java
new file mode 100644
index 0000000..b4fbe41
--- /dev/null
+++ b/common/src/main/java/org/apache/sqoop/model/MToConfig.java
@@ -0,0 +1,64 @@
+/**
+ * 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 java.util.List;
+
+/**
+ * Config describing all required information to build the TO part of the job
+ * NOTE: It extends a config list since {@link MToConfig} could consist of a related config groups
+ * In future this could be simplified to hold a single list of all configs for the TO object
+
+ */
+public class MToConfig extends MConfigList {
+ public MToConfig(List<MConfig> configs) {
+ super(configs);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("To: ");
+ sb.append(super.toString());
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof MToConfig)) {
+ return false;
+ }
+
+ MToConfig mj = (MToConfig) other;
+ return super.equals(mj);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ @Override
+ public MToConfig clone(boolean cloneWithValue) {
+ MToConfig copy = new MToConfig(super.clone(cloneWithValue).getConfigs());
+ return copy;
+ }
+}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/model/ModelError.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/ModelError.java b/common/src/main/java/org/apache/sqoop/model/ModelError.java
index 74e924e..35a8943 100644
--- a/common/src/main/java/org/apache/sqoop/model/ModelError.java
+++ b/common/src/main/java/org/apache/sqoop/model/ModelError.java
@@ -24,7 +24,7 @@ import org.apache.sqoop.common.ErrorCode;
*/
public enum ModelError implements ErrorCode {
- MODEL_001("Attempt to pass two different set of MForms for single job type."),
+ MODEL_001("Attempt to pass two different set of MConfigs for single job type."),
MODEL_002("Creating MJob of different job types"),
@@ -34,7 +34,7 @@ public enum ModelError implements ErrorCode {
MODEL_005("Can't get field value"),
- MODEL_006("Incompatible form list and configuration object"),
+ MODEL_006("Incompatible config list and configuration object"),
MODEL_007("Primitive types in configuration objects are not allowed"),
@@ -42,7 +42,7 @@ public enum ModelError implements ErrorCode {
MODEL_009("Invalid input name"),
- MODEL_010("Form do not exist"),
+ MODEL_010("Config do not exist"),
MODEL_011("Input do not exist"),
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/utils/ClassUtils.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/utils/ClassUtils.java b/common/src/main/java/org/apache/sqoop/utils/ClassUtils.java
index eca9f7e..0be4d41 100644
--- a/common/src/main/java/org/apache/sqoop/utils/ClassUtils.java
+++ b/common/src/main/java/org/apache/sqoop/utils/ClassUtils.java
@@ -17,14 +17,12 @@
*/
package org.apache.sqoop.utils;
-import org.apache.log4j.Logger;
-
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
+
+import org.apache.log4j.Logger;
public final class ClassUtils {
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/validation/ConfigValidationError.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/validation/ConfigValidationError.java b/common/src/main/java/org/apache/sqoop/validation/ConfigValidationError.java
new file mode 100644
index 0000000..3453648
--- /dev/null
+++ b/common/src/main/java/org/apache/sqoop/validation/ConfigValidationError.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.sqoop.validation;
+
+import org.apache.sqoop.common.ErrorCode;
+
+/**
+ *
+ */
+public enum ConfigValidationError implements ErrorCode {
+
+ VALIDATION_0000("Unknown error"),
+
+ VALIDATION_0001("Missing class declaration."),
+
+ VALIDATION_0002("Usage of missing field"),
+
+ VALIDATION_0003("Invalid representation of config and input field"),
+
+ VALIDATION_0004("Can't find validator class"),
+
+ ;
+
+ private final String message;
+
+ private ConfigValidationError(String message) {
+ this.message = message;
+ }
+
+ public String getCode() {
+ return name();
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/validation/ConfigValidationResult.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/validation/ConfigValidationResult.java b/common/src/main/java/org/apache/sqoop/validation/ConfigValidationResult.java
new file mode 100644
index 0000000..4c4d123
--- /dev/null
+++ b/common/src/main/java/org/apache/sqoop/validation/ConfigValidationResult.java
@@ -0,0 +1,98 @@
+/**
+ * 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;
+
+import org.apache.sqoop.validation.validators.AbstractValidator;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Result of validation execution.
+ */
+public class ConfigValidationResult {
+
+ /**
+ * All messages for each named item.
+ */
+ Map<String, List<Message>> messages;
+
+ /**
+ * Overall status.
+ */
+ Status status;
+
+ public ConfigValidationResult() {
+ messages = new HashMap<String, List<Message>>();
+ status = Status.getDefault();
+ }
+
+ /**
+ * Add given validator result to this instance.
+ *
+ * @param name Full name of the validated object
+ * @param validator Executed validator
+ */
+ public void addValidatorResult(String name, AbstractValidator<String> validator) {
+ if(validator.getStatus() == Status.getDefault()) {
+ return;
+ }
+
+ status = Status.getWorstStatus(status, validator.getStatus());
+ if(messages.containsKey(name)) {
+ messages.get(name).addAll(validator.getMessages());
+ } else {
+ messages.put(name, validator.getMessages());
+ }
+ }
+
+ /**
+ * Merge results with another validation result.
+ *
+ * @param result Other validation result
+ */
+ public void mergeValidatorResult(ConfigValidationResult result) {
+ messages.putAll(result.messages);
+ status = Status.getWorstStatus(status, result.status);
+ }
+
+ /**
+ * Method to directly add messages for given name.
+ *
+ * This method will replace previous messages for given name.
+ *
+ * @param name Name of the entity
+ * @param messages List of messages associated with the name
+ */
+ public void addMessages(String name, List<Message> messages) {
+ this.messages.put(name, messages);
+
+ for(Message message : messages) {
+ this.status = Status.getWorstStatus(status, message.getStatus());
+ }
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public Map<String, List<Message>> getMessages() {
+ return messages;
+ }
+}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/validation/ConfigValidationRunner.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/validation/ConfigValidationRunner.java b/common/src/main/java/org/apache/sqoop/validation/ConfigValidationRunner.java
new file mode 100644
index 0000000..8c66b3d
--- /dev/null
+++ b/common/src/main/java/org/apache/sqoop/validation/ConfigValidationRunner.java
@@ -0,0 +1,177 @@
+/**
+ * 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;
+
+import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.model.ConfigurationClass;
+import org.apache.sqoop.model.Config;
+import org.apache.sqoop.model.ConfigClass;
+import org.apache.sqoop.model.ConfigUtils;
+import org.apache.sqoop.model.Input;
+import org.apache.sqoop.model.Validator;
+import org.apache.sqoop.utils.ClassUtils;
+import org.apache.sqoop.validation.validators.AbstractValidator;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Validation runner that will run validators associated with given configuration
+ * class or config object.
+ *
+ * Execution follows following rules:
+ * * Run children first (Inputs -> Config -> Class)
+ * * If any children is not suitable (canProceed = false), skip running parent
+ *
+ * Which means that config validator don't have to repeat it's input validators as it will
+ * be never called if the input's are not valid. Similarly Class validators won't be called
+ * unless all configs will pass validators.
+ *
+ */
+public class ConfigValidationRunner {
+
+ /**
+ * Private cache of instantiated validators.
+ *
+ * We're expecting that this cache will be very small as the number of possible validators
+ * is driven to high extent by the number of connectors and hence we don't have a cache
+ * eviction at the moment.
+ */
+ private Map<Class<? extends AbstractValidator>, AbstractValidator> cache;
+
+ public ConfigValidationRunner() {
+ cache = new HashMap<Class<? extends AbstractValidator>, AbstractValidator>();
+ }
+
+ /**
+ * Validate given configuration instance.
+ *
+ * @param config Configuration instance
+ * @return
+ */
+ public ConfigValidationResult validate(Object config) {
+ ConfigValidationResult result = new ConfigValidationResult();
+ ConfigurationClass globalAnnotation = ConfigUtils.getConfigurationClassAnnotation(config, true);
+
+ // Iterate over all declared config and call their validators
+ for (Field field : config.getClass().getDeclaredFields()) {
+ field.setAccessible(true);
+
+ Config configAnnotation = ConfigUtils.getConfigAnnotation(field, false);
+ if(configAnnotation == null) {
+ continue;
+ }
+
+ String configName = ConfigUtils.getName(field, configAnnotation);
+ ConfigValidationResult r = validateConfig(configName, ConfigUtils.getFieldValue(field, config));
+ result.mergeValidatorResult(r);
+ }
+
+ // Call class validator only as long as we are in suitable state
+ if(result.getStatus().canProceed()) {
+ ConfigValidationResult r = validateArray("", config, globalAnnotation.validators());
+ result.mergeValidatorResult(r);
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate given config instance.
+ *
+ * @param configName Config's name to build full name for all inputs.
+ * @param config Config instance
+ * @return
+ */
+ public ConfigValidationResult validateConfig(String configName, Object config) {
+ ConfigValidationResult result = new ConfigValidationResult();
+ ConfigClass configAnnotation = ConfigUtils.getConfigClassAnnotation(config, true);
+
+ // Iterate over all declared inputs and call their validators
+ for (Field field : config.getClass().getDeclaredFields()) {
+ Input inputAnnotation = ConfigUtils.getInputAnnotation(field, false);
+ if(inputAnnotation == null) {
+ continue;
+ }
+
+ String name = configName + "." + ConfigUtils.getName(field, inputAnnotation);
+
+ ConfigValidationResult r = validateArray(name, ConfigUtils.getFieldValue(field, config), inputAnnotation.validators());
+ result.mergeValidatorResult(r);
+ }
+
+ // Call config validator only as long as we are in suitable state
+ if(result.getStatus().canProceed()) {
+ ConfigValidationResult r = validateArray(configName, config, configAnnotation.validators());
+ result.mergeValidatorResult(r);
+ }
+
+ return result;
+ }
+
+ /**
+ * Execute array of validators on given object (can be input/config/class).
+ *
+ * @param name Full name of the object
+ * @param object Input, Config or Class instance
+ * @param validators Validators array
+ * @return
+ */
+ private ConfigValidationResult validateArray(String name, Object object, Validator[] validators) {
+ ConfigValidationResult result = new ConfigValidationResult();
+
+ for (Validator validator : validators) {
+ AbstractValidator v = executeValidator(object, validator);
+ result.addValidatorResult(name, v);
+ }
+
+ return result;
+ }
+
+ /**
+ * Execute single validator.
+ *
+ * @param object Input, Config or Class instance
+ * @param validator Validator annotation
+ * @return
+ */
+ private AbstractValidator executeValidator(Object object, Validator validator) {
+ // Try to get validator instance from the cache
+ AbstractValidator instance = cache.get(validator.value());
+
+ if(instance == null) {
+ instance = (AbstractValidator) ClassUtils.instantiate(validator.value());
+
+ // This could happen if we would be missing some connector's jars on our classpath
+ if(instance == null) {
+ throw new SqoopException(ConfigValidationError.VALIDATION_0004, validator.value().getName());
+ }
+
+ cache.put(validator.value(), instance);
+ } else {
+ instance.reset();
+ }
+
+ instance.setStringArgument(validator.strArg());
+ instance.validate(object);
+ return instance;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/validation/ConfigValidator.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/validation/ConfigValidator.java b/common/src/main/java/org/apache/sqoop/validation/ConfigValidator.java
new file mode 100644
index 0000000..eac789e
--- /dev/null
+++ b/common/src/main/java/org/apache/sqoop/validation/ConfigValidator.java
@@ -0,0 +1,228 @@
+/**
+ * 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;
+
+import org.apache.sqoop.common.SqoopException;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Config validators.
+ *
+ * This class represents validations for the sqoop objects
+ */
+public class ConfigValidator {
+
+ // Configuration class that belongs to this validation
+ Class klass;
+
+ // Entire validation status
+ Status status;
+
+ // Status messages for various fields
+ Map<ConfigInput, Message> messages;
+
+ public ConfigValidator(Class klass) {
+ this.klass = klass;
+ status = Status.getDefault();
+ messages = new HashMap<ConfigInput, Message>();
+ }
+
+ public ConfigValidator(Status status, Map<ConfigInput, Message> messages) {
+ this.status = status;
+ this.messages = messages;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public Map<ConfigInput, Message> getMessages() {
+ return messages;
+ }
+
+ /**
+ * Add message to config.
+ *
+ * @param status Severity of the message
+ * @param config Config name, must be defined in the class
+ * @param message Validation message
+ */
+ public void addMessage(Status status, String config, String message) {
+ addMessage(status, config, null, message);
+ }
+
+ /**
+ * Add message to input in one of the configs.
+ *
+ * @param status Severity of the message
+ * @param config Config name, must be defined in the class
+ * @param input Field name, must be defined in the config class
+ * @param message Validation message
+ */
+ public void addMessage(Status status, String config, String input, String message ) {
+ if( klass == null) {
+ throw new SqoopException(ConfigValidationError.VALIDATION_0001);
+ }
+
+ assert config != null;
+ assert message != null;
+
+ // Field for specified config
+ Field configField;
+
+ // Load the config field and verify that it exists
+ try {
+ configField = klass.getDeclaredField(config);
+ } catch (NoSuchFieldException e) {
+ throw new SqoopException(ConfigValidationError.VALIDATION_0002,
+ "Can't get config " + config + " from " + klass.getName(), e);
+ }
+
+ // If this is config message, just save the message and continue
+ if(input == null) {
+ setMessage(status, config, input, message);
+ return;
+ }
+
+ // Verify that specified input exists on the config
+ try {
+ configField.getType().getDeclaredField(input);
+ } catch (NoSuchFieldException e) {
+ throw new SqoopException(ConfigValidationError.VALIDATION_0002,
+ "Can't get input " + input + " from config" + configField.getType().getName(), e);
+ }
+
+ setMessage(status, config, input, message);
+ }
+
+ private void setMessage(Status status, String config, String input, String message) {
+ this.status = Status.getWorstStatus(this.status, status);
+ messages.put(new ConfigInput(config, input), new Message(status, message));
+ }
+
+ public static 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 + "}";
+ }
+ }
+
+ public static class ConfigInput{
+ private String config;
+ private String input;
+
+ public ConfigInput(String config, String input) {
+ this.config = config;
+ this.input = input;
+ }
+
+ public ConfigInput(String configInput) {
+ assert configInput != null;
+ String []parts = configInput.split("\\.");
+
+ if(configInput.isEmpty() || (parts.length != 1 && parts.length != 2)) {
+ throw new SqoopException(ConfigValidationError.VALIDATION_0003,
+ "Specification " + configInput + " is not in valid configat config.input");
+ }
+
+ this.config = parts[0];
+ if(parts.length == 2) {
+ this.input = parts[1];
+ }
+ }
+
+ public String getConfig() {
+ return config;
+ }
+
+ public String getInput() {
+ return input;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ConfigInput configInput = (ConfigInput) o;
+
+ if (config != null ? !config.equals(configInput.config) : configInput.config != null)
+ return false;
+ if (input != null ? !input.equals(configInput.input) : configInput.input != null)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = config != null ? config.hashCode() : 0;
+ result = 31 * result + (input != null ? input.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ if(input == null) {
+ return config;
+ }
+
+ return config + "." + input;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/validation/Message.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/validation/Message.java b/common/src/main/java/org/apache/sqoop/validation/Message.java
index cb55b6a..3361b6f 100644
--- a/common/src/main/java/org/apache/sqoop/validation/Message.java
+++ b/common/src/main/java/org/apache/sqoop/validation/Message.java
@@ -21,7 +21,7 @@ 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.
+ * is wrong. It can be associated with Input, Config or ConfigurationGroup class.
*/
public class Message {
private Status status;
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/validation/Validation.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/validation/Validation.java b/common/src/main/java/org/apache/sqoop/validation/Validation.java
deleted file mode 100644
index fce6e88..0000000
--- a/common/src/main/java/org/apache/sqoop/validation/Validation.java
+++ /dev/null
@@ -1,228 +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.sqoop.validation;
-
-import org.apache.sqoop.common.SqoopException;
-
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Validation class.
- *
- * This class represents validations to given configuration object.
- */
-public class Validation {
-
- // Configuration class that belongs to this validation
- Class klass;
-
- // Entire validation status
- Status status;
-
- // Status messages for various fields
- Map<FormInput, Message> messages;
-
- public Validation(Class klass) {
- this.klass = klass;
- status = Status.getDefault();
- messages = new HashMap<FormInput, Message>();
- }
-
- public Validation(Status status, Map<FormInput, Message> messages) {
- this.status = status;
- this.messages = messages;
- }
-
- public Status getStatus() {
- return status;
- }
-
- public Map<FormInput, Message> getMessages() {
- return messages;
- }
-
- /**
- * Add message to form.
- *
- * @param status Severity of the message
- * @param form Form name, must be defined in the class
- * @param message Validation message
- */
- public void addMessage(Status status, String form, String message) {
- addMessage(status, form, null, message);
- }
-
- /**
- * Add message to input in one of the forms.
- *
- * @param status Severity of the message
- * @param form Form name, must be defined in the class
- * @param input Field name, must be defined in the form class
- * @param message Validation message
- */
- public void addMessage(Status status, String form, String input, String message ) {
- if( klass == null) {
- throw new SqoopException(ValidationError.VALIDATION_0001);
- }
-
- assert form != null;
- assert message != null;
-
- // Field for specified form
- Field formField;
-
- // Load the form field and verify that it exists
- try {
- formField = klass.getDeclaredField(form);
- } catch (NoSuchFieldException e) {
- throw new SqoopException(ValidationError.VALIDATION_0002,
- "Can't get form " + form + " from " + klass.getName(), e);
- }
-
- // If this is form message, just save the message and continue
- if(input == null) {
- setMessage(status, form, input, message);
- return;
- }
-
- // Verify that specified input exists on the form
- try {
- formField.getType().getDeclaredField(input);
- } catch (NoSuchFieldException e) {
- throw new SqoopException(ValidationError.VALIDATION_0002,
- "Can't get input " + input + " from form" + formField.getType().getName(), e);
- }
-
- setMessage(status, form, input, message);
- }
-
- private void setMessage(Status status, String form, String input, String message) {
- this.status = Status.getWorstStatus(this.status, status);
- messages.put(new FormInput(form, input), new Message(status, message));
- }
-
- public static 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 + "}";
- }
- }
-
- public static class FormInput {
- private String form;
- private String input;
-
- public FormInput(String form, String input) {
- this.form = form;
- this.input = input;
- }
-
- public FormInput(String formInput) {
- assert formInput != null;
- String []parts = formInput.split("\\.");
-
- if(formInput.isEmpty() || (parts.length != 1 && parts.length != 2)) {
- throw new SqoopException(ValidationError.VALIDATION_0003,
- "Specification " + formInput + " is not in valid format form.input");
- }
-
- this.form = parts[0];
- if(parts.length == 2) {
- this.input = parts[1];
- }
- }
-
- public String getForm() {
- return form;
- }
-
- public String getInput() {
- return input;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- FormInput formInput = (FormInput) o;
-
- if (form != null ? !form.equals(formInput.form) : formInput.form != null)
- return false;
- if (input != null ? !input.equals(formInput.input) : formInput.input != null)
- return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = form != null ? form.hashCode() : 0;
- result = 31 * result + (input != null ? input.hashCode() : 0);
- return result;
- }
-
- @Override
- public String toString() {
- if(input == null) {
- return form;
- }
-
- return form + "." + input;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/validation/ValidationError.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/validation/ValidationError.java b/common/src/main/java/org/apache/sqoop/validation/ValidationError.java
deleted file mode 100644
index ec64f10..0000000
--- a/common/src/main/java/org/apache/sqoop/validation/ValidationError.java
+++ /dev/null
@@ -1,52 +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.sqoop.validation;
-
-import org.apache.sqoop.common.ErrorCode;
-
-/**
- *
- */
-public enum ValidationError implements ErrorCode {
-
- VALIDATION_0000("Unknown error"),
-
- VALIDATION_0001("Missing class declaration."),
-
- VALIDATION_0002("Usage of missing field"),
-
- VALIDATION_0003("Invalid representation of form and input field"),
-
- VALIDATION_0004("Can't find validator class"),
-
- ;
-
- private final String message;
-
- private ValidationError(String message) {
- this.message = message;
- }
-
- public String getCode() {
- return name();
- }
-
- public String getMessage() {
- return message;
- }
-}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/validation/ValidationResult.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/validation/ValidationResult.java b/common/src/main/java/org/apache/sqoop/validation/ValidationResult.java
deleted file mode 100644
index ae8f1d1..0000000
--- a/common/src/main/java/org/apache/sqoop/validation/ValidationResult.java
+++ /dev/null
@@ -1,98 +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.sqoop.validation;
-
-import org.apache.sqoop.validation.validators.AbstractValidator;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Result of validation execution.
- */
-public class ValidationResult {
-
- /**
- * All messages for each named item.
- */
- Map<String, List<Message>> messages;
-
- /**
- * Overall status.
- */
- Status status;
-
- public ValidationResult() {
- messages = new HashMap<String, List<Message>>();
- status = Status.getDefault();
- }
-
- /**
- * Add given validator result to this instance.
- *
- * @param name Full name of the validated object
- * @param validator Executed validator
- */
- public void addValidator(String name, AbstractValidator validator) {
- if(validator.getStatus() == Status.getDefault()) {
- return;
- }
-
- status = Status.getWorstStatus(status, validator.getStatus());
- if(messages.containsKey(name)) {
- messages.get(name).addAll(validator.getMessages());
- } else {
- messages.put(name, validator.getMessages());
- }
- }
-
- /**
- * Merge results with another validation result.
- *
- * @param result Other validation result
- */
- public void merge(ValidationResult result) {
- messages.putAll(result.messages);
- status = Status.getWorstStatus(status, result.status);
- }
-
- /**
- * Method to directly add messages for given name.
- *
- * This method will replace previous messages for given name.
- *
- * @param name Name of the entity
- * @param messages List of messages associated with the name
- */
- public void addMessages(String name, List<Message> messages) {
- this.messages.put(name, messages);
-
- for(Message message : messages) {
- this.status = Status.getWorstStatus(status, message.getStatus());
- }
- }
-
- public Status getStatus() {
- return status;
- }
-
- public Map<String, List<Message>> getMessages() {
- return messages;
- }
-}
http://git-wip-us.apache.org/repos/asf/sqoop/blob/8362c73c/common/src/main/java/org/apache/sqoop/validation/ValidationRunner.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/validation/ValidationRunner.java b/common/src/main/java/org/apache/sqoop/validation/ValidationRunner.java
deleted file mode 100644
index 8ffc0d4..0000000
--- a/common/src/main/java/org/apache/sqoop/validation/ValidationRunner.java
+++ /dev/null
@@ -1,176 +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.sqoop.validation;
-
-import org.apache.sqoop.common.SqoopException;
-import org.apache.sqoop.model.ConfigurationClass;
-import org.apache.sqoop.model.Form;
-import org.apache.sqoop.model.FormClass;
-import org.apache.sqoop.model.FormUtils;
-import org.apache.sqoop.model.Input;
-import org.apache.sqoop.model.Validator;
-import org.apache.sqoop.utils.ClassUtils;
-import org.apache.sqoop.validation.validators.AbstractValidator;
-
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Validation runner that will run validators associated with given configuration
- * class or form object.
- *
- * Execution follows following rules:
- * * Run children first (Inputs -> Form -> Class)
- * * If any children is not suitable (canProceed = false), skip running parent
- *
- * Which means that form validator don't have to repeat it's input validators as it will
- * be never called if the input's are not valid. Similarly Class validators won't be called
- * unless all forms will pass validators.
- */
-public class ValidationRunner {
-
- /**
- * Private cache of instantiated validators.
- *
- * We're expecting that this cache will be very small as the number of possible validators
- * is driven to high extent by the number of connectors and hence we don't have a cache
- * eviction at the moment.
- */
- private Map<Class<? extends AbstractValidator>, AbstractValidator> cache;
-
- public ValidationRunner() {
- cache = new HashMap<Class<? extends AbstractValidator>, AbstractValidator>();
- }
-
- /**
- * Validate given configuration instance.
- *
- * @param config Configuration instance
- * @return
- */
- public ValidationResult validate(Object config) {
- ValidationResult result = new ValidationResult();
- ConfigurationClass globalAnnotation = FormUtils.getConfigurationClassAnnotation(config, true);
-
- // Iterate over all declared form and call their validators
- for (Field field : config.getClass().getDeclaredFields()) {
- field.setAccessible(true);
-
- Form formAnnotation = FormUtils.getFormAnnotation(field, false);
- if(formAnnotation == null) {
- continue;
- }
-
- String formName = FormUtils.getName(field, formAnnotation);
- ValidationResult r = validateForm(formName, FormUtils.getFieldValue(field, config));
- result.merge(r);
- }
-
- // Call class validator only as long as we are in suitable state
- if(result.getStatus().canProceed()) {
- ValidationResult r = validateArray("", config, globalAnnotation.validators());
- result.merge(r);
- }
-
- return result;
- }
-
- /**
- * Validate given form instance.
- *
- * @param formName Form's name to build full name for all inputs.
- * @param form Form instance
- * @return
- */
- public ValidationResult validateForm(String formName, Object form) {
- ValidationResult result = new ValidationResult();
- FormClass formAnnotation = FormUtils.getFormClassAnnotation(form, true);
-
- // Iterate over all declared inputs and call their validators
- for (Field field : form.getClass().getDeclaredFields()) {
- Input inputAnnotation = FormUtils.getInputAnnotation(field, false);
- if(inputAnnotation == null) {
- continue;
- }
-
- String name = formName + "." + FormUtils.getName(field, inputAnnotation);
-
- ValidationResult r = validateArray(name, FormUtils.getFieldValue(field, form), inputAnnotation.validators());
- result.merge(r);
- }
-
- // Call form validator only as long as we are in suitable state
- if(result.getStatus().canProceed()) {
- ValidationResult r = validateArray(formName, form, formAnnotation.validators());
- result.merge(r);
- }
-
- return result;
- }
-
- /**
- * Execute array of validators on given object (can be input/form/class).
- *
- * @param name Full name of the object
- * @param object Input, Form or Class instance
- * @param validators Validators array
- * @return
- */
- private ValidationResult validateArray(String name, Object object, Validator[] validators) {
- ValidationResult result = new ValidationResult();
-
- for (Validator validator : validators) {
- AbstractValidator v = executeValidator(object, validator);
- result.addValidator(name, v);
- }
-
- return result;
- }
-
- /**
- * Execute single validator.
- *
- * @param object Input, Form or Class instance
- * @param validator Validator annotation
- * @return
- */
- private AbstractValidator executeValidator(Object object, Validator validator) {
- // Try to get validator instance from the cache
- AbstractValidator instance = cache.get(validator.value());
-
- if(instance == null) {
- instance = (AbstractValidator) ClassUtils.instantiate(validator.value());
-
- // This could happen if we would be missing some connector's jars on our classpath
- if(instance == null) {
- throw new SqoopException(ValidationError.VALIDATION_0004, validator.value().getName());
- }
-
- cache.put(validator.value(), instance);
- } else {
- instance.reset();
- }
-
- instance.setStringArgument(validator.strArg());
- instance.validate(object);
- return instance;
- }
-
-
-}