DefaultIndexerModule.java

  1. /*
  2.  * DefaultIndexerModule
  3.  */
  4. package gov.usgs.earthquake.indexer;

  5. import gov.usgs.earthquake.distribution.ContinuableListenerException;
  6. import gov.usgs.earthquake.distribution.SignatureVerifier;
  7. import gov.usgs.earthquake.geoserve.ANSSRegionsFactory;
  8. import gov.usgs.earthquake.product.Product;
  9. import gov.usgs.earthquake.qdm.Point;
  10. import gov.usgs.earthquake.qdm.Regions;
  11. import gov.usgs.util.Config;
  12. import gov.usgs.util.DefaultConfigurable;
  13. import gov.usgs.util.StringUtils;

  14. import java.math.BigDecimal;
  15. import java.util.ArrayList;
  16. import java.util.List;
  17. import java.util.logging.Logger;

  18. /**
  19.  * Default implementation of the IndexerModule interface, implements ANSS
  20.  * Authoritative Region logic.
  21.  *
  22.  * Provides a basic level of support for any type of product. Creates a
  23.  * ProductSummary using the ProductSummary(product) constructor, which copies
  24.  * all properties, and links from the product.
  25.  */
  26. public class DefaultIndexerModule extends DefaultConfigurable implements IndexerModule {

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

  28.     /** Property for ignoreRegions */
  29.     public static final String IGNORE_REGIONS_PROPERTY = "ignoreRegions";

  30.     /** Initial preferred weight. */
  31.     public static final long DEFAULT_PREFERRED_WEIGHT = 1;

  32.     /** Weight added when product source is same as event source. */
  33.     public static final long SAME_SOURCE_WEIGHT = 5;

  34.     /** Weight added when product author is in its authoritative region. */
  35.     public static final long AUTHORITATIVE_WEIGHT = 100;

  36.     /** Weight added when product refers to an authoritative event. */
  37.     public static final long AUTHORITATIVE_EVENT_WEIGHT = 50;

  38.     /** Weight added when product author has an authoritative region. */
  39.     public static final long ANSS_CONTRIBUTOR_WEIGHT = 1;

  40.     /** Weight added when product author is NEIC. */
  41.     public static final long NEIC_CONTRIBUTOR_WEIGHT = 2;

  42.     /** Signature verifier, configured by indexer. */
  43.     private SignatureVerifier signatureVerifier = new SignatureVerifier();

  44.     private List<String> ignoreRegions = new ArrayList<String>();

  45.     @Override
  46.     public void configure(final Config config) throws Exception {
  47.         final String ignore = config.getProperty(IGNORE_REGIONS_PROPERTY);
  48.         if (ignore != null) {
  49.             ignoreRegions.addAll(StringUtils.split(ignore, ","));
  50.             LOGGER.config("[" + getName() + "] ignore regions = " + ignore);
  51.         }
  52.     }

  53.     /**
  54.      * Create a ProductSummary from a Product.
  55.      *
  56.      * Uses the ProductSummary(Product) constructor, which copies product
  57.      * information. Checks whether product is within its authoritative region, and
  58.      * if so boosts preferredWeight by AUTHORITATIVE_WEIGHT.
  59.      *
  60.      * @param product the product to summarize.
  61.      * @return ProductSummary for Product object.
  62.      */
  63.     public ProductSummary getProductSummary(final Product product) throws Exception {
  64.         ProductSummary summary = new ProductSummary(product);

  65.         // allow sender to assign preferredWeight if we add them to the keychain
  66.         String preferredWeight = product.getProperties().get("preferredWeight");
  67.         if (preferredWeight != null && signatureVerifier.verifySignature(product)) {
  68.             LOGGER.fine("Signature verified, using sender assigned preferredWeight " + preferredWeight);
  69.             summary.setPreferredWeight(Long.valueOf(preferredWeight));
  70.         } else {
  71.             summary.setPreferredWeight(getPreferredWeight(summary));
  72.         }
  73.         return summary;
  74.     }

  75.     /**
  76.      * Calculate the preferred weight for a product summary.
  77.      *
  78.      * This method is called after creating a product summary, but before returning
  79.      * the created summary. It's return value is used to assign the product summary
  80.      * preferred weight.
  81.      *
  82.      * Within each type of product, the summary with the largest preferred weight is
  83.      * considered preferred.
  84.      *
  85.      * @param summary the summary to calculate a preferred weight.
  86.      * @return the absolute preferred weight.
  87.      * @throws Exception if error occurs
  88.      */
  89.     protected long getPreferredWeight(final ProductSummary summary) throws Exception {
  90.         long preferredWeight = DEFAULT_PREFERRED_WEIGHT;

  91.         final String source = summary.getId().getSource();
  92.         final String eventSource = summary.getEventSource();

  93.         // check ignore regions here for subclasses that use this method.
  94.         if (ignoreRegions.contains(source)) {
  95.             // source gets no region boost
  96.             return preferredWeight;
  97.         }

  98.         final Regions regions = ANSSRegionsFactory.getFactory().getRegions();
  99.         if (regions == null) {
  100.             throw new ContinuableListenerException("Unable to load ANSS Authoritative Regions");
  101.         }

  102.         final BigDecimal latitude = summary.getEventLatitude();
  103.         final BigDecimal longitude = summary.getEventLongitude();
  104.         Point location = null;
  105.         if (latitude != null && longitude != null) {
  106.             location = new Point(longitude.doubleValue(), latitude.doubleValue());
  107.         }

  108.         // authoritative check
  109.         if (location != null) {
  110.             if (regions.isAuthor(source, location)) {
  111.                 // based on product source, who authored this product.
  112.                 preferredWeight += AUTHORITATIVE_WEIGHT;
  113.             }
  114.             if (eventSource != null && regions.isAuthor(eventSource, location)) {
  115.                 // based on event source, which event this product is about
  116.                 preferredWeight += AUTHORITATIVE_EVENT_WEIGHT;
  117.             }
  118.         }

  119.         // anss source check
  120.         if (regions.isValidnetID(source)) {
  121.             preferredWeight += ANSS_CONTRIBUTOR_WEIGHT;
  122.         }

  123.         // neic source check
  124.         if (regions.isDefaultNetID(source)) {
  125.             preferredWeight += NEIC_CONTRIBUTOR_WEIGHT;
  126.         }

  127.         // same source check
  128.         if (eventSource != null && eventSource.equalsIgnoreCase(source)) {
  129.             preferredWeight += SAME_SOURCE_WEIGHT;
  130.         }

  131.         return preferredWeight;
  132.     }

  133.     /**
  134.      * Remove "internal-" prefix and "-scenario" suffix from product type".
  135.      *
  136.      * @param type product type.
  137.      * @return base product type (without any known prefix or suffix).
  138.      */
  139.     public String getBaseProductType(String type) {
  140.         if (type.startsWith("internal-")) {
  141.             type = type.replace("internal-", "");
  142.         }

  143.         if (type.endsWith("-scenario")) {
  144.             type = type.replace("-scenario", "");
  145.         }

  146.         return type;
  147.     }

  148.     /** @return ignoreRegions */
  149.     public List<String> getIgnoreRegions() {
  150.         return ignoreRegions;
  151.     }

  152.     /**
  153.      * This module provides a default level of support for any type of product.
  154.      *
  155.      * @param product the product to test.
  156.      * @return IndexerModule.LEVEL_DEFAULT.
  157.      */
  158.     public int getSupportLevel(final Product product) {
  159.         return IndexerModule.LEVEL_DEFAULT;
  160.     }

  161.     /** @return signatureVerifier */
  162.     public SignatureVerifier getSignatureVerifier() {
  163.         return signatureVerifier;
  164.     }

  165.     /** @param signatureVerifier to set */
  166.     public void setSignatureVerifier(SignatureVerifier signatureVerifier) {
  167.         this.signatureVerifier = signatureVerifier;
  168.     }

  169. }