You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sqoop.apache.org by ja...@apache.org on 2013/05/23 10:17:27 UTC

git commit: SQOOP-995: Sqoop2: Add cloning ability to model classes

Updated Branches:
  refs/heads/sqoop2 cd4a822ab -> 94c91efd3


SQOOP-995: Sqoop2: Add cloning ability to model classes

(Vasanth kumar RJ via Jarek Jarcec Cecho)


Project: http://git-wip-us.apache.org/repos/asf/sqoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/sqoop/commit/94c91efd
Tree: http://git-wip-us.apache.org/repos/asf/sqoop/tree/94c91efd
Diff: http://git-wip-us.apache.org/repos/asf/sqoop/diff/94c91efd

Branch: refs/heads/sqoop2
Commit: 94c91efd3bfc87123ec11589aa32812a23101d3e
Parents: cd4a822
Author: Jarek Jarcec Cecho <ja...@apache.org>
Authored: Thu May 23 01:16:00 2013 -0700
Committer: Jarek Jarcec Cecho <ja...@apache.org>
Committed: Thu May 23 01:16:00 2013 -0700

----------------------------------------------------------------------
 .../java/org/apache/sqoop/model/MClonable.java     |   28 +++++++++
 .../java/org/apache/sqoop/model/MConnection.java   |   31 +++++++++-
 .../org/apache/sqoop/model/MConnectionForms.java   |    6 ++
 .../java/org/apache/sqoop/model/MConnector.java    |   18 ++++++
 .../java/org/apache/sqoop/model/MEnumInput.java    |   11 +++
 .../main/java/org/apache/sqoop/model/MForm.java    |   13 ++++-
 .../java/org/apache/sqoop/model/MFormList.java     |   18 +++++-
 .../java/org/apache/sqoop/model/MFramework.java    |   19 ++++++-
 .../main/java/org/apache/sqoop/model/MInput.java   |    2 +-
 .../java/org/apache/sqoop/model/MIntegerInput.java |   10 +++
 .../src/main/java/org/apache/sqoop/model/MJob.java |   33 ++++++++++-
 .../java/org/apache/sqoop/model/MJobForms.java     |    6 ++
 .../java/org/apache/sqoop/model/MMapInput.java     |   16 +++++
 .../java/org/apache/sqoop/model/MStringInput.java  |   11 +++
 .../org/apache/sqoop/model/TestMConnection.java    |   26 ++++++++
 .../org/apache/sqoop/model/TestMConnector.java     |   44 +++++++++++++
 .../test/java/org/apache/sqoop/model/TestMJob.java |   48 +++++++++++++++
 17 files changed, 334 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/common/src/main/java/org/apache/sqoop/model/MClonable.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MClonable.java b/common/src/main/java/org/apache/sqoop/model/MClonable.java
new file mode 100644
index 0000000..6353779
--- /dev/null
+++ b/common/src/main/java/org/apache/sqoop/model/MClonable.java
@@ -0,0 +1,28 @@
+/**
+ * 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;
+
+public interface MClonable {
+  /**
+   * Clone object
+   * Invoke with value true for cloning value
+   * @param cloneWithValue
+   * @return
+   */
+  public Object clone(boolean cloneWithValue);
+}

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/common/src/main/java/org/apache/sqoop/model/MConnection.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MConnection.java b/common/src/main/java/org/apache/sqoop/model/MConnection.java
index c31eafd..0e4f1a2 100644
--- a/common/src/main/java/org/apache/sqoop/model/MConnection.java
+++ b/common/src/main/java/org/apache/sqoop/model/MConnection.java
@@ -21,7 +21,7 @@ package org.apache.sqoop.model;
  * Model describing entire connection object including both connector and
  * framework part.
  */
