DirectoryProductSource.java

/*
 * DirectoryProductSource
 */
package gov.usgs.earthquake.product.io;

import gov.usgs.earthquake.product.Content;
import gov.usgs.earthquake.product.Product;
import gov.usgs.earthquake.product.FileContent;
import gov.usgs.earthquake.product.URLContent;

import gov.usgs.util.StreamUtils;

import java.io.File;
import java.io.InputStream;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Load a product from a Directory.
 *
 * Usually a directory is created using DirectoryProductOutput. It should
 * contain a product xml file named "product.xml". All other files are treated
 * as attachments.
 */
public class DirectoryProductSource implements ProductSource {

  /** The directory this product input references. */
  private File directory;

  private static final Logger LOGGER = Logger.getLogger(DirectoryProductSource.class.getName());

  /**
   * Construct a new DirectoryProductSource object.
   *
   * @param directory the directory containing a product.
   */
  public DirectoryProductSource(final File directory) {
    this.directory = directory;
  }

  /**
   * Load Product from a directory, then send product events to the ProductOutput.
   *
   * @param out the ProductOutput that will receive the product.
   */
  public void streamTo(ProductHandler out) throws Exception {
    InputStream in = null;

    try {
      in = StreamUtils.getInputStream(new File(directory, DirectoryProductHandler.PRODUCT_XML_FILENAME));

      // load product from xml
      Product product = ObjectProductHandler.getProduct(new XmlProductSource(in));

      // Convert URLContent to FileContent
      Map<String, Content> contents = product.getContents();
      Content urlContent;
      boolean foundURLContent = false;
      for (String key : contents.keySet()) {
        urlContent = contents.get(key);
        if (urlContent instanceof URLContent) {
          foundURLContent = true;
          if (!"".equals(key)) {
            File filePath = new File(directory, key);
            if (filePath.exists()) {
              FileContent fileContent = new FileContent(filePath);
              fileContent.setContentType(urlContent.getContentType());
              fileContent.setLastModified(urlContent.getLastModified());
              fileContent.setLength(urlContent.getLength());
              // go direct to file based on key
              contents.put(key, fileContent);
            } else {
              // old way
              contents.put(key, new FileContent((URLContent) urlContent));
            }
          }
        }
      }

      if (!foundURLContent) {
        LOGGER.log(Level.FINER,
            "[DirectoryProductSource] Product does not have any " + " URLContent. Scraping directory for files.");

        // load contents from directory
        contents.putAll(FileContent.getDirectoryContents(directory));

        // except for product.xml which is the product, not its content
        contents.remove(DirectoryProductHandler.PRODUCT_XML_FILENAME);
      }

      // now use ObjectProductInput to send loaded product
      new ObjectProductSource(product).streamTo(out);
    } finally {
      StreamUtils.closeStream(in);
    }
  }

  /**
   * Free any resources associated with this source.
   */
  @Override
  public void close() {
    directory = null;
  }

}