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.      *
  43.      * @param value String
  44.      * @return Format ENUM
  45.      */
  46.     public static Format fromString(final String value) {
  47.       if (BINARY.value.equals(value)) {
  48.         return BINARY;
  49.       } else if (JSON.value.equals(value)) {
  50.         return JSON;
  51.       } else if (XML.value.equals(value)) {
  52.         return XML;
  53.       } else {
  54.         throw new IllegalArgumentException("Invalid format");
  55.       }
  56.     }
  57.   };

  58.   private static final Logger LOGGER = Logger.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.   /**
  70.    * (Deprecated, use STORAGE_PATH) Property name to configure binary or xml
  71.    * format.
  72.    */
  73.   public static final String BINARY_FORMAT_PROPERTY = "binaryFormat";
  74.   /** Default value for whether to use binary format. */
  75.   public static final String BINARY_FORMAT_DEFAULT = "false";

  76.   private Format storageFormat = Format.XML;
  77.   private String storagePath = DEFAULT_STORAGE_PATH;

  78.   /**
  79.    * Constructor for the Configurable interface.
  80.    */
  81.   public URLProductStorage() {
  82.   }

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

  93.   /**
  94.    * Load the baseURL from configuration.
  95.    *
  96.    * @param config 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() + "] 'url' is a required configuration property");
  103.     }
  104.     baseURL = new URL(urlString);
  105.     LOGGER.config("[" + getName() + "] base url is '" + baseURL.toString() + "'");

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

  117.     storagePath = config.getProperty(STORAGE_PATH_PROPERTY, DEFAULT_STORAGE_PATH);
  118.     LOGGER.config("[" + getName() + "] using path " + storagePath);
  119.   }

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

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

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

  168.   /**
  169.    * A method for subclasses to override the storage format.
  170.    *
  171.    * When overriding this method, the method getProductOutputForFile should also
  172.    * be overridden.
  173.    *
  174.    * @param file a file that should be converted into a ProductInput.
  175.    * @return the ProductInput.
  176.    */
  177.   protected ProductSource getProductSourceFormat(final File file) throws Exception {
  178.     InputStream in = StreamUtils.getInputStream(file);
  179.     if (storageFormat == Format.BINARY) {
  180.       return new BinaryProductSource(in);
  181.     } else if (storageFormat == Format.JSON) {
  182.       return new JsonProductSource(in);
  183.     } else {
  184.       return new XmlProductSource(in);
  185.     }
  186.   }

  187.   /** @return storageFormat */
  188.   public Format getStorageFormat() {
  189.     return this.storageFormat;
  190.   }

  191.   /** @param format set a storageFormat */
  192.   public void setStorageFormat(final Format format) {
  193.     this.storageFormat = format;
  194.   }

  195.   /** @return storagePath */
  196.   public String getStoragePath() {
  197.     return this.storagePath;
  198.   }

  199.   /** @param path set a string as the storagePath */
  200.   public void setStoragePath(final String path) {
  201.     this.storagePath = path;
  202.   }

  203. }