DYFIProduct.java

package gov.usgs.earthquake.dyfi;

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

import java.io.InputStream;
import java.math.BigDecimal;

/**
 * DYFIProduct object to add additional Product properties based on contents.
 *
 * This subclass of Product provides access to additional DYFI-specific
 * attributes and loads these attributes, as well as additional Product
 * attributes from ShakeMap source XML files.
 */
public class DYFIProduct extends Product {

  /** References the event_data.xml file in the Product */
  public static final String DYFI_EVENT_XML_ATTACHMENT = "event_data.xml";

  /** Attribute for number of responses. Read from XML */
  public static final String DYFI_NUM_RESP_ATTRIBUTE = "nresponses";
  /** Attribute for max intensity. Read from XML */
  public static final String DYFI_MAX_MMI_ATTRIBUTE = "max_intensity";

  /** Internally set number of responses property */
  public static final String DYFI_NUM_RESP_PROPERTY = "numResp";
  /** Internally set max intensity property */
  public static final String DYFI_MAX_MMI_PROPERTY = "maxmmi";

  /**
   * Creates a new DYFIProduct using the given <code>Product</code> as a basis.
   * The given product must have a <code>DYFI_EVENT_XML_ATTACHMENT</code> in order
   * to successfully create a DYFIProduct.
   *
   * @param product The product serving as a basis for this instance.
   */
  public DYFIProduct(final Product product) {
    super(product);

    if (product.getProperties().get(DYFI_NUM_RESP_PROPERTY) == null
        || product.getProperties().get(DYFI_MAX_MMI_PROPERTY) == null) {
      // only load xml if properties not set
      loadEventXml();
    }
  }

  /** Reads in DYFI Event EXL and parses it into a EventDataXMLHandler */
  protected void loadEventXml() {
    // Parse event_data.xml for more information about product
    Content source = getContents().get(DYFI_EVENT_XML_ATTACHMENT);
    if (source == null) {
      throw new IllegalArgumentException(
          "Given product lacked the " + "required file to be a DYFIProduct. (" + DYFI_EVENT_XML_ATTACHMENT + ")");
    }

    EventDataXMLHandler handler = new EventDataXMLHandler(this);
    try (final InputStream in = source.getInputStream()) {
      handler.parse(in);
    } catch (Exception e) {
      throw new IllegalArgumentException(e);
    }
  }

  /**
   * @return The number of felt reports submitted for this event.
   */
  public int getNumResponses() {
    return Integer.parseInt(getProperties().get(DYFI_NUM_RESP_PROPERTY));
  }

  /**
   * Set the number of felt reports submitted for this event.
   *
   * @param numResponses The new number of submitted felt reports.
   * @throws NumberFormatException If the given <code>numResponses</code> could
   *                               not be parsed into an integer.
   */
  public void setNumResponses(final String numResponses) throws NumberFormatException {
    // This is a throw-away line, but makes sure the value being passed
    // at least makes sense; an exception is thrown for garbage input.
    Integer.parseInt(numResponses);

    getProperties().put(DYFI_NUM_RESP_PROPERTY, numResponses);
  }

  /**
   * @return The maximum reported intensity for this event.
   */
  public BigDecimal getMaxMMI() {
    return new BigDecimal(getProperties().get(DYFI_MAX_MMI_PROPERTY));
  }

  /**
   * Sets the maximum reported intensity for this event.
   *
   * @param maxMMI The new maximum reported intensity.
   * @throws NumberFormatException If the given <code>maxMMI</code> could not be
   *                               parsed into a double.
   */
  public void setMaxMMI(final String maxMMI) throws NumberFormatException {
    // This is a throw-away line, but makes sure the value being passed
    // at least makes sense; an exception is thrown for garbage input.
    Double.parseDouble(maxMMI);

    getProperties().put(DYFI_MAX_MMI_PROPERTY, maxMMI);
  }
}