sqoop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From b...@apache.org
Subject svn commit: r1373069 - in /sqoop/branches/sqoop2: client/src/main/java/org/apache/sqoop/client/shell/ common/src/main/java/org/apache/sqoop/json/ common/src/main/java/org/apache/sqoop/model/ common/src/test/java/org/apache/sqoop/json/ common/src/test/j...
Date Tue, 14 Aug 2012 20:37:26 GMT
Author: blee
Date: Tue Aug 14 20:37:26 2012
New Revision: 1373069

URL: http://svn.apache.org/viewvc?rev=1373069&view=rev
Log:
SQOOP-544: Split job metadata for different job types (import, export)

Added:
    sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MConnection.java
    sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MJob.java
    sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/ModelError.java
    sqoop/branches/sqoop2/common/src/test/java/org/apache/sqoop/json/
    sqoop/branches/sqoop2/common/src/test/java/org/apache/sqoop/json/TestConnectorBean.java
    sqoop/branches/sqoop2/common/src/test/java/org/apache/sqoop/model/TestMFramework.java
Modified:
    sqoop/branches/sqoop2/client/src/main/java/org/apache/sqoop/client/shell/ShowConnectorFunction.java
    sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/json/ConnectorBean.java
    sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MConnector.java
    sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MFramework.java
    sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MStringInput.java
    sqoop/branches/sqoop2/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcConnector.java
    sqoop/branches/sqoop2/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcConnectorConstants.java
    sqoop/branches/sqoop2/connector/connector-mysql-jdbc/src/main/java/org/apache/sqoop/connector/mysqljdbc/MySqlJdbcConnector.java
    sqoop/branches/sqoop2/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java
    sqoop/branches/sqoop2/core/src/main/java/org/apache/sqoop/framework/FrameworkManager.java
    sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepositoryHandler.java
    sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaConstants.java
    sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaQuery.java
    sqoop/branches/sqoop2/spi/src/main/java/org/apache/sqoop/connector/spi/SqoopConnector.java

Modified: sqoop/branches/sqoop2/client/src/main/java/org/apache/sqoop/client/shell/ShowConnectorFunction.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/client/src/main/java/org/apache/sqoop/client/shell/ShowConnectorFunction.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/client/src/main/java/org/apache/sqoop/client/shell/ShowConnectorFunction.java (original)
+++ sqoop/branches/sqoop2/client/src/main/java/org/apache/sqoop/client/shell/ShowConnectorFunction.java Tue Aug 14 20:37:26 2012
@@ -30,6 +30,7 @@ import org.apache.sqoop.model.MConnector
 import org.apache.sqoop.model.MForm;
 import org.apache.sqoop.model.MInput;
 import org.apache.sqoop.model.MInputType;
+import org.apache.sqoop.model.MJob;
 import org.apache.sqoop.model.MStringInput;
 import org.codehaus.groovy.tools.shell.IO;
 
@@ -85,7 +86,7 @@ public class ShowConnectorFunction exten
     }
     ConnectorBean connectorBean =
       conntectorRequest.doGet(Environment.getServerUrl(), cid);
-    MConnector[] connectors = connectorBean.getConnectos();
+    MConnector[] connectors = connectorBean.getConnectors();
 
     io.out.println("@|bold " + connectors.length + " connector(s) to show: |@");
     for (int i = 0; i < connectors.length; i++) {
@@ -94,14 +95,23 @@ public class ShowConnectorFunction exten
       io.out.print("Connector with id ");
       io.out.print(connector.getPersistenceId());
       io.out.println(":");
-  
+
       io.out.print("  Name: ");
       io.out.println(connector.getUniqueName());
       io.out.print("  Class: ");
       io.out.println(connector.getClassName());
+      io.out.print("  Supported job types: ");
+      io.out.println(connector.getJobs().keySet().toString());
+
+      displayForms(connector.getConnection().getForms(), "Connection");
 
-      displayForms(connector.getConnectionForms(), "Connection");
-      displayForms(connector.getJobForms(), "Job");
+      for (MJob job : connector.getJobs().values()) {
+        io.out.print("  Forms for job type ");
+        io.out.print(job.getType().name());
+        io.out.println(":");
+
+        displayForms(job.getForms(), "Job");
+      }
     }
 
     io.out.println();
@@ -111,36 +121,36 @@ public class ShowConnectorFunction exten
     Iterator<MForm> fiter = forms.iterator();
     int findx = 1;
     while (fiter.hasNext()) {
-      io.out.print("  ");
+      io.out.print("    ");
       io.out.print(type);
       io.out.print(" form ");
       io.out.print(findx++);
       io.out.println(":");
 
       MForm form = fiter.next();
-      io.out.print("    Name: ");
+      io.out.print("      Name: ");
       io.out.println(form.getName());
 
       List<MInput<?>> inputs = form.getInputs();
       Iterator<MInput<?>> iiter = inputs.iterator();
       int iindx = 1;
       while (iiter.hasNext()) {
-        io.out.print("    Input ");
+        io.out.print("      Input ");
         io.out.print(iindx++);
         io.out.println(":");
 
         MInput<?> input = iiter.next();
-        io.out.print("      Name: ");
+        io.out.print("        Name: ");
         io.out.println(input.getName());
-        io.out.print("      Type: ");
+        io.out.print("        Type: ");
         io.out.println(input.getType());
         if (input.getType() == MInputType.STRING) {
-          io.out.print("      Mask: ");
+          io.out.print("        Mask: ");
           io.out.println(((MStringInput)input).isMasked());
-          io.out.print("      Size: ");
+          io.out.print("        Size: ");
           io.out.println(((MStringInput)input).getMaxLength());
         }
       }
     }
   }
-}
\ No newline at end of file
+}

Modified: sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/json/ConnectorBean.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/json/ConnectorBean.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/json/ConnectorBean.java (original)
+++ sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/json/ConnectorBean.java Tue Aug 14 20:37:26 2012
@@ -20,12 +20,15 @@ package org.apache.sqoop.json;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
+import org.apache.sqoop.model.MConnection;
 import org.apache.sqoop.model.MConnector;
 import org.apache.sqoop.model.MForm;
 import org.apache.sqoop.model.MFormType;
 import org.apache.sqoop.model.MInput;
 import org.apache.sqoop.model.MInputType;
+import org.apache.sqoop.model.MJob;
 import org.apache.sqoop.model.MMapInput;
 import org.apache.sqoop.model.MStringInput;
 import org.json.simple.JSONArray;
