/**
  * Check if result times should be added
  *
  * @param request GetDataAvailability request
  * @return <code>true</code>, if result times should be added
  */
 private boolean isIncludeResultTime(GetDataAvailabilityRequest request) {
   if (request.isSetExtensions()) {
     return request.getExtensions().isBooleanExtensionSet(INCLUDE_RESULT_TIMES)
         || hasPhenomenonTimeFilter(request.getExtensions());
   }
   return false;
 }
 /**
  * GetDataAvailability processing is series mapping is supported.
  *
  * @param request GetDataAvailability request
  * @param session Hibernate session
  * @return List of valid data availability information
  * @throws OwsExceptionReport If an error occurs
  */
 private List<?> querySeriesDataAvailabilities(GetDataAvailabilityRequest request, Session session)
     throws OwsExceptionReport {
   List<DataAvailability> dataAvailabilityValues = Lists.newLinkedList();
   Map<String, ReferenceType> procedures = new HashMap<String, ReferenceType>();
   Map<String, ReferenceType> observableProperties = new HashMap<String, ReferenceType>();
   Map<String, ReferenceType> featuresOfInterest = new HashMap<String, ReferenceType>();
   AbstractSeriesObservationDAO seriesObservationDAO = getSeriesObservationDAO();
   SeriesMinMaxTransformer seriesMinMaxTransformer = new SeriesMinMaxTransformer();
   boolean supportsNamedQuery =
       HibernateHelper.isNamedQuerySupported(SQL_QUERY_GET_DATA_AVAILABILITY_FOR_SERIES, session);
   for (final Series series :
       DaoFactory.getInstance()
           .getSeriesDAO()
           .getSeries(
               request.getProcedures(),
               request.getObservedProperties(),
               request.getFeaturesOfInterest(),
               session)) {
     TimePeriod timePeriod = null;
     if (!request.isSetOfferings()) {
       // get time information from series object
       if (series.isSetFirstLastTime()) {
         timePeriod = new TimePeriod(series.getFirstTimeStamp(), series.getLastTimeStamp());
       }
       // get time information from a named query
       else if (timePeriod == null && supportsNamedQuery) {
         timePeriod =
             getTimePeriodFromNamedQuery(series.getSeriesId(), seriesMinMaxTransformer, session);
       }
     }
     // get time information from SeriesGetDataAvailability mapping if
     // supported
     if (timePeriod == null) {
       SeriesObservationTimeDAO seriesObservationTimeDAO =
           (SeriesObservationTimeDAO) DaoFactory.getInstance().getObservationTimeDAO();
       timePeriod =
           getTimePeriodFromSeriesGetDataAvailability(
               seriesObservationTimeDAO, series, request, seriesMinMaxTransformer, session);
     }
     // create DataAvailabilities
     if (timePeriod != null && !timePeriod.isEmpty()) {
       DataAvailability dataAvailability =
           new DataAvailability(
               getProcedureReference(series, procedures),
               getObservedPropertyReference(series, observableProperties),
               getFeatureOfInterestReference(series, featuresOfInterest, session),
               timePeriod);
       if (isShowCount(request)) {
         dataAvailability.setCount(getCountFor(series, request, session));
       }
       if (isIncludeResultTime(request)) {
         dataAvailability.setResultTimes(
             getResultTimesFromSeriesObservation(seriesObservationDAO, series, request, session));
       }
       dataAvailabilityValues.add(dataAvailability);
     }
   }
   return dataAvailabilityValues;
 }
 /**
  * Get count of available observation for this time series
  *
  * @param series Time series
  * @param request GetDataAvailability request
  * @param session Hibernate session
  * @return Count of available observations
  */
 private Long getCountFor(Series series, GetDataAvailabilityRequest request, Session session) {
   Criteria criteria =
       session
           .createCriteria(SeriesObservationInfo.class)
           .add(Restrictions.eq(AbstractObservation.DELETED, false));
   criteria.add(Restrictions.eq(SeriesObservationInfo.SERIES, series));
   if (request.isSetOfferings()) {
     criteria
         .createCriteria(SeriesObservationTime.OFFERINGS)
         .add(Restrictions.in(Offering.IDENTIFIER, request.getOfferings()));
   }
   criteria.setProjection(Projections.rowCount());
   return (Long) criteria.uniqueResult();
 }
 /**
  * Get the result times for the timeseries
  *
  * @param seriesObservationDAO DAO
  * @param series time series
  * @param request GetDataAvailability request
  * @param session Hibernate session
  * @return List of result times
  * @throws OwsExceptionReport if the requested temporal filter is not supported
  */
 private List<TimeInstant> getResultTimesFromSeriesObservation(
     AbstractSeriesObservationDAO seriesObservationDAO,
     Series series,
     GetDataAvailabilityRequest request,
     Session session)
     throws OwsExceptionReport {
   Criterion filter = null;
   if (hasPhenomenonTimeFilter(request.getExtensions())) {
     filter = TemporalRestrictions.filter(getPhenomenonTimeFilter(request.getExtensions()));
   }
   List<Date> dateTimes =
       seriesObservationDAO.getResultTimesForSeriesObservation(
           series, request.getOfferings(), filter, session);
   List<TimeInstant> resultTimes = Lists.newArrayList();
   for (Date date : dateTimes) {
     resultTimes.add(new TimeInstant(date));
   }
   return resultTimes;
 }
 private boolean checkForNamedQueries(GetDataAvailabilityRequest req, Session session) {
   final boolean features = req.isSetFeaturesOfInterest();
   final boolean observableProperties = req.isSetObservedProperties();
   final boolean procedures = req.isSetProcedures();
   // all
   if (features && observableProperties && procedures) {
     return HibernateHelper.isNamedQuerySupported(
         SQL_QUERY_GET_DATA_AVAILABILITY_FOR_FEATURES_PROCEDURES_OBSERVED_PROPERTIES, session);
   }
   // observableProperties and procedures
   else if (!features && observableProperties && procedures) {
     return HibernateHelper.isNamedQuerySupported(
         SQL_QUERY_GET_DATA_AVAILABILITY_FOR_PROCEDURES_OBSERVED_PROPERTIES, session);
   }
   // only observableProperties
   else if (!features && observableProperties && !procedures) {
     return HibernateHelper.isNamedQuerySupported(
         SQL_QUERY_GET_DATA_AVAILABILITY_FOR_OBSERVED_PROPERTIES, session);
   }
   // only procedures
   else if (!features && !observableProperties && procedures) {
     return HibernateHelper.isNamedQuerySupported(
         SQL_QUERY_GET_DATA_AVAILABILITY_FOR_PROCEDURES, session);
   }
   // features and observableProperties
   else if (features && observableProperties && !procedures) {
     return HibernateHelper.isNamedQuerySupported(
         SQL_QUERY_GET_DATA_AVAILABILITY_FOR_FEATURES_OBSERVED_PROPERTIES, session);
   }
   // features and procedures
   else if (features && !observableProperties && procedures) {
     return HibernateHelper.isNamedQuerySupported(
         SQL_QUERY_GET_DATA_AVAILABILITY_FOR_FEATURES_PROCEDURES, session);
   }
   // only features
   else if (features && !observableProperties && procedures) {
     return HibernateHelper.isNamedQuerySupported(
         SQL_QUERY_GET_DATA_AVAILABILITY_FOR_FEATURES, session);
   }
   return false;
 }
 /**
  * Get time information from SeriesGetDataAvailability mapping
  *
  * @param seriesGetDataAvailabilityDAO Series GetDataAvailability DAO class
  * @param series Series to get information for
  * @param request
  * @param seriesMinMaxTransformer Hibernate result transformator for min/max time value
  * @param session Hibernate Session
  * @return Time period
  */
 private TimePeriod getTimePeriodFromSeriesGetDataAvailability(
     SeriesObservationTimeDAO seriesGetDataAvailabilityDAO,
     Series series,
     GetDataAvailabilityRequest request,
     SeriesMinMaxTransformer seriesMinMaxTransformer,
     Session session) {
   Criteria criteria =
       seriesGetDataAvailabilityDAO.getMinMaxTimeCriteriaForSeriesGetDataAvailabilityDAO(
           series, request.getOfferings(), session);
   criteria.setResultTransformer(seriesMinMaxTransformer);
   LOGGER.debug(
       "QUERY getTimePeriodFromSeriesObservation(series): {}",
       HibernateHelper.getSqlString(criteria));
   return (TimePeriod) criteria.uniqueResult();
 }
 @Override
 public GetDataAvailabilityResponse getDataAvailability(GetDataAvailabilityRequest req)
     throws OwsExceptionReport {
   Session session = sessionHolder.getSession();
   try {
     List<?> dataAvailabilityValues = queryDataAvailabilityValues(req, session);
     GetDataAvailabilityResponse response = new GetDataAvailabilityResponse();
     response.setService(req.getService());
     response.setVersion(req.getVersion());
     response.setNamespace(req.getNamespace());
     for (Object o : dataAvailabilityValues) {
       if (o != null) {
         response.addDataAvailability((DataAvailability) o);
       }
     }
     return response;
   } catch (HibernateException he) {
     throw new NoApplicableCodeException()
         .causedBy(he)
         .withMessage("Error while querying data for GetDataAvailability!");
   } finally {
     sessionHolder.returnSession(session);
   }
 }
 /**
  * Check if optional count should be added
  *
  * @param request GetDataAvailability request
  * @return <code>true</code>, if optional count should be added
  */
 private boolean isShowCount(GetDataAvailabilityRequest request) {
   if (request.isSetExtensions()) {
     return request.getExtensions().isBooleanExtensionSet(SHOW_COUNT);
   }
   return isForceValueCount();
 }
 private List<?> executeNamedQuery(GetDataAvailabilityRequest req, Session session) {
   final boolean features = req.isSetFeaturesOfInterest();
   final boolean observableProperties = req.isSetObservedProperties();
   final boolean procedures = req.isSetProcedures();
   String namedQueryName = null;
   Map<String, Collection<String>> parameter = Maps.newHashMap();
   // all
   if (features && observableProperties && procedures) {
     namedQueryName = SQL_QUERY_GET_DATA_AVAILABILITY_FOR_FEATURES_PROCEDURES_OBSERVED_PROPERTIES;
     parameter.put(FEATURES, req.getFeaturesOfInterest());
     parameter.put(OBSERVABLE_PROPERTIES, req.getObservedProperties());
     parameter.put(PROCEDURES, req.getProcedures());
   }
   // observableProperties and procedures
   else if (!features && observableProperties && procedures) {
     namedQueryName = SQL_QUERY_GET_DATA_AVAILABILITY_FOR_PROCEDURES_OBSERVED_PROPERTIES;
     parameter.put(OBSERVABLE_PROPERTIES, req.getObservedProperties());
     parameter.put(PROCEDURES, req.getProcedures());
   }
   // only observableProperties
   else if (!features && observableProperties && !procedures) {
     namedQueryName = SQL_QUERY_GET_DATA_AVAILABILITY_FOR_OBSERVED_PROPERTIES;
     parameter.put(OBSERVABLE_PROPERTIES, req.getObservedProperties());
   }
   // only procedures
   else if (!features && !observableProperties && procedures) {
     namedQueryName = SQL_QUERY_GET_DATA_AVAILABILITY_FOR_PROCEDURES;
     parameter.put(PROCEDURES, req.getProcedures());
   }
   // features and observableProperties
   else if (features && observableProperties && !procedures) {
     namedQueryName = SQL_QUERY_GET_DATA_AVAILABILITY_FOR_FEATURES_OBSERVED_PROPERTIES;
     parameter.put(FEATURES, req.getFeaturesOfInterest());
     parameter.put(OBSERVABLE_PROPERTIES, req.getObservedProperties());
   }
   // features and procedures
   else if (features && !observableProperties && procedures) {
     namedQueryName = SQL_QUERY_GET_DATA_AVAILABILITY_FOR_FEATURES_PROCEDURES;
     parameter.put(FEATURES, req.getFeaturesOfInterest());
     parameter.put(PROCEDURES, req.getProcedures());
   }
   // only features
   else if (features && !observableProperties && procedures) {
     namedQueryName = SQL_QUERY_GET_DATA_AVAILABILITY_FOR_FEATURES;
     parameter.put(FEATURES, req.getFeaturesOfInterest());
   }
   if (StringHelper.isNotEmpty(namedQueryName)) {
     Query namedQuery = session.getNamedQuery(namedQueryName);
     for (String key : parameter.keySet()) {
       namedQuery.setParameterList(key, parameter.get(key));
     }
     LOGGER.debug(
         "QUERY getProceduresForFeatureOfInterest(feature) with NamedQuery: {}", namedQuery);
     namedQuery.setResultTransformer(new DataAvailabilityTransformer(session));
     return namedQuery.list();
   }
   return Lists.newLinkedList();
 }