TOOLS: Refactor GenerateAreaCodeData.
authorphilip.liard@gmail.com <philip.liard@gmail.com@ee073f10-1060-11df-b6a4-87a95322a99c>
Wed, 19 Oct 2011 12:48:09 +0000 (12:48 +0000)
committerphilip.liard@gmail.com <philip.liard@gmail.com@ee073f10-1060-11df-b6a4-87a95322a99c>
Wed, 19 Oct 2011 12:48:09 +0000 (12:48 +0000)
Review URL: http://codereview.appspot.com/5246051

git-svn-id: http://libphonenumber.googlecode.com/svn/trunk@372 ee073f10-1060-11df-b6a4-87a95322a99c

tools/java/java-build/src/com/google/i18n/phonenumbers/EntryPoint.java
tools/java/java-build/src/com/google/i18n/phonenumbers/geocoding/GenerateAreaCodeData.java
tools/java/java-build/src/com/google/i18n/phonenumbers/geocoding/GenerateAreaCodeDataEntryPoint.java [new file with mode: 0644]
tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar

index fb3a0b1..709cf51 100644 (file)
@@ -16,7 +16,7 @@
 
 package com.google.i18n.phonenumbers;
 
-import com.google.i18n.phonenumbers.geocoding.GenerateAreaCodeData;
+import com.google.i18n.phonenumbers.geocoding.GenerateAreaCodeDataEntryPoint;
 
 /**
  * Entry point class for Java and JavaScript build tools.
@@ -29,7 +29,7 @@ public class EntryPoint {
     boolean status = new CommandDispatcher(args, new Command[] {
       new BuildMetadataJsonFromXml(),
       new BuildMetadataProtoFromXml(),
-      new GenerateAreaCodeData(),
+      new GenerateAreaCodeDataEntryPoint(),
     }).start();
 
     System.exit(status ? 0 : 1);
index 7170c60..47e7fa8 100644 (file)
@@ -16,8 +16,6 @@
 
 package com.google.i18n.phonenumbers.geocoding;
 
-import com.google.i18n.phonenumbers.Command;
-
 import java.io.BufferedInputStream;
 import java.io.BufferedReader;
 import java.io.Closeable;
@@ -54,59 +52,64 @@ import java.util.regex.Pattern;
  *
  * @author Philippe Liard
  */
