URLProductStorage.java
/*
* URLProductStorage
*/
package gov.usgs.earthquake.distribution;
import gov.usgs.earthquake.product.ProductId;
import gov.usgs.earthquake.product.io.BinaryProductHandler;
import gov.usgs.earthquake.product.io.BinaryProductSource;
import gov.usgs.earthquake.product.io.JsonProductHandler;
import gov.usgs.earthquake.product.io.JsonProductSource;
import gov.usgs.earthquake.product.io.ProductSource;
import gov.usgs.earthquake.product.io.ProductHandler;
import gov.usgs.earthquake.product.io.XmlProductSource;
import gov.usgs.earthquake.product.io.XmlProductHandler;
import gov.usgs.util.Config;
import gov.usgs.util.StreamUtils;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.logging.Logger;
/**
* Store products in a file system which is also available at a URL.
*/
public class URLProductStorage extends FileProductStorage {
/** Different types of formats */
public enum Format {
/** Enum for BINARY/bin format */
BINARY("bin"),
/** Enum for JSON format */
JSON("json"),
/** Enum for XML format */
XML("xml");
private String value;
private Format(final String value) {
this.value = value;
}
public String toString() {
return this.value;
}
/**
* Takes a string value and returns ENUM of its format
* @param value String
* @return Format ENUM
*/
public static Format fromString(final String value) {
if (BINARY.value.equals(value)) {
return BINARY;
} else if (JSON.value.equals(value)) {
return JSON;
} else if (XML.value.equals(value)) {
return XML;
} else {
throw new IllegalArgumentException("Invalid format");
}
}
};
private static final Logger LOGGER = Logger
.getLogger(URLProductStorage.class.getName());
/** Property name representing base URL. */
public static final String URL_PROPERTY_NAME = "url";
/** The URL which corresponds to baseDirectory. */
private URL baseURL;
/** Property for storageFormat */
public static final String STORAGE_FORMAT_PROPERTY = "storageFormat";
/** Property for storagePath */
public static final String STORAGE_PATH_PROPERTY = "storagePath";
/** Sets up default storage path */
public static final String DEFAULT_STORAGE_PATH = "{source}_{type}_{code}_{updateTime}.{format}";
/** (Deprecated, use STORAGE_PATH) Property name to configure binary or xml format. */
public static final String BINARY_FORMAT_PROPERTY = "binaryFormat";
/** Default value for whether to use binary format. */
public static final String BINARY_FORMAT_DEFAULT = "false";
private Format storageFormat = Format.XML;
private String storagePath = DEFAULT_STORAGE_PATH;
/**
* Constructor for the Configurable interface.
*/
public URLProductStorage() {
}
/**
* Construct a new ProductStorage object
*
* @param baseDirectory
* the storage directory where products are stored.
* @param baseURL
* the url where storage directory is available.
*/
public URLProductStorage(final File baseDirectory, final URL baseURL) {
super(baseDirectory);
this.baseURL = baseURL;
}
/**
* Load the baseURL from configuration.
*
* @param config
* the configuration object.
*/
public void configure(final Config config) throws Exception {
super.configure(config);
String urlString = config.getProperty(URL_PROPERTY_NAME);
if (urlString == null) {
throw new ConfigurationException("[" + getName()
+ "] 'url' is a required configuration property");
}
baseURL = new URL(urlString);
LOGGER.config("[" + getName() + "] base url is '" + baseURL.toString()
+ "'");
String format = config.getProperty(STORAGE_FORMAT_PROPERTY);
if (format != null) {
storageFormat = Format.fromString(format);
} else {
if (Boolean.valueOf(config.getProperty(
BINARY_FORMAT_PROPERTY,
BINARY_FORMAT_DEFAULT))) {
storageFormat = Format.BINARY;
} else {
storageFormat = Format.XML;
}
}
LOGGER.config("[" + getName() + "] using format " + storageFormat);
storagePath = config.getProperty(STORAGE_PATH_PROPERTY, DEFAULT_STORAGE_PATH);
LOGGER.config("[" + getName() + "] using path " + storagePath);
}
/**
* Compute the URL to a product.
*
* @param id
* which product.
* @return the URL to a product.
* @throws Exception if error occurs
*/
public URL getProductURL(final ProductId id) throws Exception {
return new URL(baseURL, getProductPath(id));
}
/**
* A method for subclasses to override the storage path.
*
* The returned path is appended to the base directory when storing and
* retrieving products.
*
* @param id
* the product id to convert.
* @return the directory used to store id.
*/
@Override
public String getProductPath(final ProductId id) {
String path = storagePath;
path = path.replace("{source}", id.getSource());
path = path.replace("{type}", id.getType());
path = path.replace("{code}", id.getCode());
path = path.replace("{updateTime}", Long.toString(id.getUpdateTime().getTime()));
path = path.replace("{format}", storageFormat.toString());
return path;
}
/**
* A method for subclasses to override the storage format.
*
* When overriding this method, the method getProductInputForFile should
* also be overridden.
*
* @param file
* a file that should be converted into a ProductOutput.
* @return the ProductOutput.
*/
protected ProductHandler getProductHandlerFormat(final File file)
throws Exception {
OutputStream out = StreamUtils.getOutputStream(file);
if (storageFormat == Format.BINARY) {
return new BinaryProductHandler(out);
} else if (storageFormat == Format.JSON) {
return new JsonProductHandler(out);
} else {
return new XmlProductHandler(out);
}
}
/**
* A method for subclasses to override the storage format.
*
* When overriding this method, the method getProductOutputForFile should
* also be overridden.
*
* @param file
* a file that should be converted into a ProductInput.
* @return the ProductInput.
*/
protected ProductSource getProductSourceFormat(final File file)
throws Exception {
InputStream in = StreamUtils.getInputStream(file);
if (storageFormat == Format.BINARY) {
return new BinaryProductSource(in);
} else if (storageFormat == Format.JSON) {
return new JsonProductSource(in);
} else {
return new XmlProductSource(in);
}
}
/** @return storageFormat */
public Format getStorageFormat() {
return this.storageFormat;
}
/** @param format set a storageFormat */
public void setStorageFormat(final Format format) {
this.storageFormat = format;
}
/** @return storagePath */
public String getStoragePath() {
return this.storagePath;
}
/** @param path set a string as the storagePath */
public void setStoragePath(final String path) {
this.storagePath = path;
}
}