URLProductStorage.java

  1. /*
  2.  * URLProductStorage
  3.  */
  4. package gov.usgs.earthquake.distribution;

  5. import gov.usgs.earthquake.product.ProductId;

  6. import gov.usgs.earthquake.product.io.BinaryProductHandler;
  7. import gov.usgs.earthquake.product.io.BinaryProductSource;
  8. import gov.usgs.earthquake.product.io.JsonProductHandler;
  9. import gov.usgs.earthquake.product.io.JsonProductSource;
  10. import gov.usgs.earthquake.product.io.ProductSource;
  11. import gov.usgs.earthquake.product.io.ProductHandler;
  12. import gov.usgs.earthquake.product.io.XmlProductSource;
  13. import gov.usgs.earthquake.product.io.XmlProductHandler;
  14. import gov.usgs.util.Config;
  15. import gov.usgs.util.StreamUtils;

  16. import java.io.File;
  17. import java.io.InputStream;
  18. import java.io.OutputStream;

  19. import java.net.URL;
  20. import java.util.logging.Logger;

  21. /**
  22.  * Store products in a file system which is also available at a URL.
  23.  */
  24. public class URLProductStorage extends FileProductStorage {

  25.     /** Different types of formats */
  26.     public enum Format {
  27.         /** Enum for BINARY/bin format */
  28.         BINARY("bin"),
  29.         /** Enum for JSON format */
  30.         JSON("json"),
  31.         /** Enum for XML format */
  32.         XML("xml");

  33.         private String value;

  34.         private Format(final String value) {
  35.             this.value = value;
  36.         }

  37.         public String toString() {
  38.             return this.value;
  39.         }

  40.         /**
  41.          * Takes a string value and returns ENUM of its format
  42.          * @param value String
  43.          * @return Format ENUM
  44.          */
  45.         public static Format fromString(final String value) {
  46.             if (BINARY.value.equals(value)) {
  47.                 return BINARY;
  48.             } else if (JSON.value.equals(value)) {
  49.                 return JSON;
  50.             } else if (XML.value.equals(value)) {
  51.                 return XML;
  52.             } else {
  53.                 throw new IllegalArgumentException("Invalid format");
  54.             }
  55.         }
  56.     };

  57.     private static final Logger LOGGER = Logger
  58.             .getLogger(URLProductStorage.class.getName());

  59.     /** Property name representing base URL. */
  60.     public static final String URL_PROPERTY_NAME = "url";

  61.     /** The URL which corresponds to baseDirectory. */
  62.     private URL baseURL;

  63.     /** Property for storageFormat */
  64.     public static final String STORAGE_FORMAT_PROPERTY = "storageFormat";

  65.     /** Property for storagePath */
  66.     public static final String STORAGE_PATH_PROPERTY = "storagePath";
  67.     /** Sets up default storage path */
  68.     public static final String DEFAULT_STORAGE_PATH = "{source}_{type}_{code}_{updateTime}.{format}";

  69.     /** (Deprecated, use STORAGE_PATH) Property name to configure binary or xml format. */
  70.     public static final String BINARY_FORMAT_PROPERTY = "binaryFormat";
  71.     /** Default value for whether to use binary format. */
  72.     public static final String BINARY_FORMAT_DEFAULT = "false";

  73.     private Format storageFormat = Format.XML;
  74.     private String storagePath = DEFAULT_STORAGE_PATH;

  75.     /**
  76.      * Constructor for the Configurable interface.
  77.      */
  78.     public URLProductStorage() {
  79.     }

  80.     /**
  81.      * Construct a new ProductStorage object
  82.      *
  83.      * @param baseDirectory
  84.      *            the storage directory where products are stored.
  85.      * @param baseURL
  86.      *            the url where storage directory is available.
  87.      */
  88.     public URLProductStorage(final File baseDirectory, final URL baseURL) {
  89.         super(baseDirectory);
  90.         this.baseURL = baseURL;
  91.     }

  92.     /**
  93.      * Load the baseURL from configuration.
  94.      *
  95.      * @param config
  96.      *            the configuration object.
  97.      */
  98.     public void configure(final Config config) throws Exception {
  99.         super.configure(config);

  100.         String urlString = config.getProperty(URL_PROPERTY_NAME);
  101.         if (urlString == null) {
  102.             throw new ConfigurationException("[" + getName()
  103.                     + "] 'url' is a required configuration property");
  104.         }
  105.         baseURL = new URL(urlString);
  106.         LOGGER.config("[" + getName() + "] base url is '" + baseURL.toString()
  107.                 + "'");

  108.         String format = config.getProperty(STORAGE_FORMAT_PROPERTY);
  109.         if (format != null) {
  110.             storageFormat = Format.fromString(format);
  111.         } else {
  112.             if (Boolean.valueOf(config.getProperty(
  113.                     BINARY_FORMAT_PROPERTY,
  114.                     BINARY_FORMAT_DEFAULT))) {
  115.                 storageFormat = Format.BINARY;
  116.             } else {
  117.                 storageFormat = Format.XML;
  118.             }
  119.         }
  120.         LOGGER.config("[" + getName() + "] using format " + storageFormat);

  121.         storagePath = config.getProperty(STORAGE_PATH_PROPERTY, DEFAULT_STORAGE_PATH);
  122.         LOGGER.config("[" + getName() + "] using path " + storagePath);
  123.     }

  124.     /**
  125.      * Compute the URL to a product.
  126.      *
  127.      * @param id
  128.      *            which product.
  129.      * @return the URL to a product.
  130.      * @throws Exception if error occurs
  131.      */
  132.     public URL getProductURL(final ProductId id) throws Exception {
  133.         return new URL(baseURL, getProductPath(id));
  134.     }

  135.     /**
  136.      * A method for subclasses to override the storage path.
  137.      *
  138.      * The returned path is appended to the base directory when storing and
  139.      * retrieving products.
  140.      *
  141.      * @param id
  142.      *            the product id to convert.
  143.      * @return the directory used to store id.
  144.      */
  145.     @Override
  146.     public String getProductPath(final ProductId id) {
  147.         String path = storagePath;
  148.         path = path.replace("{source}", id.getSource());
  149.         path = path.replace("{type}", id.getType());
  150.         path = path.replace("{code}", id.getCode());
  151.         path = path.replace("{updateTime}", Long.toString(id.getUpdateTime().getTime()));
  152.         path = path.replace("{format}", storageFormat.toString());
  153.         return path;
  154.     }

  155.     /**
  156.      * A method for subclasses to override the storage format.
  157.      *
  158.      * When overriding this method, the method getProductInputForFile should
  159.      * also be overridden.
  160.      *
  161.      * @param file
  162.      *            a file that should be converted into a ProductOutput.
  163.      * @return the ProductOutput.
  164.      */
  165.     protected ProductHandler getProductHandlerFormat(final File file)
  166.             throws Exception {
  167.         OutputStream out = StreamUtils.getOutputStream(file);
  168.         if (storageFormat == Format.BINARY) {
  169.             return new BinaryProductHandler(out);
  170.         } else if (storageFormat == Format.JSON) {
  171.             return new JsonProductHandler(out);
  172.         } else {
  173.             return new XmlProductHandler(out);
  174.         }
  175.     }

  176.     /**
  177.      * A method for subclasses to override the storage format.
  178.      *
  179.      * When overriding this method, the method getProductOutputForFile should
  180.      * also be overridden.
  181.      *
  182.      * @param file
  183.      *            a file that should be converted into a ProductInput.
  184.      * @return the ProductInput.
  185.      */
  186.     protected ProductSource getProductSourceFormat(final File file)
  187.             throws Exception {
  188.         InputStream in = StreamUtils.getInputStream(file);
  189.         if (storageFormat == Format.BINARY) {
  190.             return new BinaryProductSource(in);
  191.         } else if (storageFormat == Format.JSON) {
  192.             return new JsonProductSource(in);
  193.         } else {
  194.             return new XmlProductSource(in);
  195.         }
  196.     }

  197.     /** @return storageFormat */
  198.     public Format getStorageFormat() {
  199.         return this.storageFormat;
  200.     }

  201.     /** @param format set a storageFormat */
  202.     public void setStorageFormat(final Format format) {
  203.         this.storageFormat = format;
  204.     }

  205.     /** @return storagePath */
  206.     public String getStoragePath() {
  207.         return this.storagePath;
  208.     }

  209.     /** @param path set a string as the storagePath */
  210.     public void setStoragePath(final String path) {
  211.         this.storagePath = path;
  212.     }

  213. }