-public class GenerateAreaCodeData extends Command {
+public class GenerateAreaCodeData {
   // The path to the input directory containing the languages directories.
   private final File inputPath;
-  // The path to the output directory.
-  private final File outputPath;
   private static final int NANPA_COUNTRY_CODE = 1;
   // Pattern used to match the two-letter-long language code contained in the input text file path.
   private static final Pattern LANGUAGE_IN_FILE_PATH_PATTERN =
       Pattern.compile("(.*)(?:[a-z]{2})(/\\d+\\.txt)");
   // Map used to store the English mappings to avoid reading the English text files multiple times.
   private final Map<Integer /* country code */, SortedMap<Integer, String>> englishMaps =
-      new HashMap<Integer, SortedMap<Integer,String>>();
+      new HashMap<Integer, SortedMap<Integer, String>>();
+  // The IO Handler used to output the generated binary files.
+  private final IOHandler ioHandler;
 
   private static final Logger LOGGER = Logger.getLogger(GenerateAreaCodeData.class.getName());
 
   /**
-   * Empty constructor used by the EntryPoint class.
+   * Abstracts the way the generated binary files are created and written.
    */
-  public GenerateAreaCodeData() {
-    inputPath = null;
-    outputPath = null;
-  }
+  abstract static class IOHandler {
+    /**
+     * Adds the provided file to the global output that can be for example a JAR.
+     *
+     * @throws IOException
+     */
+    abstract void addFileToOutput(File file) throws IOException;
 
-  public GenerateAreaCodeData(File inputPath, File outputPath) throws IOException {
-    if (!inputPath.isDirectory()) {
-      throw new IOException("The provided input path does not exist: " +
-                             inputPath.getAbsolutePath());
-    }
-    if (outputPath.exists()) {
-      if (!outputPath.isDirectory()) {
-        throw new IOException("Expected directory: " + outputPath.getAbsolutePath());
+    /**
+     * Creates a new file from the provided path.
+     */
+    abstract File createFile(String path);
+
+    /**
+     * Releases the resources used by the underlying implementation if any.
+     */
+    abstract void close();
+
+    /**
+     * Closes the provided file and logs any potential IOException.
+     */
+    void closeFile(Closeable closeable) {
+      if (closeable == null) {
+        return;
       }
-    } else {
-      if (!outputPath.mkdirs()) {
-        throw new IOException("Could not create directory " + outputPath.getAbsolutePath());
+      try {
+        closeable.close();
+      } catch (IOException e) {
+        LOGGER.log(Level.WARNING, e.getMessage());
       }
     }
-    this.inputPath = inputPath;
-    this.outputPath = outputPath;
   }
 
-  /**
-   * Closes the provided file and log any potential IOException.
-   */
-  private static void closeFile(Closeable closeable) {
-    if (closeable == null) {
-      return;
-    }
-    try {
-      closeable.close();
-    } catch (IOException e) {
-      LOGGER.log(Level.WARNING, e.getMessage());
+  public GenerateAreaCodeData(File inputPath, IOHandler ioHandler) throws IOException {
+    if (!inputPath.isDirectory()) {
+      throw new IOException("The provided input path does not exist: " +
+                             inputPath.getAbsolutePath());
     }
+    this.inputPath = inputPath;
+    this.ioHandler = ioHandler;
   }
 
   /**
@@ -228,12 +231,10 @@ public class GenerateAreaCodeData extends Command {
         }
       });
       for (int prefix : phonePrefixes) {
-        outputFiles.add(
-            new File(outputPath, generateBinaryFilename(prefix, language)));
+        outputFiles.add(ioHandler.createFile(generateBinaryFilename(prefix, language)));
       }
     } else {
-      outputFiles.add(
-          new File(outputPath, generateBinaryFilename(countryCode, language)));
+      outputFiles.add(ioHandler.createFile(generateBinaryFilename(countryCode, language)));
     }
     return outputFiles;
   }
@@ -429,7 +430,7 @@ public class GenerateAreaCodeData extends Command {
         englishMap = readMappingsFromTextFile(englishFileInputStream);
         englishMaps.put(countryCode, englishMap);
       } finally {
-        closeFile(englishFileInputStream);
+        ioHandler.closeFile(englishFileInputStream);
       }
     }
     compressAccordingToEnglishData(englishMap, mappings);
@@ -483,8 +484,9 @@ public class GenerateAreaCodeData extends Command {
             fileOutputStream = new FileOutputStream(outputBinaryFile);
             writeToBinaryFile(mappingsForFile.getValue(), fileOutputStream);
             addConfigurationMapping(availableDataFiles, outputBinaryFile);
+            ioHandler.addFileToOutput(outputBinaryFile);
           } finally {
-            closeFile(fileOutputStream);
+            ioHandler.closeFile(fileOutputStream);
           }
         }
       } catch (RuntimeException e) {
@@ -494,44 +496,21 @@ public class GenerateAreaCodeData extends Command {
       } catch (IOException e) {
         LOGGER.log(Level.SEVERE, e.getMessage());
       } finally {
-        closeFile(fileInputStream);
-        closeFile(fileOutputStream);
+        ioHandler.closeFile(fileInputStream);
+        ioHandler.closeFile(fileOutputStream);
       }
     }
     // Output the binary configuration file mapping country codes to languages.
     FileOutputStream fileOutputStream = null;
     try {
-      File configFile = new File(outputPath, "config");
+      File configFile = ioHandler.createFile("config");
       fileOutputStream = new FileOutputStream(configFile);
       outputBinaryConfiguration(availableDataFiles, fileOutputStream);
+      ioHandler.addFileToOutput(configFile);
     } finally {
-      closeFile(fileOutputStream);
+      ioHandler.closeFile(fileOutputStream);
+      ioHandler.close();
     }
     LOGGER.log(Level.INFO, "Geocoding data successfully generated.");
   }
-
-  @Override
-  public String getCommandName() {
-    return "GenerateAreaCodeData";
-  }
-
-  @Override
-  public boolean start() {
-    String[] args = getArgs();
-
-    if (args.length != 3) {
-      LOGGER.log(Level.SEVERE,
-                 "usage: GenerateAreaCodeData /path/to/input/directory /path/to/output/directory");
-      return false;
-    }
-    try {
-      GenerateAreaCodeData generateAreaCodeData =
-          new GenerateAreaCodeData(new File(args[1]), new File(args[2]));
-      generateAreaCodeData.run();
-    } catch (IOException e) {
-      LOGGER.log(Level.SEVERE, e.getMessage());
-      return false;
-    }
-    return true;
-  }
 }
diff --git a/tools/java/java-build/src/com/google/i18n/phonenumbers/geocoding/GenerateAreaCodeDataEntryPoint.java b/tools/java/java-build/src/com/google/i18n/phonenumbers/geocoding/GenerateAreaCodeDataEntryPoint.java
new file mode 100644 (file)
index 0000000..57acee1
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2011 The Libphonenumber Authors
+ *
+ * Licensed 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 com.google.i18n.phonenumbers.geocoding;
+
+import com.google.i18n.phonenumbers.Command;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Entry point class used to invoke the generation of the binary geocoding data files.
+ *
+ * @author Philippe Liard
+ */
+public class GenerateAreaCodeDataEntryPoint extends Command {
+  private static final Logger LOGGER = Logger.getLogger(GenerateAreaCodeData.class.getName());
+
+  /**
+   * Implementation of the IOHandler required by the GenerateAreaCodeData class used here to create
+   * the output files.
+   */
+  private static class IOHandler extends GenerateAreaCodeData.IOHandler {
+    // The path to the output directory.
+    private final File outputPath;
+
+    public IOHandler(File outputPath) throws IOException {
+      if (outputPath.exists()) {
+        if (!outputPath.isDirectory()) {
+          throw new IOException("Expected directory: " + outputPath.getAbsolutePath());
+        }
+      } else {
+        if (!outputPath.mkdirs()) {
+          throw new IOException("Could not create directory " + outputPath.getAbsolutePath());
+        }
+      }
+      this.outputPath = outputPath;
+    }
+
+    @Override
+    public void addFileToOutput(File file) throws IOException {
+      // Do nothing. This would be the place dealing with the addition of the provided file to the
+      // resulting JAR if the global output was a JAR instead of a directory containing the binary
+      // files.
+    }
+
+    @Override
+    public File createFile(String path) {
+      return new File(outputPath, path);
+    }
+
+    @Override
+    public void close() {
+      // Do nothing as no resource needs to be released.
+    }
+  }
+
+  @Override
+  public String getCommandName() {
+    return "GenerateAreaCodeData";
+  }
+
+  @Override
+  public boolean start() {
+    String[] args = getArgs();
+
+    if (args.length != 3) {
+      LOGGER.log(Level.SEVERE,
+                 "usage: GenerateAreaCodeData /path/to/input/directory /path/to/output/directory");
+      return false;
+    }
+    try {
+      GenerateAreaCodeData generateAreaCodeData =
+          new GenerateAreaCodeData(new File(args[1]), new IOHandler(new File(args[2])));
+      generateAreaCodeData.run();
+    } catch (IOException e) {
+      LOGGER.log(Level.SEVERE, e.getMessage());
+      return false;
+    }
+    return true;
+  }
+}
index 45296a8..febbe34 100644 (file)
Binary files a/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar and b/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar differ