/** * Copyright (c) Codice Foundation * <p> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p> * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package ddf.catalog.pubsub.predicate; import java.util.Date; import java.util.Map; import org.codice.ddf.platform.util.DateUtils; import org.osgi.service.event.Event; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ddf.catalog.data.Metacard; import ddf.catalog.pubsub.EventProcessorImpl.DateType; import ddf.catalog.pubsub.criteria.temporal.TemporalEvaluationCriteria; import ddf.catalog.pubsub.criteria.temporal.TemporalEvaluationCriteriaImpl; import ddf.catalog.pubsub.criteria.temporal.TemporalEvaluator; import ddf.catalog.pubsub.internal.PubSubConstants; public class TemporalPredicate implements Predicate { private static final Logger LOGGER = LoggerFactory.getLogger(TemporalPredicate.class); private Date end; private Date start; private long offset; private DateType type; /** * Instantiates a new temporal predicate. * * @param start * the start date * @param end * the end date * @param type * What date */ public TemporalPredicate(Date start, Date end, DateType type) { if (end != null) { this.end = new Date(end.getTime()); } if (start != null) { this.start = new Date(start.getTime()); } this.offset = 0; this.type = type; } public TemporalPredicate(long offset, DateType type) { this.offset = offset; this.start = null; this.end = null; this.type = type; } public static boolean isTemporal(String startXML, String endXML) { return !startXML.isEmpty() && !endXML.isEmpty(); } public boolean matches(Event properties) { LOGGER.debug("ENTERING: matches"); TemporalEvaluationCriteria tec = null; Date date = null; Map<String, Object> contextualMap = (Map<String, Object>) properties.getProperty( PubSubConstants.HEADER_CONTEXTUAL_KEY); String operation = (String) properties.getProperty(PubSubConstants.HEADER_OPERATION_KEY); LOGGER.debug("operation = {}", operation); if (contextualMap != null) { String metadata = (String) contextualMap.get("METADATA"); // If deleting a catalog entry and the entry's location data is NULL is only the word // "deleted" (i.e., the // source is deleting the catalog entry and did not send any location data with the // delete event), then // cannot apply any geospatial filtering - just send the event on to the subscriber if (PubSubConstants.DELETE.equals(operation) && PubSubConstants.METADATA_DELETED.equals( metadata)) { LOGGER.debug( "Detected a DELETE operation where metadata is just the word 'deleted', so send event on to subscriber"); return true; } } Metacard entry = (Metacard) properties.getProperty(PubSubConstants.HEADER_ENTRY_KEY); if (entry != null) { LOGGER.debug("entry id: {}", entry.getId()); switch (this.type) { case modified: LOGGER.debug("search by modified: {}", entry.getModifiedDate()); date = entry.getModifiedDate(); break; case effective: LOGGER.debug("search by effective: {}", entry.getEffectiveDate()); date = entry.getEffectiveDate(); break; case created: // currently searches by createdDate not supported by endpoints LOGGER.debug("search by created: {}", entry.getCreatedDate()); date = entry.getCreatedDate(); break; case expiration: // currently searches by expirationDate not supported by endpoints LOGGER.debug("search by expiration: {}", entry.getExpirationDate()); date = entry.getExpirationDate(); break; default: LOGGER.debug("unsupported type: {}", type); throw new IllegalArgumentException("Unsupported date type for TemporalPredicate"); } if (offset > 0) { this.end = new Date(); long startTimeMillis = end.getTime() - offset; this.start = new Date(startTimeMillis); LOGGER.debug("time period lowerBound = {}", start); LOGGER.debug("time period upperBound = {}", end); } tec = new TemporalEvaluationCriteriaImpl(end, start, date); } LOGGER.debug("EXITING: matches"); return TemporalEvaluator.evaluate(tec); } public Date getEnd() { return DateUtils.copy(end); } public Date getStart() { return DateUtils.copy(start); } public DateType getType() { return type; } public String toString() { StringBuffer sb = new StringBuffer(); if (start != null) { sb.append("\tstart = " + start.toString() + "\n"); } // end date can be null for non-absolute (i.e., MODIFIED) criteria if (end != null) { sb.append("\tend = " + end.toString() + "\n"); } sb.append("\toffset = " + Long.toString(offset) + "\n"); sb.append("\t(DateType) type = " + type.toString() + "\n"); return sb.toString(); } }