Review Board 1.7.22


SQOOP-623: Add support for loading Map inputs in Sqoop2

Review Request #7490 - Created Oct. 8, 2012 and submitted

Jarek Cecho
SQOOP-623
Reviewers
Sqoop
sqoop-sqoop2
I've implemented handler for MMapInput class.
No new unit tests introduced, just manual testing.

Diff revision 2 (Latest)

1 2
1 2

  1. client/src/main/java/org/apache/sqoop/client/utils/FormFiller.java: Loading...
client/src/main/java/org/apache/sqoop/client/utils/FormFiller.java
Revision df39291 New Change
[20] 20 lines
[+20]
21
import org.apache.sqoop.client.core.Environment;
21
import org.apache.sqoop.client.core.Environment;
22
import org.apache.sqoop.model.MConnection;
22
import org.apache.sqoop.model.MConnection;
23
import org.apache.sqoop.model.MForm;
23
import org.apache.sqoop.model.MForm;
24
import org.apache.sqoop.model.MInput;
24
import org.apache.sqoop.model.MInput;
25
import org.apache.sqoop.model.MIntegerInput;
25
import org.apache.sqoop.model.MIntegerInput;

    
   
26
import org.apache.sqoop.model.MMapInput;
26
import org.apache.sqoop.model.MJob;
27
import org.apache.sqoop.model.MJob;
27
import org.apache.sqoop.model.MStringInput;
28
import org.apache.sqoop.model.MStringInput;
28
import org.codehaus.groovy.tools.shell.IO;
29
import org.codehaus.groovy.tools.shell.IO;
29

    
   
30

   
30
import java.io.IOException;
31
import java.io.IOException;
31
import java.util.List;
32
import java.util.List;

    
   
33
import java.util.Map;

    
   
34
import java.util.HashMap;
32
import java.util.ResourceBundle;
35
import java.util.ResourceBundle;
33

    
   
36

   
34
/**
37
/**
35
 * Convenient methods for retrieving user input.
38
 * Convenient methods for retrieving user input.
36
 */
39
 */
[+20] [20] 137 lines
[+20] [+] public static boolean fillInput(IO io,
174
    switch (input.getType()) {
177
    switch (input.getType()) {
175
      case STRING:
178
      case STRING:
176
        return fillInputString(io, (MStringInput) input, reader, bundle);
179
        return fillInputString(io, (MStringInput) input, reader, bundle);
177
      case INTEGER:
180
      case INTEGER:
178
        return fillInputInteger(io, (MIntegerInput) input, reader, bundle);
181
        return fillInputInteger(io, (MIntegerInput) input, reader, bundle);
179
      //TODO(jarcec): Support MAP
182
      case MAP:

    
   
183
        return fillInputMap(io, (MMapInput)input, reader, bundle);
180
      default:
184
      default:
181
        io.out.println("Unsupported data type " + input.getType());
185
        io.out.println("Unsupported data type " + input.getType());
182
        return true;
186
        return true;
183
    }
187
    }
184
  }
188
  }
185

    
   
189

   

    
   
190
  /**

    
   
191
   * Load user input for map type.

    
   
192
   *

    
   
193
   * This implementation will load one map entry at the time. Current flows is

    
   
194
   * as follows: if user did not enter anything (empty input) finish loading

    
   
195
   * and return from function. If user specified input with equal sign (=),

    
   
196
   * lets add new key value pair. Otherwise consider entire input as a key name

    
   
197
   * and try to remove it from the map.

    
   
198
   *

    
   
199
   * Please note that following code do not supports equal sign in property

    
   
200
   * name. It's however perfectly fine to have equal sign in value.

    
   
201
   *

    
   
202
   * @param io Shell's IO object

    
   
203
   * @param input Input that we should read or edit

    
   
204
   * @param reader Associated console reader

    
   
205
   * @param bundle Resource bundle

    
   
206
   * @return True if user wish to continue with loading additional inputs

    
   
207
   * @throws IOException

    
   
208
   */

    
   
209
  private static boolean fillInputMap(IO io,

    
   
210
                                      MMapInput input,

    
   
211
                                      ConsoleReader reader,

    
   
212
                                      ResourceBundle bundle)

    
   
