IOUtil.java

  1. package gov.usgs.earthquake.product.io;

  2. import gov.usgs.util.StreamUtils;

  3. import java.io.BufferedInputStream;
  4. import java.io.File;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.util.zip.InflaterInputStream;
  8. import java.util.zip.ZipException;

  9. /**
  10.  * Class with main method for converting from one product format to another.
  11.  */
  12. public class IOUtil {

  13.     /** Argument for input file */
  14.     public static final String INFILE_ARGUMENT = "--infile=";
  15.     /** Argument for input format */
  16.     public static final String INFORMAT_ARGUMENT = "--informat=";

  17.     /** Argument for output file */
  18.     public static final String OUTFILE_ARGUMENT = "--outfile=";
  19.     /** Argument for output format */
  20.     public static final String OUTFORMAT_ARGUMENT = "--outformat=";

  21.     /** Zip format */
  22.     public static final String ZIP_FORMAT = "zip";
  23.     /** XML format */
  24.     public static final String XML_FORMAT = "xml";
  25.     /** Directory format */
  26.     public static final String DIRECTORY_FORMAT = "directory";
  27.     /** Binary format */
  28.     public static final String BINARY_FORMAT = "binary";

  29.     /**
  30.      * Returns a ProductHandler based on the output format
  31.      * @param outformat Output format
  32.      * @param outfile Output file
  33.      * @return a Product Handler
  34.      * @throws IOException if IO error occurs
  35.      */
  36.     public static ProductHandler getProductHandler(final String outformat,
  37.             final File outfile) throws IOException {
  38.         ProductHandler out = null;
  39.         if (outformat.equals(XML_FORMAT)) {
  40.             out = new XmlProductHandler(StreamUtils.getOutputStream(outfile));
  41.         } else if (outformat.equals(ZIP_FORMAT)) {
  42.             out = new ZipProductHandler(StreamUtils.getOutputStream(outfile));
  43.         } else if (outformat.equals(DIRECTORY_FORMAT)) {
  44.             out = new DirectoryProductHandler(outfile);
  45.         } else if (outformat.equals(BINARY_FORMAT)) {
  46.             out = new BinaryProductHandler(StreamUtils.getOutputStream(outfile));
  47.         } else {
  48.             throw new IllegalArgumentException("unknown product format '"
  49.                     + outformat + "'");
  50.         }
  51.         return out;
  52.     }

  53.     /**
  54.      * Returns a product source based on input format
  55.      * @param informat input file format
  56.      * @param infile input file
  57.      * @return a Productsource
  58.      * @throws IllegalArgumentException if informat argument error
  59.      * @throws IOException if error occurs
  60.      */
  61.     public static ProductSource getProductSource(final String informat,
  62.             final File infile) throws IllegalArgumentException, IOException {
  63.         ProductSource in = null;
  64.         if (informat.equals(XML_FORMAT)) {
  65.             in = new XmlProductSource(StreamUtils.getInputStream(infile));
  66.         } else if (informat.equals(ZIP_FORMAT)) {
  67.             in = new ZipProductSource(infile);
  68.         } else if (informat.equals(DIRECTORY_FORMAT)) {
  69.             in = new DirectoryProductSource(infile);
  70.         } else if (informat.equals(BINARY_FORMAT)) {
  71.             in = new BinaryProductSource(StreamUtils.getInputStream(infile));
  72.         } else {
  73.             throw new IllegalArgumentException("unknown product format '"
  74.                     + informat + "'");
  75.         }
  76.         return in;
  77.     }

  78.     /**
  79.      * Auto detect an Xml or Binary product source, that is optionally deflated.
  80.      *
  81.      * @param in
  82.      *            input stream containing optionally deflated xml or binary
  83.      *            product stream.
  84.      * @return ProductSource object.
  85.      * @throws IOException
  86.      *             if neither binary or xml product source is in stream.
  87.      */
  88.     public static ProductSource autoDetectProductSource(final InputStream in)
  89.             throws IOException {
  90.         BufferedInputStream bufferedIn = autoDetectDeflate(in);
  91.         int ch = -1;

  92.         bufferedIn.mark(1024);
  93.         // peek at first character in stream
  94.         ch = bufferedIn.read();
  95.         bufferedIn.reset();

  96.         ProductSource productSource = null;
  97.         // determine product format based on first character in stream
  98.         if (((char) ch) == '<') {
  99.             // xml format
  100.             productSource = new XmlProductSource(bufferedIn);
  101.         } else {
  102.             // binary format
  103.             productSource = new BinaryProductSource(bufferedIn);
  104.         }

  105.         return productSource;
  106.     }

  107.     /**
  108.      * Auto detect an optionally deflated stream.
  109.      *
  110.      * @param in
  111.      *            input stream containing optionally deflated xml or binary
  112.      *            product stream.
  113.      * @return ProductSource object.
  114.      * @throws IOException
  115.      *             if neither binary or xml product source is in stream.
  116.      */
  117.     public static BufferedInputStream autoDetectDeflate(final InputStream in)
  118.             throws IOException {
  119.         // stream used to read product
  120.         BufferedInputStream bufferedIn = new BufferedInputStream(in);

  121.         // detect whether incoming stream is compressed
  122.         bufferedIn.mark(1024);
  123.         try {
  124.             InflaterInputStream iis = new InflaterInputStream(bufferedIn);
  125.             iis.read();
  126.             // must be a deflated stream, reset for reading
  127.             bufferedIn.reset();
  128.             bufferedIn = new BufferedInputStream(new InflaterInputStream(bufferedIn));
  129.         } catch (ZipException ze) {
  130.             // not a deflated stream
  131.             bufferedIn.reset();
  132.         }

  133.         return bufferedIn;
  134.     }

  135.     /**
  136.      * Access into IOUtil
  137.      * Takes arguments, gets product source and handler
  138.      * Streams source to handler
  139.      * @param args CLI args for infile, informat, outfile, outformat
  140.      * @throws Exception if error occurs
  141.      */
  142.     public static void main(final String[] args) throws Exception {
  143.         File infile = null;
  144.         File outfile = null;
  145.         String informat = null;
  146.         String outformat = null;

  147.         // parse arguments
  148.         for (String arg : args) {
  149.             if (arg.startsWith(INFILE_ARGUMENT)) {
  150.                 infile = new File(arg.replace(INFILE_ARGUMENT, ""));
  151.             } else if (arg.startsWith(OUTFILE_ARGUMENT)) {
  152.                 outfile = new File(arg.replace(OUTFILE_ARGUMENT, ""));
  153.             } else if (arg.startsWith(INFORMAT_ARGUMENT)) {
  154.                 informat = arg.replace(INFORMAT_ARGUMENT, "");
  155.             } else if (arg.startsWith(OUTFORMAT_ARGUMENT)) {
  156.                 outformat = arg.replace(OUTFORMAT_ARGUMENT, "");
  157.             }
  158.         }

  159.         if (infile == null || informat == null) {
  160.             printUsage();
  161.             System.exit(1);
  162.         }

  163.         if (outfile == null || outformat == null) {
  164.             printUsage();
  165.             System.exit(1);
  166.         }

  167.         ProductSource in = getProductSource(informat, infile);
  168.         ProductHandler out = getProductHandler(outformat, outfile);
  169.         in.streamTo(out);
  170.     }

  171.     /** CLI usage */
  172.     public static void printUsage() {
  173.         System.err
  174.                 .println("IOUtil --infile=FILE --informat=(xml|directory|zip|binary) --outfile=FILE --outformat=(xml|directory|zip|binary)");
  175.     }

  176. }