@@ -59,7 +62,7 @@ public class ConnectorBean implements Js
   public ConnectorBean() {
   }
 
-  public MConnector[] getConnectos() {
+  public MConnector[] getConnectors() {
     return connectors;
   }
 
@@ -76,8 +79,13 @@ public class ConnectorBean implements Js
       idArray.add(connector.getPersistenceId());
       nameArray.add(connector.getUniqueName());
       classArray.add(connector.getClassName());
-      conFormsArray.add(extractForms(connector.getConnectionForms()));
-      jobFormsArray.add(extractForms(connector.getJobForms()));
+      conFormsArray.add(extractForms(connector.getConnection().getForms()));
+
+      JSONObject jobForms = new JSONObject();
+      for (MJob job : connector.getJobs().values()) {
+        jobForms.put(job.getType().name(), extractForms(job.getForms()));
+      }
+      jobFormsArray.add(jobForms);
     }
 
     JSONObject result = new JSONObject();
@@ -126,6 +134,7 @@ public class ConnectorBean implements Js
   }
 
   @Override
+  @SuppressWarnings("unchecked")
   public void restore(JSONObject jsonObject) {
     JSONArray idArray = (JSONArray) jsonObject.get(ID);
     JSONArray nameArray = (JSONArray) jsonObject.get(NAME);
@@ -141,10 +150,23 @@ public class ConnectorBean implements Js
       String uniqueName = (String) nameArray.get(i);
       String className = (String) classArray.get(i);
 
-      List<MForm> conMForms = restoreForms((JSONArray) conFormsArray.get(i));
-      List<MForm> jobMForms = restoreForms((JSONArray) jobFormsArray.get(i));
+      List<MForm> connForms = restoreForms((JSONArray) conFormsArray.get(i));
+
+      JSONObject jobJson = (JSONObject) jobFormsArray.get(i);
+      List<MJob> jobs = new ArrayList<MJob>();
+      for( Map.Entry entry : (Set<Map.Entry>) jobJson.entrySet()) {
+        //TODO(jarcec): Handle situation when server is supporting operation
+        // that client do not know (server do have newer version than client)
+        MJob.Type type = MJob.Type.valueOf((String) entry.getKey());
+
+        List<MForm> jobForms =
+          restoreForms((JSONArray) jobJson.get(entry.getKey()));
+
+        jobs.add(new MJob(type, jobForms));
+      }
+
       MConnector connector = new MConnector(uniqueName, className,
-          conMForms, jobMForms);
+        new MConnection(connForms), jobs);
       connector.setPersistenceId(persistenceId);
       connectors[i] = connector;
     }

Added: sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MConnection.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MConnection.java?rev=1373069&view=auto
==============================================================================
--- sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MConnection.java (added)
+++ sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MConnection.java Tue Aug 14 20:37:26 2012
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sqoop.model;
+
+import java.util.List;
+
+/**
+ * Metadata describing all required information to build up an connection
+ * object. Both connector and framework will have it's own MConnection part of
+ * metadata.
+ */
+public class MConnection extends MPersistableEntity {
+
+  private final List<MForm> forms;
+
+  public MConnection(List<MForm> forms) {
+    this.forms = forms;
+  }
+
+  public List<MForm> getForms() {
+    return forms;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("connection, forms:");
+    sb.append(forms);
+    return sb.toString();
+  }
+
+  @Override
+  public boolean equals(Object other) {
+    if (other == this) {
+      return true;
+    }
+
+    if (!(other instanceof MConnection)) {
+      return false;
+    }
+
+    MConnection mc = (MConnection) other;
+    return forms.equals(mc.forms);
+  }
+
+  @Override
+  public int hashCode() {
+    int result = super.hashCode();
+    for(MForm form : forms) {
+      result = 31 * result + form.hashCode();
+    }
+
+    return result;
+  }
+}

Modified: sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MConnector.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MConnector.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MConnector.java (original)
+++ sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MConnector.java Tue Aug 14 20:37:26 2012
@@ -23,8 +23,7 @@ import java.util.List;
  * Connector metadata.
  *
  * Includes unique id that identifies connector in metadata store, unique human