213
                                      throws IOException {

    
   
214
    // Special prompt in Map case

    
   
215
    io.out.println(bundle.getString(input.getLabelKey()) + ": ");

    
   
216

   

    
   
217
    // Internal loading map

    
   
218
    Map<String, String> values = input.getValue();

    
   
219
    if(values == null) {

    
   
220
      values = new HashMap<String, String>();

    
   
221
    }

    
   
222

   

    
   
223
    String userTyped;

    
   
224

   

    
   
225
    while(true) {

    
   
226
      // Print all current items in each iteration

    
   
227
      io.out.println("There are currently " + values.size()

    
   
228
        + " values in the map:");

    
   
229
      for(Map.Entry<String, String> entry : values.entrySet()) {

    
   
230
        io.out.println(entry.getKey() + " = " + entry.getValue());

    
   
231
      }

    
   
232

   

    
   
233
      // Special prompt for Map entry

    
   
234
      reader.printString("entry# ");

    
   
235
      reader.flushConsole();

    
   
236

   

    
   
237
      userTyped = reader.readLine();

    
   
238

   

    
   
239
      if(userTyped == null) {

    
   
240
        // Finish loading and return back to Sqoop shell

    
   
241
        return false;

    
   
242
      } else if(userTyped.isEmpty()) {

    
   
243
        // User has finished loading data to Map input, either set input empty

    
   
244
        // if there are no entries or propagate entries to the input

    
   
245
        if(values.size() == 0) {

    
   
246
          input.setEmpty();

    
   
247
        } else {

    
   
248
          input.setValue(values);

    
   
249
        }

    
   
250
        return true;

    
   
251
      } else {

    
   
252
        // User has specified regular input, let's check if it contains equals

    
   
253
        // sign. Save new entry (or update existing one) if it does. Otherwise

    
   
254
        // try to remove entry that user specified.

    
   
255
        if(userTyped.contains("=")) {

    
   
256
          String []keyValue = userTyped.split("=", 2);

    
   
257
          values.put(handleUserInput(keyValue[0]), handleUserInput(keyValue[1]));

    
   
258
        } else {

    
   
259
          String key = handleUserInput(userTyped);

    
   
260
          if(values.containsKey(key)) {

    
   
261
            values.remove(key);

    
   
262
          } else {

    
   
263
            errorMessage(io, "Don't know what to do with " + userTyped);

    
   
264
          }

    
   
265
        }

    
   
266
      }

    
   
267

   

    
   
268
    }

    
   
269
  }

    
   
270

   

    
   
271
  /**

    
   
272
   * Handle special cases in user input.

    
   
273
   *

    
   
274
   * Preserve null and empty values, remove whitespace characters before and

    
   
275
   * after loaded string and de-quote the string if it's quoted (to preserve

    
   
276
   * spaces for example).

    
   
277
   *

    
   
278
   * @param input String loaded from user

    
   
279
   * @return Unquoted transformed string

    
   
280
   */

    
   
281
  private static String handleUserInput(String input) {

    
   
282
    // Preserve null and empty values

    
   
283
    if(input == null) {

    
   
284
      return null;

    
   
285
    }

    
   
286
    if(input.isEmpty()) {

    
   
287
      return input;

    
   
288
    }

    
   
289

   

    
   
290
    // Removes empty characters at the begging and end of loaded string

    
   
291
    input = input.trim();

    
   
292

   

    
   
293
    int lastIndex = input.length() - 1;

    
   
294
    char first = input.charAt(0);

    
   
295
    char last = input.charAt(lastIndex);

    
   
296

   

    
   
297
    // Remove quoting if present

    
   
298
    if(first == '\'' && last == '\'') {

    
   
299
      input = input.substring(1, lastIndex);

    
   
300
    } else if(first == '"' && last == '"') {

    
   
301
      input =  input.substring(1, lastIndex);

    
   
302
    }

    
   
303

   

    
   
304
    // Return final string

    
   
305
    return input;

    
   
306
  }

    
   
307

   
186
  private static boolean fillInputInteger(IO io,
308
  private static boolean fillInputInteger(IO io,
187
                                          MIntegerInput input,
309
                                          MIntegerInput input,
188
                                          ConsoleReader reader,
310
                                          ConsoleReader reader,
189
                                          ResourceBundle bundle)
311
                                          ResourceBundle bundle)
190
                                          throws IOException {
312
                                          throws IOException {
[+20] [20] 100 lines
  1. client/src/main/java/org/apache/sqoop/client/utils/FormFiller.java: Loading...