-public class MConnection extends MAccountableEntity {
+public class MConnection extends MAccountableEntity implements MClonable {
   private long connectorId;
   private String name;
 
@@ -84,4 +84,33 @@ public class MConnection extends MAccountableEntity {
   public MForm getFrameworkForm(String formName) {
     return frameworkPart.getForm(formName);
   }
+
+  @Override
+  public MConnection clone(boolean cloneWithValue) {
+    MConnection copy = new MConnection(this.getConnectorId(),
+        this.getConnectorPart().clone(cloneWithValue),
+        this.getFrameworkPart().clone(cloneWithValue));
+    if(cloneWithValue) {
+      copy.setPersistenceId(this.getPersistenceId());
+      copy.setName(this.getName());
+    }
+    return copy;
+  }
+
+  @Override
+  public boolean equals(Object object) {
+    if(object == this) {
+      return true;
+    }
+
+    if(!(object instanceof MConnection)) {
+      return false;
+    }
+
+    MConnection mc = (MConnection)object;
+    return (mc.connectorId == this.connectorId)
+        && (mc.getPersistenceId() == this.getPersistenceId())
+        && (mc.connectorPart.equals(this.connectorPart))
+        && (mc.frameworkPart.equals(this.frameworkPart));
+  }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/common/src/main/java/org/apache/sqoop/model/MConnectionForms.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MConnectionForms.java b/common/src/main/java/org/apache/sqoop/model/MConnectionForms.java
index d289a02..457ccdb 100644
--- a/common/src/main/java/org/apache/sqoop/model/MConnectionForms.java
+++ b/common/src/main/java/org/apache/sqoop/model/MConnectionForms.java
@@ -45,4 +45,10 @@ public class MConnectionForms extends MFormList {
 
     return super.equals(other);
   }
+
+  @Override
+  public MConnectionForms clone(boolean cloneWithValue) {
+    MConnectionForms copy = new MConnectionForms(super.clone(cloneWithValue).getForms());
+    return copy;
+  }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/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 9207c62..1c2c422 100644
--- a/common/src/main/java/org/apache/sqoop/model/MConnector.java
+++ b/common/src/main/java/org/apache/sqoop/model/MConnector.java
@@ -17,6 +17,7 @@
  */
 package org.apache.sqoop.model;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -94,4 +95,21 @@ public final class MConnector extends MFramework {
 
     return result;
   }
+
+  @Override
+  public MConnector clone(boolean cloneWithValue) {
+    //Connector never have any values filled
+    cloneWithValue = false;
+    List<MJobForms> copyJobForms = null;
+    if(this.getAllJobsForms()!=null) {
+      copyJobForms = new ArrayList<MJobForms>();
+      for(MJobForms entry: this.getAllJobsForms().values()) {
+        copyJobForms.add(entry.clone(cloneWithValue));
+      }
+    }
+    MConnector copy = new MConnector(this.getUniqueName(), this.getClassName(), this.getVersion(),
+        this.getConnectionForms().clone(cloneWithValue), copyJobForms);
+    copy.setPersistenceId(this.getPersistenceId());
+    return copy;
+  }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/common/src/main/java/org/apache/sqoop/model/MEnumInput.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MEnumInput.java b/common/src/main/java/org/apache/sqoop/model/MEnumInput.java
index 12705a6..620c840 100644
--- a/common/src/main/java/org/apache/sqoop/model/MEnumInput.java
+++ b/common/src/main/java/org/apache/sqoop/model/MEnumInput.java
@@ -124,4 +124,15 @@ public class MEnumInput extends MInput<String> {
   public void setEmpty() {
     setValue((String)null);
   }
+
+  @Override
+  public MEnumInput clone(boolean cloneWithValue) {
+    MEnumInput copy = new MEnumInput(this.getName(),
+        this.isSensitive(), this.getValues());
+    copy.setPersistenceId(this.getPersistenceId());
+    if(cloneWithValue) {
+      copy.setValue(this.getValue());
+    }
+    return copy;
+  }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/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
index 76998dd..cc7d88c 100644
--- a/common/src/main/java/org/apache/sqoop/model/MForm.java
+++ b/common/src/main/java/org/apache/sqoop/model/MForm.java
@@ -19,6 +19,7 @@ package org.apache.sqoop.model;
 
 import org.apache.sqoop.common.SqoopException;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -26,7 +27,7 @@ import java.util.List;
  * 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 {
+public final class MForm extends MValidatedElement implements MClonable {
 
   private final List<MInput<?>> inputs;
 
@@ -99,4 +100,14 @@ public final class MForm extends MValidatedElement {
 
     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/94c91efd/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
index 3bf508d..c1c3a41 100644
--- a/common/src/main/java/org/apache/sqoop/model/MFormList.java
+++ b/common/src/main/java/org/apache/sqoop/model/MFormList.java
@@ -19,12 +19,13 @@ 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 {
+public class MFormList implements MClonable {
 
   private final List<MForm> forms;
 
@@ -101,4 +102,19 @@ public class MFormList {
     }
     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/94c91efd/common/src/main/java/org/apache/sqoop/model/MFramework.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MFramework.java b/common/src/main/java/org/apache/sqoop/model/MFramework.java
index f5252ef..694f022 100644
--- a/common/src/main/java/org/apache/sqoop/model/MFramework.java
+++ b/common/src/main/java/org/apache/sqoop/model/MFramework.java
@@ -19,6 +19,7 @@ package org.apache.sqoop.model;
 
 import org.apache.sqoop.common.SqoopException;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -27,7 +28,7 @@ import java.util.Map;
  * Metadata describing framework options for connection and job for each
  * supported job type.
  */
-public class MFramework extends MPersistableEntity {
+public class MFramework extends MPersistableEntity implements MClonable {
 
   private final MConnectionForms connectionForms;
   private final Map<MJob.Type, MJobForms> jobs;
@@ -95,5 +96,21 @@ public class MFramework extends MPersistableEntity {
   public MJobForms getJobForms(MJob.Type type) {
     return jobs.get(type);
   }
+
+  @Override
+  public MFramework clone(boolean cloneWithValue) {
+    //Framework never have any values filled
+    cloneWithValue = false;
+    List<MJobForms> copyJobForms = null;
+    if(this.getAllJobsForms()!=null) {
+      copyJobForms = new ArrayList<MJobForms>();
+      for(MJobForms entry: this.getAllJobsForms().values()) {
+        copyJobForms.add(entry.clone(cloneWithValue));
+      }
+    }
+    MFramework copy = new MFramework(this.getConnectionForms().clone(cloneWithValue), copyJobForms);
+    copy.setPersistenceId(this.getPersistenceId());
+    return copy;
+  }
 }
 

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/common/src/main/java/org/apache/sqoop/model/MInput.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MInput.java b/common/src/main/java/org/apache/sqoop/model/MInput.java
index 7d6215f..1f4c425 100644
--- a/common/src/main/java/org/apache/sqoop/model/MInput.java
+++ b/common/src/main/java/org/apache/sqoop/model/MInput.java
@@ -23,7 +23,7 @@ package org.apache.sqoop.model;
  * @param <T> the value type associated with this parameter
  * @param boolean whether or not the field contains sensitive information
  */
-public abstract class MInput<T> extends MValidatedElement {
+public abstract class MInput<T> extends MValidatedElement implements MClonable {
   private final boolean sensitive;
 
   private T value;

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/common/src/main/java/org/apache/sqoop/model/MIntegerInput.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MIntegerInput.java b/common/src/main/java/org/apache/sqoop/model/MIntegerInput.java
index d23ac31..a43f440 100644
--- a/common/src/main/java/org/apache/sqoop/model/MIntegerInput.java
+++ b/common/src/main/java/org/apache/sqoop/model/MIntegerInput.java
@@ -79,4 +79,14 @@ public class MIntegerInput extends MInput<Integer> {
   public void setEmpty() {
     setValue(null);
   }
+
+  @Override
+  public MIntegerInput clone(boolean cloneWithValue) {
+    MIntegerInput copy = new MIntegerInput(this.getName(), this.isSensitive());
+    copy.setPersistenceId(this.getPersistenceId());
+    if(cloneWithValue) {
+      copy.setValue(this.getValue());
+    }
+    return copy;
+  }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/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 5b50bfd..c58d1f0 100644
--- a/common/src/main/java/org/apache/sqoop/model/MJob.java
+++ b/common/src/main/java/org/apache/sqoop/model/MJob.java
@@ -23,7 +23,7 @@ import org.apache.sqoop.common.SqoopException;
  * Model describing entire job object including both connector and
  * framework part.
  */
-public class MJob extends MAccountableEntity {
+public class MJob extends MAccountableEntity implements MClonable {
 
   public static enum Type {
     IMPORT,
@@ -130,4 +130,35 @@ public class MJob extends MAccountableEntity {
   public Type getType() {
     return type;
   }
+
+  @Override
+  public MJob clone(boolean cloneWithValue) {
+    MJob copy = new MJob(this.connectorId, this.connectionId, this.type,
+        this.getConnectorPart().clone(cloneWithValue),
+        this.getFrameworkPart().clone(cloneWithValue));
+    if(cloneWithValue) {
+      copy.setPersistenceId(this.getPersistenceId());
+      copy.setName(this.getName());
+    }
+    return copy;
+  }
+
+  @Override
+  public boolean equals(Object object) {
+    if(object == this) {
+      return true;
+    }
+
+    if(!(object instanceof MJob)) {
+      return false;
+    }
+
+    MJob job = (MJob)object;
+    return (job.connectorId == this.connectorId)
+        && (job.connectionId == this.connectionId)
+        && (job.getPersistenceId() == this.getPersistenceId())
+        && (job.type.equals(this.type))
+        && (job.connectorPart.equals(this.connectorPart))
+        && (job.frameworkPart.equals(this.frameworkPart));
+  }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/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
index bce646f..f697023 100644
--- a/common/src/main/java/org/apache/sqoop/model/MJobForms.java
+++ b/common/src/main/java/org/apache/sqoop/model/MJobForms.java
@@ -64,4 +64,10 @@ public class MJobForms extends MFormList {
     result = 31 * result + type.hashCode();
     return result;
   }
+
+  @Override
+  public MJobForms clone(boolean cloneWithValue) {
+    MJobForms copy = new MJobForms(this.type, super.clone(cloneWithValue).getForms());
+    return copy;
+  }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/common/src/main/java/org/apache/sqoop/model/MMapInput.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MMapInput.java b/common/src/main/java/org/apache/sqoop/model/MMapInput.java
index 704c1f8..de17e2d 100644
--- a/common/src/main/java/org/apache/sqoop/model/MMapInput.java
+++ b/common/src/main/java/org/apache/sqoop/model/MMapInput.java
@@ -19,6 +19,7 @@ package org.apache.sqoop.model;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.sqoop.utils.UrlSafeUtils;
 
@@ -103,4 +104,19 @@ public final class MMapInput extends MInput<Map<String, String>> {
   public void setEmpty() {
     setValue(null);
   }
+
+  @Override
+  public MMapInput clone(boolean cloneWithValue) {
+    MMapInput copy = new MMapInput(this.getName(), this.isSensitive());
+    copy.setPersistenceId(this.getPersistenceId());
+    if(cloneWithValue && this.getValue() != null) {
+      Map<String, String> copyMap = new HashMap<String, String>();
+      Set<Map.Entry<String, String>> entry = this.getValue().entrySet();
+      for(Map.Entry<String, String> itr : entry) {
+        copyMap.put(itr.getKey(), itr.getValue());
+      }
+      copy.setValue(copyMap);
+    }
+    return copy;
+  }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/common/src/main/java/org/apache/sqoop/model/MStringInput.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/model/MStringInput.java b/common/src/main/java/org/apache/sqoop/model/MStringInput.java
index a437a25..289a4ee 100644
--- a/common/src/main/java/org/apache/sqoop/model/MStringInput.java
+++ b/common/src/main/java/org/apache/sqoop/model/MStringInput.java
@@ -104,4 +104,15 @@ public final class MStringInput extends MInput<String> {
   public void setEmpty() {
     setValue(null);
   }
+
+  @Override
+  public MStringInput clone(boolean cloneWithValue) {
+    MStringInput copy = new MStringInput(this.getName(),
+        this.isSensitive(), this.getMaxLength());
+    copy.setPersistenceId(this.getPersistenceId());
+    if(cloneWithValue) {
+      copy.setValue(this.getValue());
+    }
+    return copy;
+  }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/common/src/test/java/org/apache/sqoop/model/TestMConnection.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMConnection.java b/common/src/test/java/org/apache/sqoop/model/TestMConnection.java
index c3469ff..301ef1d 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMConnection.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMConnection.java
@@ -47,11 +47,37 @@ public class TestMConnection {
     assertEquals(connector2().getForms().get(0), connection.getFrameworkForm("form"));
   }
 
+  @Test
+  public void testClone() {
+    MConnectionForms connectorPart = connector1();
+    MConnectionForms frameworkPart = connector2();
+    MConnection connection = new MConnection(123l, connectorPart, frameworkPart);
+    connection.setPersistenceId(12l);
+    MForm originalForm = connection.getConnectorPart().getForms().get(0);
+    MConnection clone1 = connection.clone(true);
+    assertEquals(123l, clone1.getConnectorId());
+    MForm clonedForm1 = clone1.getConnectorPart().getForms().get(0);
+    assertEquals(clonedForm1.getInputs().get(0).getValue(), originalForm.getInputs().get(0).getValue());
+    assertEquals(clonedForm1.getInputs().get(1).getValue(), originalForm.getInputs().get(1).getValue());
+    assertNotNull(clonedForm1.getInputs().get(0).getValue());
+    assertNotNull(clonedForm1.getInputs().get(1).getValue());
+    assertEquals(connection, clone1);
+    MConnection cloneCopy = clone1.clone(true);
+    assertEquals(clone1, cloneCopy);
+    //Clone without values
+    MConnection clone2 = connection.clone(false);
+    assertNotSame(connection, clone2);
+  }
+
   private MConnectionForms connector1() {
     List<MForm> forms = new ArrayList<MForm>();
     MIntegerInput input = new MIntegerInput("INTEGER-INPUT", false);
+    input.setValue(100);
+    MStringInput strInput = new MStringInput("STRING-INPUT",false,(short)20);
+    strInput.setValue("TEST-VALUE");
     List<MInput<?>> list = new ArrayList<MInput<?>>();
     list.add(input);
+    list.add(strInput);
     MForm form = new MForm("FORMNAME", list);
     forms.add(form);
     return new MConnectionForms(forms);

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/common/src/test/java/org/apache/sqoop/model/TestMConnector.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMConnector.java b/common/src/test/java/org/apache/sqoop/model/TestMConnector.java
index 716b124..f3ca317 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMConnector.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMConnector.java
@@ -64,4 +64,48 @@ public class TestMConnector {
       assertTrue(true);
     }
   }
+
+  @Test
+  public void testClone() {
+    List<MForm> forms = new ArrayList<MForm>();
+    MIntegerInput input = new MIntegerInput("INTEGER-INPUT", false);
+    input.setValue(100);
+    MStringInput strInput = new MStringInput("STRING-INPUT",false,(short)20);
+    strInput.setValue("TEST-VALUE");
+    List<MInput<?>> list = new ArrayList<MInput<?>>();
+    list.add(input);
+    list.add(strInput);
+    MForm form = new MForm("FORMNAME", list);
+    forms.add(form);
+    MConnectionForms connectionForms1 = new MConnectionForms(forms);
+    MJobForms jobform1 = new MJobForms(MJob.Type.EXPORT, forms);
+    List<MJobForms> jobFormList = new ArrayList<MJobForms>();
+    jobFormList.add(jobform1);
+    MConnector connector1 = new MConnector("NAME", "CLASSNAME", "1.0",
+        connectionForms1, jobFormList);
+    assertEquals("NAME", connector1.getUniqueName());
+    assertEquals("CLASSNAME", connector1.getClassName());
+    assertEquals("1.0", connector1.getVersion());
+    //Clone with values. Checking values copying after the cloning. But form values will be null
+    MConnector clone1 = connector1.clone(true);
+    assertEquals("NAME", clone1.getUniqueName());
+    assertEquals("CLASSNAME", clone1.getClassName());
+    assertEquals("1.0", clone1.getVersion());
+    MForm clonedForm1 = clone1.getConnectionForms().getForms().get(0);
+    assertNull(clonedForm1.getInputs().get(0).getValue());
+    assertNull(clonedForm1.getInputs().get(1).getValue());
+
+    MForm clonedForm2 = clone1.getJobForms(MJob.Type.EXPORT).getForms().get(0);
+    assertNull(clonedForm2.getInputs().get(0).getValue());
+    assertNull(clonedForm2.getInputs().get(1).getValue());
+
+    //Clone without values. Inputs value will be null after cloning.
+    MConnector clone2 = connector1.clone(false);
+    clonedForm1 = clone2.getConnectionForms().getForms().get(0);
+    assertNull(clonedForm1.getInputs().get(0).getValue());
+    assertNull(clonedForm1.getInputs().get(1).getValue());
+    clonedForm2 = clone2.getJobForms(MJob.Type.EXPORT).getForms().get(0);
+    assertNull(clonedForm2.getInputs().get(0).getValue());
+    assertNull(clonedForm2.getInputs().get(1).getValue());
+  }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/94c91efd/common/src/test/java/org/apache/sqoop/model/TestMJob.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMJob.java b/common/src/test/java/org/apache/sqoop/model/TestMJob.java
index dbc791e..6cbf7a6 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMJob.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMJob.java
@@ -45,4 +45,52 @@ public class TestMJob {
     assertEquals(jobform1, job.getConnectorPart());
     assertEquals(jobform2, job.getFrameworkPart());
   }
+
+  @Test
+  public void testClone() {
+    List<MForm> forms = new ArrayList<MForm>();
+    forms.add(getInputValues());
+    MJobForms jobform1 = new MJobForms(MJob.Type.EXPORT, forms);
+    List<MForm> forms2 = new ArrayList<MForm>();
+    forms2.add(getInputValues());
+    MJobForms jobform2 = new MJobForms(MJob.Type.EXPORT, forms2);
+    MJob job = new MJob(123l, 456l, MJob.Type.EXPORT, jobform1, jobform2);
+    job.setPersistenceId(12l);
+
+    MForm originalForm = job.getConnectorPart().getForms().get(0);
+    //Clone job
+    MJob cloneJob = job.clone(true);
+    assertEquals(12l, cloneJob.getPersistenceId());
+    assertEquals(123l, cloneJob.getConnectorId());
+    assertEquals(456l, cloneJob.getConnectionId());
+    assertEquals(MJob.Type.EXPORT, cloneJob.getType());
+    MForm clonedForm = cloneJob.getConnectorPart().getForms().get(0);
+    assertEquals(clonedForm.getInputs().get(0).getValue(), originalForm.getInputs().get(0).getValue());
+    assertEquals(clonedForm.getInputs().get(1).getValue(), originalForm.getInputs().get(1).getValue());
+    assertNotNull(clonedForm.getInputs().get(0).getValue());
+    assertNotNull(clonedForm.getInputs().get(1).getValue());
+    assertEquals(job, cloneJob);
+
+    //Clone job without value
+    MJob cloneJob1 = job.clone(false);
+    assertEquals(123l, cloneJob1.getConnectorId());
+    assertEquals(456l, cloneJob1.getConnectionId());
+    assertEquals(MJob.Type.EXPORT, cloneJob1.getType());
+    clonedForm = cloneJob1.getConnectorPart().getForms().get(0);
+    assertNull(clonedForm.getInputs().get(0).getValue());
+    assertNull(clonedForm.getInputs().get(1).getValue());
+    assertNotSame(job, cloneJob1);
+  }
+
+  private MForm getInputValues() {
+    MIntegerInput input = new MIntegerInput("INTEGER-INPUT", false);
+    input.setValue(100);
+    MStringInput strInput = new MStringInput("STRING-INPUT",false,(short)20);
+    strInput.setValue("TEST-VALUE");
+    List<MInput<?>> list = new ArrayList<MInput<?>>();
+    list.add(input);
+    list.add(strInput);
+    MForm form = new MForm("FORMNAME", list);
+    return form;
+  }
 }