sqoop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject [46/52] [abbrv] SQOOP-1498: Sqoop2: Repository Object refactoring (objects prefixed with M)
Date Fri, 10 Oct 2014 02:52:15 GMT
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;
-  }
-
-
-}


Mime
View raw message