SearchResponseParser.java
- package gov.usgs.earthquake.indexer;
- import java.math.BigDecimal;
- import java.net.URI;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import gov.usgs.earthquake.distribution.FileProductStorage;
- import gov.usgs.earthquake.product.Product;
- import gov.usgs.earthquake.product.ProductId;
- import gov.usgs.earthquake.product.io.XmlProductHandler;
- import gov.usgs.util.XmlUtils;
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
- /**
- * Parser for SearchXML response.
- */
- public class SearchResponseParser extends DefaultHandler {
- private SearchResponse response = null;
- private SearchQuery query = null;
- private ProductSummary pSummary = null;
- private EventSummary eSummary = null;
- private Event event = null;
- private boolean inQueryElement = false;
- private boolean inErrorElement = false;
- private FileProductStorage storage;
- private SearchResponseXmlProductSource productHandler = null;
- /**
- * Constructor
- * @param storage a FileProductStorage
- */
- public SearchResponseParser(final FileProductStorage storage) {
- this.storage = storage;
- }
- /** @return SearchResponse */
- public SearchResponse getSearchResponse() {
- return response;
- }
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
- if (productHandler != null) {
- productHandler.startElement(uri, localName, qName, attributes);
- } else if (SearchXML.INDEXER_XMLNS.equals(uri)) {
- if (SearchXML.RESPONSE_ELEMENT.equals(localName)) {
- response = new SearchResponse();
- } else if (SearchXML.RESULT_ELEMENT.equals(localName)) {
- if (response == null)
- throw new SAXException(
- "Unexpected result element without response element parent.");
- SearchMethod method = SearchMethod.fromXmlMethodName(XmlUtils
- .getAttribute(attributes, uri,
- SearchXML.METHOD_ATTRIBUTE));
- query = SearchQuery.getSearchQuery(method,
- new ProductIndexQuery());
- // create results container now
- if (query instanceof EventDetailQuery) {
- ((EventDetailQuery) query)
- .setResult(new ArrayList<Event>());
- } else if (query instanceof EventsSummaryQuery) {
- ((EventsSummaryQuery) query)
- .setResult(new ArrayList<EventSummary>());
- } else if (query instanceof ProductDetailQuery) {
- ((ProductDetailQuery) query)
- .setResult(new ArrayList<Product>());
- } else if (query instanceof ProductsSummaryQuery) {
- ((ProductsSummaryQuery) query)
- .setResult(new ArrayList<ProductSummary>());
- }
- } else if (SearchXML.QUERY_ELEMENT.equals(localName)) {
- if (query == null)
- throw new SAXException(
- "Unexpected query element without result element parent.");
- inQueryElement = true;
- ProductIndexQuery piQuery = query.getProductIndexQuery();
- // Update the ProductIndexQuery with each given attribute
- // Event Source Attribute
- String eventSource = XmlUtils.getAttribute(attributes, uri,
- SearchXML.EVENT_SOURCE_ATTRIBUTE);
- if (eventSource != null) {
- piQuery.setEventSource(eventSource);
- }
- // Event Source Code Attribute
- String eventSourceCode = XmlUtils.getAttribute(attributes, uri,
- SearchXML.EVENT_SOURCE_CODE_ATTRIBUTE);
- if (eventSourceCode != null) {
- piQuery.setEventSourceCode(eventSourceCode);
- }
- // Max Event Depth Attribute
- String maxEventDepth = XmlUtils.getAttribute(attributes, uri,
- SearchXML.MAX_EVENT_DEPTH_ATTRIBUTE);
- if (maxEventDepth != null) {
- piQuery.setMaxEventDepth(new BigDecimal(maxEventDepth));
- }
- // Max Event Latitude Attribute
- String maxEventLatitude = XmlUtils.getAttribute(attributes,
- uri, SearchXML.MAX_EVENT_LATITUDE_ATTRIBUTE);
- if (maxEventLatitude != null) {
- piQuery.setMaxEventLatitude(new BigDecimal(maxEventLatitude));
- }
- // Max Event Longitude Attribute
- String maxEventLongitude = XmlUtils.getAttribute(attributes,
- uri, SearchXML.MAX_EVENT_LONGITUDE_ATTRIBUTE);
- if (maxEventLongitude != null) {
- piQuery.setMaxEventLongitude(new BigDecimal(
- maxEventLongitude));
- }
- // Max Event Magnitude Attribute
- String maxEventMagnitude = XmlUtils.getAttribute(attributes,
- uri, SearchXML.MAX_EVENT_MAGNITUDE_ATTRIBUTE);
- if (maxEventMagnitude != null) {
- piQuery.setMaxEventMagnitude(new BigDecimal(
- maxEventMagnitude));
- }
- // Max Event Time Attribute
- String maxEventTime = XmlUtils.getAttribute(attributes, uri,
- SearchXML.MAX_EVENT_TIME_ATTRIBUTE);
- if (maxEventTime != null) {
- piQuery.setMaxEventTime(XmlUtils.getDate(maxEventTime));
- }
- // Max Product Update Time Attribute
- String maxProductUpdateTime = XmlUtils.getAttribute(attributes,
- uri, SearchXML.MAX_PRODUCT_UPDATE_TIME_ATTRIBUTE);
- if (maxProductUpdateTime != null) {
- piQuery.setMaxProductUpdateTime(XmlUtils
- .getDate(maxProductUpdateTime));
- }
- // Min Event Depth Attribute
- String minEventDepth = XmlUtils.getAttribute(attributes, uri,
- SearchXML.MIN_EVENT_DEPTH_ATTRIBUTE);
- if (minEventDepth != null) {
- piQuery.setMinEventDepth(new BigDecimal(minEventDepth));
- }
- // Min Event Latitude Attribute
- String minEventLatitude = XmlUtils.getAttribute(attributes,
- uri, SearchXML.MIN_EVENT_LATITUDE_ATTRIBUTE);
- if (minEventLatitude != null) {
- piQuery.setMinEventLatitude(new BigDecimal(minEventLatitude));
- }
- // Min Event Longitude Attribute
- String minEventLongitude = XmlUtils.getAttribute(attributes,
- uri, SearchXML.MIN_EVENT_LONGITUDE_ATTRIBUTE);
- if (minEventLongitude != null) {
- piQuery.setMinEventLongitude(new BigDecimal(
- minEventLongitude));
- }
- // Min Event Magnitude Attribute
- String minEventMagnitude = XmlUtils.getAttribute(attributes,
- uri, SearchXML.MIN_EVENT_MAGNITUDE_ATTRIBUTE);
- if (minEventMagnitude != null) {
- piQuery.setMinEventMagnitude(new BigDecimal(
- minEventMagnitude));
- }
- // Min Event Time Attribute
- String minEventTime = XmlUtils.getAttribute(attributes, uri,
- SearchXML.MIN_EVENT_TIME_ATTRIBUTE);
- if (minEventTime != null) {
- piQuery.setMinEventTime(XmlUtils.getDate(minEventTime));
- }
- // Min Product Update Time Attribute
- String minProductUpdateTime = XmlUtils.getAttribute(attributes,
- uri, SearchXML.MIN_PRODUCT_UPDATE_TIME_ATTRIBUTE);
- if (minProductUpdateTime != null) {
- piQuery.setMinProductUpdateTime(XmlUtils
- .getDate(minProductUpdateTime));
- }
- // Product Code Attribute
- String productCode = XmlUtils.getAttribute(attributes, uri,
- SearchXML.PRODUCT_CODE_ATTRIBUTE);
- if (productCode != null) {
- piQuery.setProductCode(productCode);
- }
- // Product Source Attribute
- String productSource = XmlUtils.getAttribute(attributes, uri,
- SearchXML.PRODUCT_SOURCE_ATTRIBUTE);
- if (productSource != null) {
- piQuery.setProductSource(productSource);
- }
- // Product Status Attribute
- String productStatus = XmlUtils.getAttribute(attributes, uri,
- SearchXML.PRODUCT_STATUS_ATTRIBUTE);
- if (productStatus != null) {
- piQuery.setProductStatus(productStatus);
- }
- // Product Type Attribute
- String productType = XmlUtils.getAttribute(attributes, uri,
- SearchXML.PRODUCT_TYPE_ATTRIBUTE);
- if (productType != null) {
- piQuery.setProductType(productType);
- }
- // Product Version Attribute
- String productVersion = XmlUtils.getAttribute(attributes, uri,
- SearchXML.PRODUCT_VERSION_ATTRIBUTE);
- if (productVersion != null) {
- piQuery.setProductVersion(productVersion);
- }
- // Set result type. At the moment we ony support the "current"
- // type.
- piQuery.setResultType(ProductIndexQuery.RESULT_TYPE_CURRENT);
- } else if (SearchXML.PRODUCT_SUMMARY_ELEMENT.equals(localName)) {
- if (inQueryElement) {
- // This product summary is being used to pass ID information
- // for the query
- ProductIndexQuery piQuery = query.getProductIndexQuery();
- piQuery.getProductIds().add(
- ProductId.parse(XmlUtils.getAttribute(attributes,
- uri, SearchXML.ID_ATTRIBUTE)));
- } else {
- // This is a more complete returned product summary
- pSummary = new ProductSummary();
- // Set the attributes of the ProductSummary
- // Depth attribute
- String depth = XmlUtils.getAttribute(attributes, uri,
- SearchXML.DEPTH_ATTRIBUTE);
- if (depth != null) {
- pSummary.setEventDepth(new BigDecimal(depth));
- }
- // Latitude attribute
- String latitude = XmlUtils.getAttribute(attributes, uri,
- SearchXML.LATITUDE_ATTRIBUTE);
- if (latitude != null) {
- pSummary.setEventLatitude(new BigDecimal(latitude));
- }
- // Longitude attribute
- String longitude = XmlUtils.getAttribute(attributes, uri,
- SearchXML.LONGITUDE_ATTRIBUTE);
- if (longitude != null) {
- pSummary.setEventLongitude(new BigDecimal(longitude));
- }
- // Magnitude attribute
- String magnitude = XmlUtils.getAttribute(attributes, uri,
- SearchXML.MAGNITUDE_ATTRIBUTE);
- if (magnitude != null) {
- pSummary.setEventMagnitude(new BigDecimal(magnitude));
- }
- // Event Source attribute
- String eventSource = XmlUtils.getAttribute(attributes, uri,
- SearchXML.EVENT_SOURCE_ATTRIBUTE);
- if (eventSource != null) {
- pSummary.setEventSource(eventSource);
- }
- // Event Source Code attribute
- String eventSourceCode = XmlUtils.getAttribute(attributes,
- uri, SearchXML.EVENT_SOURCE_CODE_ATTRIBUTE);
- if (eventSourceCode != null) {
- pSummary.setEventSourceCode(eventSourceCode);
- }
- // Time attribute
- String time = XmlUtils.getAttribute(attributes, uri,
- SearchXML.TIME_ATTRIBUTE);
- if (time != null) {
- pSummary.setEventTime(XmlUtils.getDate(time));
- }
- // ID attribute
- String id = XmlUtils.getAttribute(attributes, uri,
- SearchXML.ID_ATTRIBUTE);
- if (id != null) {
- pSummary.setId(ProductId.parse(id));
- }
- // Preferred Weight attribute
- String preferredWeight = XmlUtils.getAttribute(attributes,
- uri, SearchXML.PREFERRED_WEIGHT_ATTRIBUTE);
- if (preferredWeight != null) {
- pSummary.setPreferredWeight(Integer
- .parseInt(preferredWeight));
- }
- // Status attribute
- String status = XmlUtils.getAttribute(attributes, uri,
- SearchXML.STATUS_ATTRIBUTE);
- if (status != null) {
- pSummary.setStatus(status);
- }
- // Version attribute
- String version = XmlUtils.getAttribute(attributes, uri,
- SearchXML.VERSION_ATTRIBUTE);
- if (version != null) {
- pSummary.setVersion(version);
- }
- }
- } else if (SearchXML.EVENT_ELEMENT.equals(localName)) {
- event = new Event();
- // Nothing further needs to be done here as properties are set
- // by ProductSummaries for the event
- } else if (SearchXML.EVENT_SUMMARY_ELEMENT.equals(localName)) {
- eSummary = new EventSummary();
- // Configure EventSummary attributes
- // Depth attribute
- String depth = XmlUtils.getAttribute(attributes, uri,
- SearchXML.DEPTH_ATTRIBUTE);
- if (depth != null) {
- eSummary.setDepth(new BigDecimal(depth));
- }
- // Latitude attribute
- String latitude = XmlUtils.getAttribute(attributes, uri,
- SearchXML.LATITUDE_ATTRIBUTE);
- if (latitude != null) {
- eSummary.setLatitude(new BigDecimal(latitude));
- }
- // Longitude attribute
- String longitude = XmlUtils.getAttribute(attributes, uri,
- SearchXML.LONGITUDE_ATTRIBUTE);
- if (longitude != null) {
- eSummary.setLongitude(new BigDecimal(longitude));
- }
- // Magnitude attribute
- String magnitude = XmlUtils.getAttribute(attributes, uri,
- SearchXML.MAGNITUDE_ATTRIBUTE);
- if (magnitude != null) {
- eSummary.setMagnitude(new BigDecimal(magnitude));
- }
- // Source attribute
- String source = XmlUtils.getAttribute(attributes, uri,
- SearchXML.SOURCE_ATTRIBUTE);
- if (source != null) {
- eSummary.setSource(source);
- }
- // Source code attribute
- String sourceCode = XmlUtils.getAttribute(attributes, uri,
- SearchXML.SOURCE_CODE_ATTRIBUTE);
- if (sourceCode != null) {
- eSummary.setSourceCode(sourceCode);
- }
- // Time attribute
- String time = XmlUtils.getAttribute(attributes, uri,
- SearchXML.TIME_ATTRIBUTE);
- if (time != null) {
- eSummary.setTime(XmlUtils.getDate(time));
- }
- } else if (SearchXML.ERROR_ELEMENT.equals(localName)) {
- inErrorElement = true;
- }
- } else if (XmlProductHandler.PRODUCT_XML_NAMESPACE.equals(uri)) {
- if (XmlProductHandler.PROPERTY_ELEMENT.equals(localName)) {
- if (pSummary != null) {
- // Currently working on a Product Summary
- pSummary.getProperties()
- .put(XmlUtils.getAttribute(attributes, uri,
- XmlProductHandler.PROPERTY_ATTRIBUTE_NAME),
- XmlUtils.getAttribute(
- attributes,
- uri,
- XmlProductHandler.PROPERTY_ATTRIBUTE_VALUE));
- } else if (eSummary != null) {
- // Currently working on an Event Summary
- eSummary.getProperties()
- .put(XmlUtils.getAttribute(attributes, uri,
- XmlProductHandler.PROPERTY_ATTRIBUTE_NAME),
- XmlUtils.getAttribute(
- attributes,
- uri,
- XmlProductHandler.PROPERTY_ATTRIBUTE_VALUE));
- } else if (inQueryElement) {
- // Currently working on a query
- // This is defined in the schema, but not in the class
- // for either query
- } else {
- throw new SAXException(
- "Property element without appropriate parent encountered.");
- }
- } else if (XmlProductHandler.LINK_ELEMENT.equals(localName)) {
- if (pSummary != null) {
- // This link is occurring as part of a product summary
- String relation = XmlUtils.getAttribute(attributes, uri,
- XmlProductHandler.LINK_ATTRIBUTE_RELATION);
- Map<String, List<URI>> links = pSummary.getLinks();
- if (links.containsKey(relation))
- links.get(relation)
- .add(URI.create(XmlUtils.getAttribute(
- attributes, uri,
- XmlProductHandler.LINK_ATTRIBUTE_HREF)));
- else {
- List<URI> newList = new ArrayList<URI>();
- newList.add(URI.create(XmlUtils.getAttribute(
- attributes, uri,
- XmlProductHandler.LINK_ATTRIBUTE_HREF)));
- links.put(relation, newList);
- }
- } else {
- throw new SAXException(
- "Link element without appropriate parent encountered.");
- }
- } else if (XmlProductHandler.PRODUCT_ELEMENT.equals(localName)) {
- // We are starting to process a product and need to pass data
- // through
- // until that is complete.
- productHandler = new SearchResponseXmlProductSource(storage);
- productHandler.startElement(uri, localName, qName, attributes);
- }
- }
- }
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
- if (productHandler != null) {
- productHandler.endElement(uri, localName, qName);
- if (XmlProductHandler.PRODUCT_ELEMENT.equals(localName)) {
- ProductDetailQuery pdQuery = (ProductDetailQuery) query;
- pdQuery.getResult().add(productHandler.getProduct());
- productHandler = null;
- }
- } else if (SearchXML.INDEXER_XMLNS.equals(uri)) {
- if (SearchXML.RESPONSE_ELEMENT.equals(localName)) {
- // Do nothing, this is the end element of the document.
- } else if (SearchXML.RESULT_ELEMENT.equals(localName)) {
- // One of the results has completed
- if (response == null)
- throw new SAXException(
- "result element found without response parent");
- else {
- response.addResult(query);
- query = null;
- }
- } else if (SearchXML.QUERY_ELEMENT.equals(localName)) {
- // The query element of a result has completed
- // Because the ProductIndexQuery is part of the
- // query object controlled by the result element
- // nothing particular needs to be done other than
- // set the flag for being in the query element to false
- inQueryElement = false;
- } else if (SearchXML.PRODUCT_SUMMARY_ELEMENT.equals(localName)) {
- if (inQueryElement) {
- // Nothing needs to be done because this was just used
- // to get the product ID into the list of IDs for the
- // query.
- } else {
- if (event != null) {
- // We're adding product summaries to events.
- Map<String, List<ProductSummary>> eventProducts = event
- .getAllProducts();
- String productType = pSummary.getType();
- if (eventProducts.containsKey(productType)) {
- // Key exists, so just add the product summary to it
- eventProducts.get(productType).add(pSummary);
- } else {
- List<ProductSummary> newList = new ArrayList<ProductSummary>();
- newList.add(pSummary);
- eventProducts.put(productType, newList);
- }
- } else if (query != null
- && query.getType() == SearchMethod.PRODUCTS_SUMMARY) {
- // This was a product summary query and these are its
- // results
- ProductsSummaryQuery psQuery = (ProductsSummaryQuery) query;
- psQuery.getResult().add(pSummary);
- } else {
- throw new SAXException(
- "productSummary element encountered without recognized parent");
- }
- pSummary = null;
- }
- } else if (SearchXML.EVENT_ELEMENT.equals(localName)) {
- if (query != null
- && query.getType() == SearchMethod.EVENT_DETAIL) {
- // This was an event detail query and has opened properly
- EventDetailQuery edQuery = (EventDetailQuery) query;
- edQuery.getResult().add(event);
- event = null;
- } else {
- throw new SAXException(
- "event element encountered without recognized parent");
- }
- } else if (SearchXML.EVENT_SUMMARY_ELEMENT.equals(localName)) {
- if (query != null
- && query.getType() == SearchMethod.EVENTS_SUMMARY) {
- // This was an event summary query and has opened properly
- EventsSummaryQuery esQuery = (EventsSummaryQuery) query;
- esQuery.getResult().add(eSummary);
- esQuery = null;
- } else {
- throw new SAXException(
- "eventSummary element encountered without recognized parent");
- }
- } else if (SearchXML.ERROR_ELEMENT.equals(localName)) {
- inErrorElement = false;
- }
- } else if (XmlProductHandler.PRODUCT_XML_NAMESPACE.equals(uri)) {
- if (XmlProductHandler.PROPERTY_ELEMENT.equals(localName)) {
- // Simple tag is handled when the start element is encountered
- } else if (XmlProductHandler.LINK_ELEMENT.equals(localName)) {
- // Simple tag is handled when the start element is encountered
- }
- }
- }
- @Override
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- if (productHandler != null) {
- // Pass through if product is being generated
- productHandler.characters(ch, start, length);
- } else if (inErrorElement) {
- query.setError(new String(ch));
- }
- }
- }