- * readable name, corresponding name and all forms for both connections and
- * jobs.
+ * readable name, corresponding name and all forms for all supported job types.
  */
 public final class MConnector extends MFramework {
 
@@ -32,8 +31,8 @@ public final class MConnector extends MF
   private final String className;
 
   public MConnector(String uniqueName, String className,
-      List<MForm> connectionForms, List<MForm> jobForms) {
-    super(connectionForms, jobForms);
+      MConnection connection, List<MJob> jobs) {
+    super(connection, jobs);
 
     if (uniqueName == null || className == null) {
       throw new NullPointerException();
@@ -55,8 +54,11 @@ public final class MConnector extends MF
   public String toString() {
     StringBuilder sb = new StringBuilder("connector-");
     sb.append(uniqueName).append(":").append(getPersistenceId()).append(":");
-    sb.append(className).append("; conn-forms:").append(getConnectionForms());
-    sb.append("; job-forms:").append(getJobForms());
+    sb.append(className);
+    sb.append(", ").append(getConnection().toString());
+    for(MJob entry: getJobs().values()) {
+      sb.append(entry.toString());
+    }
 
     return sb.toString();
   }

Modified: sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MFramework.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MFramework.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MFramework.java (original)
+++ sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MFramework.java Tue Aug 14 20:37:26 2012
@@ -17,31 +17,44 @@
  */
 package org.apache.sqoop.model;
 
-import java.util.ArrayList;
+import org.apache.sqoop.common.SqoopException;
+
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
- * Metadata describing framework options for connections and jobs.
+ * Metadata describing framework options for connection and job for each
+ * supported operation.
  */
 public class MFramework extends MPersistableEntity {
 
-  private final List<MForm> connectionForms;
-  private final List<MForm> jobForms;
-
-  public MFramework(List<MForm> connectionForms, List<MForm> jobForms) {
-    this.connectionForms = new ArrayList<MForm>(connectionForms.size());
-    this.connectionForms.addAll(connectionForms);
+  private final MConnection connection;
+  private final Map<MJob.Type, MJob> jobs;
 
-    this.jobForms = new ArrayList<MForm>(jobForms.size());
-    this.jobForms.addAll(jobForms);
+  public MFramework(MConnection connection, List<MJob> jobs) {
+    this.connection = connection;
+    this.jobs = new HashMap<MJob.Type, MJob>();
+
+    for (MJob job : jobs) {
+      MJob.Type type = job.getType();
+
+      if(this.jobs.containsKey(type)) {
+        throw new SqoopException(ModelError.MODEL_001, "Duplicate entry for"
+          + " job type " + job.getType().name());
+      }
+      this.jobs.put(type, job);
+    }
   }
 
   @Override
   public String toString() {
     StringBuilder sb = new StringBuilder("framework-");
     sb.append(getPersistenceId()).append(":");
-    sb.append("; conn-forms:").append(connectionForms);
-    sb.append("; job-forms:").append(jobForms);
+    sb.append(", ").append(connection.toString());
+    for(MJob entry: jobs.values()) {
+      sb.append(entry.toString());
+    }
 
     return sb.toString();
   }
@@ -56,29 +69,31 @@ public class MFramework extends MPersist
       return false;
     }
 
-    MFramework mc = (MFramework) other;
-    return connectionForms.equals(mc.connectionForms)
-        && jobForms.equals(mc.jobForms);
+    MFramework mo = (MFramework) other;
+    return connection.equals(mo.connection) && jobs.equals(mo.jobs);
   }
 
   @Override
   public int hashCode() {
-    int result = 23;
-    for (MForm cmf : connectionForms) {
-      result = 31 * result + cmf.hashCode();
-    }
-    for (MForm jmf : jobForms) {
-      result = 31 * result + jmf.hashCode();
+    int result = connection.hashCode();
+
+    for(MJob entry: jobs.values()) {
+      result = 31 * result + entry.hashCode();
     }
 
     return result;
   }
 
-  public List<MForm> getConnectionForms() {
-    return connectionForms;
+  public MConnection getConnection() {
+    return connection;
+  }
+
+  public Map<MJob.Type, MJob> getJobs() {
+    return jobs;
   }
 
-  public List<MForm> getJobForms() {
-    return jobForms;
+  public MJob getJob(MJob.Type type) {
+    return jobs.get(type);
   }
 }
+

Added: sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MJob.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MJob.java?rev=1373069&view=auto
==============================================================================
--- sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MJob.java (added)
+++ sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MJob.java Tue Aug 14 20:37:26 2012
@@ -0,0 +1,81 @@
+/**
+ * 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 for specific job type. Internally Sqoop have two different job
+ * metadata for each job type. One for connector and second for framework.
+ */
+public class MJob extends MPersistableEntity {
+
+
+  static public enum Type {
+    IMPORT,
+    EXPORT,
+  }
+
+  private final Type type;
+  private final List<MForm> forms;
+
+  public MJob(Type type, List<MForm> forms) {
+    this.type = type;
+    this.forms = forms;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("job type:").append(type.name());
+    sb.append(", forms: ").append(forms);
+    return sb.toString();
+  }
+
+  public Type getType() {
+    return type;
+  }
+
+  public List<MForm> getForms() {
+    return forms;
+  }
+
+  @Override
+  public boolean equals(Object other) {
+    if (other == this) {
+      return true;
+    }
+
+    if (!(other instanceof MJob)) {
+      return false;
+    }
+
+    MJob mj = (MJob) other;
+    return type.equals(mj.type) && forms.equals(mj.forms);
+  }
+
+  @Override
+  public int hashCode() {
+    int result = super.hashCode();
+    result = 31 * result + type.hashCode();
+    for(MForm form : forms) {
+      result = 31 * result + form.hashCode();
+    }
+
+    return result;
+  }
+}

Modified: sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MStringInput.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MStringInput.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MStringInput.java (original)
+++ sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/MStringInput.java Tue Aug 14 20:37:26 2012
@@ -32,7 +32,6 @@ public final class MStringInput extends 
 
   /**
    * @param name the parameter name
-   * @param label the parameter label
    * @param mask a flag indicating if the string should be masked
    * @param maxLength the maximum length of the string
    */

Added: sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/ModelError.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/ModelError.java?rev=1373069&view=auto
==============================================================================
--- sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/ModelError.java (added)
+++ sqoop/branches/sqoop2/common/src/main/java/org/apache/sqoop/model/ModelError.java Tue Aug 14 20:37:26 2012
@@ -0,0 +1,42 @@
+/**
+ * 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.ErrorCode;
+
+/**
+ *
+ */
+public enum ModelError implements ErrorCode {
+
+  MODEL_001("Attempt to pass two different set of MForms for single job type.");
+
+  private final String message;
+
+  private ModelError(String message) {
+    this.message = message;
+  }
+
+  public String getCode() {
+    return name();
+  }
+
+  public String getMessage() {
+    return message;
+  }
+}

Added: sqoop/branches/sqoop2/common/src/test/java/org/apache/sqoop/json/TestConnectorBean.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/common/src/test/java/org/apache/sqoop/json/TestConnectorBean.java?rev=1373069&view=auto
==============================================================================
--- sqoop/branches/sqoop2/common/src/test/java/org/apache/sqoop/json/TestConnectorBean.java (added)
+++ sqoop/branches/sqoop2/common/src/test/java/org/apache/sqoop/json/TestConnectorBean.java Tue Aug 14 20:37:26 2012
@@ -0,0 +1,103 @@
+/**
+ * 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.json;
+
+import static org.junit.Assert.*;
+
+import org.apache.sqoop.model.MConnection;
+import org.apache.sqoop.model.MConnector;
+import org.apache.sqoop.model.MForm;
+import org.apache.sqoop.model.MInput;
+import org.apache.sqoop.model.MJob;
+import org.apache.sqoop.model.MMapInput;
+import org.apache.sqoop.model.MStringInput;
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ */
+public class TestConnectorBean {
+
+  /**
+   * Test that by JSON serialization followed by deserialization we will get
+   * equal connector object.
+   */
+  @Test
+  public void testSerialization() {
+    // Create testing connector
+    MConnector[] connectors = new MConnector[2];
+    connectors[0] = buildFakeConnector("jdbc");
+    connectors[1] = buildFakeConnector("mysql");
+
+    // Serialize it to JSON object
+    ConnectorBean bean = new ConnectorBean(connectors);
+    JSONObject json = bean.extract();
+
+    // "Move" it across network in text form
+    String string = json.toJSONString();
+
+    // Retrieved transferred object
+    JSONObject retrievedJson = (JSONObject) JSONValue.parse(string);
+    ConnectorBean retrievedBean = new ConnectorBean();
+    retrievedBean.restore(retrievedJson);
+
+    assertEquals(connectors.length, retrievedBean.getConnectors().length);
+    assertEquals(connectors[0], retrievedBean.getConnectors()[0]);
+  }
+
+  protected MConnector buildFakeConnector(String name) {
+    List<MInput<?>> inputs;
+
+    List<MForm> connectionForms = new ArrayList<MForm>();
+    inputs = new ArrayList<MInput<?>>();
+    inputs.add(new MStringInput("url", false, (short) 10));
+    inputs.add(new MStringInput("username", false, (short) 10));
+    inputs.add(new MStringInput("password", false, (short) 10));
+    connectionForms.add(new MForm("connection", inputs));
+
+    inputs = new ArrayList<MInput<?>>();
+    inputs.add(new MMapInput("properties"));
+    connectionForms.add(new MForm("properties", inputs));
+    MConnection connection = new MConnection(connectionForms);
+
+    List<MForm> jobForms = new ArrayList<MForm>();
+    inputs = new ArrayList<MInput<?>>();
+    inputs.add(new MStringInput("A", false, (short) 10));
+    inputs.add(new MStringInput("B", false, (short) 10));
+    inputs.add(new MStringInput("C", false, (short) 10));
+    jobForms.add((new MForm("D", inputs)));
+
+    inputs = new ArrayList<MInput<?>>();
+    inputs.add(new MStringInput("Z", false, (short) 10));
+    inputs.add(new MStringInput("X", false, (short) 10));
+    inputs.add(new MStringInput("Y", false, (short) 10));
+    jobForms.add(new MForm("D", inputs));
+
+    List<MJob> jobs = new ArrayList<MJob>();
+    jobs.add(new MJob(MJob.Type.IMPORT, jobForms));
+
+    return new MConnector(name, name + ".class", connection, jobs);
+  }
+}

Added: sqoop/branches/sqoop2/common/src/test/java/org/apache/sqoop/model/TestMFramework.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/common/src/test/java/org/apache/sqoop/model/TestMFramework.java?rev=1373069&view=auto
==============================================================================
--- sqoop/branches/sqoop2/common/src/test/java/org/apache/sqoop/model/TestMFramework.java (added)
+++ sqoop/branches/sqoop2/common/src/test/java/org/apache/sqoop/model/TestMFramework.java Tue Aug 14 20:37:26 2012
@@ -0,0 +1,46 @@
+/**
+ * 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.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class TestMFramework {
+
+  @Test
+  public void testFailureOnDuplicateJobTypes() {
+    MConnection connection = new MConnection(new ArrayList<MForm>());
+    List<MJob> jobs = new ArrayList<MJob>();
+    jobs.add(new MJob(MJob.Type.IMPORT, new ArrayList<MForm>()));
+    jobs.add(new MJob(MJob.Type.IMPORT, new ArrayList<MForm>()));
+
+    try {
+      new MFramework(connection, jobs);
+      fail("We we're expecting exception for invalid usage");
+    } catch(Exception ex) {
+      // Expected case
+    }
+  }
+}

Modified: sqoop/branches/sqoop2/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcConnector.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcConnector.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcConnector.java (original)
+++ sqoop/branches/sqoop2/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcConnector.java Tue Aug 14 20:37:26 2012
@@ -24,16 +24,20 @@ import java.util.ResourceBundle;
 
 import org.apache.sqoop.job.etl.Exporter;
 import org.apache.sqoop.job.etl.Importer;
+import org.apache.sqoop.model.MConnection;
 import org.apache.sqoop.model.MForm;
 import org.apache.sqoop.model.MInput;
+import org.apache.sqoop.model.MJob;
 import org.apache.sqoop.model.MMapInput;
 import org.apache.sqoop.model.MStringInput;
 import org.apache.sqoop.connector.spi.SqoopConnector;
+import static org.apache.sqoop.connector.jdbc.GenericJdbcConnectorConstants.*;
+
 
 public class GenericJdbcConnector implements SqoopConnector {
 
-  private static final List<MForm> CONNECTION_FORMS = new ArrayList<MForm>();
-  private static final List<MForm> JOB_FORMS = new ArrayList<MForm>();
+  private static final MConnection connection;
+  private static final List<MJob> jobs;
 
   private Importer IMPORTER = new Importer(
       GenericJdbcImportInitializer.class,
@@ -47,35 +51,44 @@ public class GenericJdbcConnector implem
       GenericJdbcExportDestroyer.class);
 
   static {
-    // Build the connection form
-    List<MInput<?>> connFormInputs = new ArrayList<MInput<?>>();
+    // Connection forms
+    List<MForm> forms = new ArrayList<MForm>();
+    List<MInput<?>> inputs = new ArrayList<MInput<?>>();
 
-    MStringInput jdbcDriver = new MStringInput(
-        GenericJdbcConnectorConstants.INPUT_CONN_JDBCDRIVER, false,
+    MStringInput jdbcDriver = new MStringInput(INPUT_CONN_JDBCDRIVER, false,
         (short) 128);
-    connFormInputs.add(jdbcDriver);
+    inputs.add(jdbcDriver);
 
-    MStringInput connectString = new MStringInput(
-        GenericJdbcConnectorConstants.INPUT_CONN_CONNECTSTRING, false,
-        (short) 128);
-    connFormInputs.add(connectString);
+    MStringInput connectString = new MStringInput(INPUT_CONN_CONNECTSTRING,
+      false, (short) 128);
+    inputs.add(connectString);
+
+    MStringInput username = new MStringInput(INPUT_CONN_USERNAME, false,
+      (short) 36);
+    inputs.add(username);
+
+    MStringInput password = new MStringInput(INPUT_CONN_PASSWORD, true,
+      (short) 10);
+    inputs.add(password);
+
+    MMapInput jdbcProperties = new MMapInput(INPUT_CONN_JDBCPROPS);
+    inputs.add(jdbcProperties);
 
-    MStringInput username = new MStringInput(
-        GenericJdbcConnectorConstants.INPUT_CONN_USERNAME, false, (short) 36);
-    connFormInputs.add(username);
+    MForm connForm = new MForm(FORM_CONNECTION, inputs);
+    forms.add(connForm);
 
-    MStringInput password = new MStringInput(
-        GenericJdbcConnectorConstants.INPUT_CONN_PASSWORD, true, (short) 10);
-    connFormInputs.add(password);
+    connection = new MConnection(forms);
 
-    MMapInput jdbcProperties = new MMapInput(
-        GenericJdbcConnectorConstants.INPUT_CONN_JDBCPROPS);
-    connFormInputs.add(jdbcProperties);
+    // Job forms
+    forms = new ArrayList<MForm>();
+    inputs = new ArrayList<MInput<?>>();
 
-    MForm connForm = new MForm(GenericJdbcConnectorConstants.FORM_CONNECTION,
-        connFormInputs);
+    inputs.add(new MStringInput(INPUT_TBL_TABLE, false, (short) 50));
+    forms.add(new MForm(FORM_TABLE, inputs));
 
-    CONNECTION_FORMS.add(connForm);
+    jobs = new ArrayList<MJob>();
+    jobs.add(new MJob(MJob.Type.IMPORT, forms));
+    jobs.add(new MJob(MJob.Type.EXPORT, forms));
   }
 
   @Override
@@ -85,13 +98,13 @@ public class GenericJdbcConnector implem
   }
 
   @Override
-  public List<MForm> getConnectionForms() {
-    return CONNECTION_FORMS;
+  public MConnection getConnection() {
+    return connection;
   }
 
   @Override
-  public List<MForm> getJobForms() {
-    return JOB_FORMS;
+  public List<MJob> getJobs() {
+    return jobs;
   }
 
   @Override

Modified: sqoop/branches/sqoop2/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcConnectorConstants.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcConnectorConstants.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcConnectorConstants.java (original)
+++ sqoop/branches/sqoop2/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcConnectorConstants.java Tue Aug 14 20:37:26 2012
@@ -32,7 +32,7 @@ public final class GenericJdbcConnectorC
   // Connection form
   public static final String FORM_CONNECTION = "form-connection";
 
-  // Connection form input
+  // Connection form inputs
   public static final String INPUT_CONN_JDBCDRIVER = "inp-conn-jdbcdriver";
   public static final String INPUT_CONN_CONNECTSTRING =
       "inp-conn-connectstring";
@@ -40,6 +40,12 @@ public final class GenericJdbcConnectorC
   public static final String INPUT_CONN_PASSWORD = "inp-conn-password";
   public static final String INPUT_CONN_JDBCPROPS = "inp-conn-jdbc-properties";
 
+  // Table form
+  public static final String FORM_TABLE = "table-connection";
+
+  // Table form inputs
+  public static final String INPUT_TBL_TABLE = "inp-tbl-table";
+
   private GenericJdbcConnectorConstants() {
     // Disable explicit object creation
   }

Modified: sqoop/branches/sqoop2/connector/connector-mysql-jdbc/src/main/java/org/apache/sqoop/connector/mysqljdbc/MySqlJdbcConnector.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/connector/connector-mysql-jdbc/src/main/java/org/apache/sqoop/connector/mysqljdbc/MySqlJdbcConnector.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/connector/connector-mysql-jdbc/src/main/java/org/apache/sqoop/connector/mysqljdbc/MySqlJdbcConnector.java (original)
+++ sqoop/branches/sqoop2/connector/connector-mysql-jdbc/src/main/java/org/apache/sqoop/connector/mysqljdbc/MySqlJdbcConnector.java Tue Aug 14 20:37:26 2012
@@ -24,13 +24,15 @@ import java.util.ResourceBundle;
 
 import org.apache.sqoop.job.etl.Exporter;
 import org.apache.sqoop.job.etl.Importer;
+import org.apache.sqoop.model.MConnection;
 import org.apache.sqoop.model.MForm;
 import org.apache.sqoop.connector.spi.SqoopConnector;
+import org.apache.sqoop.model.MJob;
 
 public class MySqlJdbcConnector implements SqoopConnector {
 
   private static final List<MForm> CONNECTION_FORMS = new ArrayList<MForm>();
-  private static final List<MForm> JOB_FORMS = new ArrayList<MForm>();
+  private static final List<MJob> JOBS = new ArrayList<MJob>();
 
   @Override
   public ResourceBundle getBundle(Locale locale) {
@@ -39,14 +41,13 @@ public class MySqlJdbcConnector implemen
   }
 
   @Override
-  public List<MForm> getConnectionForms() {
-    return CONNECTION_FORMS;
+  public MConnection getConnection() {
+    return new MConnection(CONNECTION_FORMS);
   }
 
   @Override
-  public List<MForm> getJobForms() {
-    // TODO Auto-generated method stub
-    return JOB_FORMS;
+  public List<MJob> getJobs() {
+    return JOBS;
   }
 
   @Override

Modified: sqoop/branches/sqoop2/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java (original)
+++ sqoop/branches/sqoop2/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java Tue Aug 14 20:37:26 2012
@@ -88,7 +88,7 @@ public final class ConnectorHandler {
 
     // Initialize Metadata
     mConnector = new MConnector(connectorUniqueName, connectorClassName,
-        connector.getConnectionForms(), connector.getJobForms());
+        connector.getConnection(), connector.getJobs());
 
     if (LOG.isInfoEnabled()) {
       LOG.info("Connector [" + connectorClassName + "] initialized.");

Modified: sqoop/branches/sqoop2/core/src/main/java/org/apache/sqoop/framework/FrameworkManager.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/core/src/main/java/org/apache/sqoop/framework/FrameworkManager.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/core/src/main/java/org/apache/sqoop/framework/FrameworkManager.java (original)
+++ sqoop/branches/sqoop2/core/src/main/java/org/apache/sqoop/framework/FrameworkManager.java Tue Aug 14 20:37:26 2012
@@ -19,9 +19,11 @@ package org.apache.sqoop.framework;
 
 import org.apache.log4j.Logger;
 import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.model.MConnection;
 import org.apache.sqoop.model.MForm;
 import org.apache.sqoop.model.MFramework;
 import org.apache.sqoop.model.MInput;
+import org.apache.sqoop.model.MJob;
 import org.apache.sqoop.model.MStringInput;
 import org.apache.sqoop.repository.RepositoryManager;
 
@@ -41,13 +43,17 @@ public class FrameworkManager {
 
   private static final Logger LOG = Logger.getLogger(FrameworkManager.class);
 
-  private static final List<MForm> CONNECTION_FORMS = new ArrayList<MForm>();
-  private static final List<MForm> JOB_FORMS = new ArrayList<MForm>();
+  private static final MConnection connection;
 
-  private static MFramework mFramework;
+  private static final List<MJob> jobs;
+
+  private static final MFramework mFramework;
 
   static {
-    // Build the connection forms
+
+    List<MForm> conForms = new ArrayList<MForm>();
+
+    // Build the connection forms for import
     List<MInput<?>> connFormInputs = new ArrayList<MInput<?>>();
 
     MStringInput maxConnections = new MStringInput(
@@ -56,9 +62,10 @@ public class FrameworkManager {
 
     MForm connForm = new MForm(FORM_SECURITY, connFormInputs);
 
-    CONNECTION_FORMS.add(connForm);
+    conForms.add(connForm);
+    connection = new MConnection(conForms);
 
-    // Build job forms
+    // Build job forms for import
     List<MInput<?>> jobFormInputs = new ArrayList<MInput<?>>();
 
     MStringInput outputFormat = new MStringInput(INPUT_CONN_MAX_OUTPUT_FORMAT,
@@ -66,14 +73,20 @@ public class FrameworkManager {
     jobFormInputs.add(outputFormat);
 
     MForm jobForm = new MForm(FORM_OUTPUT, jobFormInputs);
-    JOB_FORMS.add(jobForm);
+    List<MForm> jobForms = new ArrayList<MForm>();
+    jobForms.add(jobForm);
+
+    jobs = new ArrayList<MJob>();
+    jobs.add(new MJob(MJob.Type.IMPORT, jobForms));
+    jobs.add(new MJob(MJob.Type.EXPORT, jobForms));
+
+    mFramework = new MFramework(connection, jobs);
   }
 
   public static synchronized void initialize() {
     LOG.trace("Begin connector manager initialization");
 
     // Register framework metadata
-    mFramework = new MFramework(CONNECTION_FORMS, JOB_FORMS);
     RepositoryManager.getRepository().registerFramework(mFramework);
     if (!mFramework.hasPersistenceId()) {
       throw new SqoopException(FrameworkError.FRAMEWORK_0000);

Modified: sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepositoryHandler.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepositoryHandler.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepositoryHandler.java (original)
+++ sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepositoryHandler.java Tue Aug 14 20:37:26 2012
@@ -27,18 +27,22 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import javax.sql.DataSource;
 
 import org.apache.log4j.Logger;
 import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.model.MConnection;
 import org.apache.sqoop.model.MConnector;
 import org.apache.sqoop.model.MForm;
 import org.apache.sqoop.model.MFormType;
 import org.apache.sqoop.model.MFramework;
 import org.apache.sqoop.model.MInput;
 import org.apache.sqoop.model.MInputType;
+import org.apache.sqoop.model.MJob;
 import org.apache.sqoop.model.MMapInput;
 import org.apache.sqoop.model.MStringInput;
 import org.apache.sqoop.repository.JdbcRepositoryContext;
@@ -108,12 +112,15 @@ public class DerbyRepositoryHandler impl
       baseInputStmt = conn.prepareStatement(STMT_INSERT_INPUT_BASE,
           Statement.RETURN_GENERATED_KEYS);
 
-      // Insert connection forms
-      registerForms(connectorId, mc.getConnectionForms(),
-          MFormType.CONNECTION.name(), baseFormStmt, baseInputStmt);
-
-      registerForms(connectorId, mc.getJobForms(),
+      // Register connector forms
+      registerForms(connectorId, null, mc.getConnection().getForms(),
+        MFormType.CONNECTION.name(), baseFormStmt, baseInputStmt);
+
+      // Register all jobs
+      for (MJob job : mc.getJobs().values()) {
+        registerForms(connectorId, job.getType(), job.getForms(),
           MFormType.JOB.name(), baseFormStmt, baseInputStmt);
+      }
 
     } catch (SQLException ex) {
       throw new SqoopException(DerbyRepoError.DERBYREPO_0014,
@@ -282,18 +289,20 @@ public class DerbyRepositoryHandler impl
       String connectorName = rsetBaseConnector.getString(2);
       String connectorClassName = rsetBaseConnector.getString(3);
 
-      List<MForm> connectionForms = new ArrayList<MForm>();
-      List<MForm> jobForms = new ArrayList<MForm>();
-
       formFetchStmt = conn.prepareStatement(STMT_FETCH_FORM_CONNECTOR);
       formFetchStmt.setLong(1, connectorId);
       inputFetchStmt = conn.prepareStatement(STMT_FETCH_INPUT);
 
-      loadForms(shortName, formFetchStmt, inputFetchStmt,
-        connectionForms, jobForms);
+      List<MForm> connectionForms = new ArrayList<MForm>();
+      Map<MJob.Type, List<MForm>> jobForms =
+        new HashMap<MJob.Type, List<MForm>>();
+
+      loadForms(shortName, connectionForms, jobForms,
+        formFetchStmt, inputFetchStmt);
 
       mc = new MConnector(connectorName, connectorClassName,
-          connectionForms, jobForms);
+        new MConnection(connectionForms),
+        convertToJobList(jobForms));
       mc.setPersistenceId(connectorId);
 
       if (rsetBaseConnector.next()) {
@@ -347,12 +356,15 @@ public class DerbyRepositoryHandler impl
       baseInputStmt = conn.prepareStatement(STMT_INSERT_INPUT_BASE,
           Statement.RETURN_GENERATED_KEYS);
 
-      // Insert connection forms
-      registerForms(null, mf.getConnectionForms(),
-          MFormType.CONNECTION.name(), baseFormStmt, baseInputStmt);
-
-      registerForms(null, mf.getJobForms(),
+      // Register connector forms
+      registerForms(null, null, mf.getConnection().getForms(),
+        MFormType.CONNECTION.name(), baseFormStmt, baseInputStmt);
+
+      // Register all jobs
+      for (MJob job : mf.getJobs().values()) {
+        registerForms(null, job.getType(), job.getForms(),
           MFormType.JOB.name(), baseFormStmt, baseInputStmt);
+      }
 
       // We're using hardcoded value for framework metadata as they are
       // represented as NULL in the database.
@@ -388,16 +400,23 @@ public class DerbyRepositoryHandler impl
     PreparedStatement formFetchStmt = null;
     PreparedStatement inputFetchStmt = null;
     try {
-      List<MForm> connectionForms = new ArrayList<MForm>();
-      List<MForm> jobForms = new ArrayList<MForm>();
-
       formFetchStmt = conn.prepareStatement(STMT_FETCH_FORM_FRAMEWORK);
       inputFetchStmt = conn.prepareStatement(STMT_FETCH_INPUT);
 
-      loadForms("Framework metadata", formFetchStmt, inputFetchStmt,
-        connectionForms, jobForms);
+      List<MForm> connectionForms = new ArrayList<MForm>();
+      Map<MJob.Type, List<MForm>> jobForms =
+        new HashMap<MJob.Type, List<MForm>>();
+
+      loadForms("Framework metadata", connectionForms, jobForms,
+        formFetchStmt, inputFetchStmt);
 
-      mf = new MFramework(connectionForms, jobForms);
+      // Return nothing If there aren't any framework metadata
+      if(connectionForms.isEmpty() && jobForms.isEmpty()) {
+        return null;
+      }
+
+      mf = new MFramework(new MConnection(connectionForms),
+        convertToJobList(jobForms));
 
       // We're using hardcoded value for framework metadata as they are
       // represented as NULL in the database.
@@ -425,11 +444,6 @@ public class DerbyRepositoryHandler impl
 
     LOG.debug("Looking up framework metadta found: " + mf);
 
-    // If there aren't any framework metadata
-    if(mf.getConnectionForms().size() == 0 && mf.getJobForms().size() == 0) {
-      return null;
-    }
-
     // Returned loaded framework metadata
     return mf;
   }
@@ -454,8 +468,9 @@ public class DerbyRepositoryHandler impl
    * @param baseInputStmt
    * @throws SQLException
    */
-  private void registerForms(Long connectorId, List<MForm> forms, String type,
-      PreparedStatement baseFormStmt, PreparedStatement baseInputStmt)
+  private void registerForms(Long connectorId, MJob.Type jobType,
+      List<MForm> forms, String type, PreparedStatement baseFormStmt,
+      PreparedStatement baseInputStmt)
           throws SQLException {
     short formIndex = 0;
     for (MForm form : forms) {
@@ -464,9 +479,14 @@ public class DerbyRepositoryHandler impl
       } else {
         baseFormStmt.setLong(1, connectorId);
       }
-      baseFormStmt.setString(2, form.getName());
-      baseFormStmt.setString(3, type);
-      baseFormStmt.setShort(4, formIndex++);
+      if(jobType == null) {
+        baseFormStmt.setNull(2, Types.VARCHAR);
+      } else {
+        baseFormStmt.setString(2, jobType.name());
+      }
+      baseFormStmt.setString(3, form.getName());
+      baseFormStmt.setString(4, type);
+      baseFormStmt.setShort(5, formIndex++);
 
       int baseFormCount = baseFormStmt.executeUpdate();
       if (baseFormCount != 1) {
@@ -585,25 +605,27 @@ public class DerbyRepositoryHandler impl
    * from Derby.
    *
    * @param connectorName Connector name for purpose of printing errors
+   * @param connectionForms List of connection forms that will be filled up
+   * @param jobForms Map with job forms that will be filled up
    * @param formFetchStmt Prepared statement for fetching forms
    * @param inputFetchStmt Prepare statement for fetching inputs
-   * @param connectionForms List of connection forms that will be filled up
-   * @param jobForms List of job forms that will be filled up
    * @throws SQLException In case of any failure on Derby side
    */
   public void loadForms(String connectorName,
-                        PreparedStatement formFetchStmt,
-                        PreparedStatement inputFetchStmt,
                         List<MForm> connectionForms,
-                        List<MForm> jobForms) throws SQLException {
+                        Map<MJob.Type, List<MForm>> jobForms,
+                        PreparedStatement formFetchStmt,
+                        PreparedStatement inputFetchStmt) throws SQLException {
 
+    // Get list of structures from database
     ResultSet rsetForm = formFetchStmt.executeQuery();
     while (rsetForm.next()) {
       long formId = rsetForm.getLong(1);
       long formConnectorId = rsetForm.getLong(2);
-      String formName = rsetForm.getString(3);
-      String formType = rsetForm.getString(4);
-      int formIndex = rsetForm.getInt(5);
+      String operation = rsetForm.getString(3);
+      String formName = rsetForm.getString(4);
+      String formType = rsetForm.getString(5);
+      int formIndex = rsetForm.getInt(6);
       List<MInput<?>> formInputs = new ArrayList<MInput<?>>();
 
       MForm mf = new MForm(formName, formInputs);
@@ -661,11 +683,16 @@ public class DerbyRepositoryHandler impl
         connectionForms.add(mf);
         break;
       case JOB:
-        if (jobForms.size() != formIndex) {
+        MJob.Type jobType = MJob.Type.valueOf(operation);
+        if (!jobForms.containsKey(jobType)) {
+          jobForms.put(jobType, new ArrayList<MForm>());
+        }
+
+        if (jobForms.get(jobType).size() != formIndex) {
           throw new SqoopException(DerbyRepoError.DERBYREPO_0010,
               "connector: " + connectorName + "; form: " + mf);
         }
-        jobForms.add(mf);
+        jobForms.get(jobType).add(mf);
         break;
       default:
         throw new SqoopException(DerbyRepoError.DERBYREPO_0007,
@@ -673,4 +700,17 @@ public class DerbyRepositoryHandler impl
       }
     }
   }
+
+  public List<MJob> convertToJobList(Map<MJob.Type, List<MForm>> l) {
+    List<MJob> ret = new ArrayList<MJob>();
+
+    for (Map.Entry<MJob.Type, List<MForm>> entry : l.entrySet()) {
+      MJob.Type type = entry.getKey();
+      List<MForm> forms = entry.getValue();
+
+      ret.add(new MJob(type, forms));
+    }
+
+    return ret;
+  }
 }

Modified: sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaConstants.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaConstants.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaConstants.java (original)
+++ sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaConstants.java Tue Aug 14 20:37:26 2012
@@ -43,6 +43,8 @@ public final class DerbySchemaConstants 
 
   public static final String COLUMN_SQF_CONNECTOR = "SQF_CONNECTOR";
 
+  public static final String COLUMN_SQF_OPERATION = "SQF_OPERATION";
+
   public static final String COLUMN_SQF_NAME = "SQF_NAME";
 
   public static final String COLUMN_SQF_TYPE = "SQF_TYPE";

Modified: sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaQuery.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaQuery.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaQuery.java (original)
+++ sqoop/branches/sqoop2/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaQuery.java Tue Aug 14 20:37:26 2012
@@ -43,6 +43,7 @@ import static org.apache.sqoop.repositor
  *    +-----------------------------+
  *    | SQF_ID: BIGINT PK AUTO-GEN  |
  *    | SQF_CONNECTOR: BIGINT       | FK SQ_CONNECTOR(SQC_ID),NULL for framework
+ *    | SQF_OPERATION: VARCHAR(32)  | "IMPORT"|"EXPORT"|NULL
  *    | SQF_NAME: VARCHAR(64)       |
  *    | SQF_TYPE: VARCHAR(32)       | "CONNECTION"|"JOB"
  *    | SQF_INDEX: SMALLINT         |
@@ -84,6 +85,7 @@ public final class DerbySchemaQuery {
       "CREATE TABLE " + TABLE_SQ_FORM + " (" + COLUMN_SQF_ID
       + " BIGINT GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1) "
       + "PRIMARY KEY, " + COLUMN_SQF_CONNECTOR + " BIGINT, "
+      + COLUMN_SQF_OPERATION + " VARCHAR(32), "
       + COLUMN_SQF_NAME + " VARCHAR(64), " + COLUMN_SQF_TYPE + " VARCHAR(32), "
       + COLUMN_SQF_INDEX + " SMALLINT, " + " FOREIGN KEY ("
       + COLUMN_SQF_CONNECTOR+ ") REFERENCES " + TABLE_SQ_CONNECTOR + " ("
@@ -110,16 +112,16 @@ public final class DerbySchemaQuery {
   // DML: Fetch all forms for a given connector
   public static final String STMT_FETCH_FORM_CONNECTOR =
       "SELECT " + COLUMN_SQF_ID + ", " + COLUMN_SQF_CONNECTOR + ", "
-      + COLUMN_SQF_NAME + ", " + COLUMN_SQF_TYPE + ", " + COLUMN_SQF_INDEX
-      + " FROM " + TABLE_SQ_FORM + " WHERE " + COLUMN_SQF_CONNECTOR
-      + " = ? ORDER BY " + COLUMN_SQF_INDEX;
+      + COLUMN_SQF_OPERATION + ", " + COLUMN_SQF_NAME + ", " + COLUMN_SQF_TYPE
+      + ", " + COLUMN_SQF_INDEX + " FROM " + TABLE_SQ_FORM + " WHERE "
+      + COLUMN_SQF_CONNECTOR + " = ? ORDER BY " + COLUMN_SQF_INDEX;
 
   // DML: Fetch all framework forms
   public static final String STMT_FETCH_FORM_FRAMEWORK =
       "SELECT " + COLUMN_SQF_ID + ", " + COLUMN_SQF_CONNECTOR + ", "
-      + COLUMN_SQF_NAME + ", " + COLUMN_SQF_TYPE + ", " + COLUMN_SQF_INDEX
-      + " FROM " + TABLE_SQ_FORM + " WHERE " + COLUMN_SQF_CONNECTOR
-      + " IS NULL ORDER BY " + COLUMN_SQF_INDEX;
+      + COLUMN_SQF_OPERATION + ", " + COLUMN_SQF_NAME + ", " + COLUMN_SQF_TYPE
+      + ", " + COLUMN_SQF_INDEX + " FROM " + TABLE_SQ_FORM + " WHERE " +
+      COLUMN_SQF_CONNECTOR + " IS NULL ORDER BY " + COLUMN_SQF_INDEX;
 
   // DML: Fetch inputs for a given form
   public static final String STMT_FETCH_INPUT =
@@ -136,9 +138,9 @@ public final class DerbySchemaQuery {
 
   // DML: Insert form base
   public static final String STMT_INSERT_FORM_BASE =
-      "INSERT INTO " + TABLE_SQ_FORM + " (" + COLUMN_SQF_CONNECTOR
-      + ", " + COLUMN_SQF_NAME + ", " + COLUMN_SQF_TYPE + ", "
-      + COLUMN_SQF_INDEX + ") VALUES ( ?, ?, ?, ?)";
+      "INSERT INTO " + TABLE_SQ_FORM + " (" + COLUMN_SQF_CONNECTOR + ", "
+      + COLUMN_SQF_OPERATION + ", " + COLUMN_SQF_NAME + ", " + COLUMN_SQF_TYPE
+      + ", " + COLUMN_SQF_INDEX + ") VALUES ( ?, ?, ?, ?, ?)";
 
   // DML: Insert form input
   public static final String STMT_INSERT_INPUT_BASE =

Modified: sqoop/branches/sqoop2/spi/src/main/java/org/apache/sqoop/connector/spi/SqoopConnector.java
URL: http://svn.apache.org/viewvc/sqoop/branches/sqoop2/spi/src/main/java/org/apache/sqoop/connector/spi/SqoopConnector.java?rev=1373069&r1=1373068&r2=1373069&view=diff
==============================================================================
--- sqoop/branches/sqoop2/spi/src/main/java/org/apache/sqoop/connector/spi/SqoopConnector.java (original)
+++ sqoop/branches/sqoop2/spi/src/main/java/org/apache/sqoop/connector/spi/SqoopConnector.java Tue Aug 14 20:37:26 2012
@@ -19,11 +19,13 @@ package org.apache.sqoop.connector.spi;
 
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.ResourceBundle;
 
 import org.apache.sqoop.job.etl.Exporter;
 import org.apache.sqoop.job.etl.Importer;
-import org.apache.sqoop.model.MForm;
+import org.apache.sqoop.model.MConnection;
+import org.apache.sqoop.model.MJob;
 
 /**
  * Service provider interface for Sqoop Connectors.
@@ -37,17 +39,14 @@ public interface SqoopConnector {
   public ResourceBundle getBundle(Locale locale);
 
   /**
-   * @return a list of <tt>MForm</tt> that provide metadata about input needed
-   * by Sqoop to create a connection object using this connector.
+   * @return Get connection structure
    */
-  public List<MForm> getConnectionForms();
-
+  public MConnection getConnection();
 
   /**
-   * @return a list of <tt>MForm</tt> that provide metadata about input needed
-   * by Sqoop to create a job object using this connector.
+   * @return Get supported jobs and their associated data structures
    */
-  public List<MForm> getJobForms();
+  public List<MJob> getJobs();
 
   /**
    * @return an <tt>Importer</tt> that provides classes for performing import.



Mime
View raw message