/**
   * Add ETag and Last-Modified cache control headers to the response
   *
   * @param servletResponse the servlet response
   * @param resource the fedora resource
   * @param session the session
   */
  protected static void addCacheControlHeaders(
      final HttpServletResponse servletResponse,
      final FedoraResource resource,
      final Session session) {

    final String txId = TransactionServiceImpl.getCurrentTransactionId(session);
    if (txId != null) {
      // Do not add caching headers if in a transaction
      return;
    }

    final FedoraResource mutableResource =
        resource instanceof NonRdfSourceDescription
            ? ((NonRdfSourceDescription) resource).getDescribedResource()
            : resource;
    final EntityTag etag = new EntityTag(mutableResource.getEtagValue());
    final Date date = mutableResource.getLastModifiedDate();

    if (!etag.getValue().isEmpty()) {
      servletResponse.addHeader("ETag", etag.toString());
    }

    if (date != null) {
      servletResponse.addDateHeader("Last-Modified", date.getTime());
    }
  }
  private static void evaluateRequestPreconditions(
      final Request request,
      final HttpServletResponse servletResponse,
      final FedoraResource resource,
      final Session session,
      final boolean cacheControl) {

    final String txId = TransactionServiceImpl.getCurrentTransactionId(session);
    if (txId != null) {
      // Force cache revalidation if in a transaction
      servletResponse.addHeader(CACHE_CONTROL, "must-revalidate");
      servletResponse.addHeader(CACHE_CONTROL, "max-age=0");
      return;
    }

    final EntityTag etag = new EntityTag(resource.getEtagValue());
    final Date date = resource.getLastModifiedDate();
    final Date roundedDate = new Date();

    if (date != null) {
      roundedDate.setTime(date.getTime() - date.getTime() % 1000);
    }

    Response.ResponseBuilder builder = request.evaluatePreconditions(etag);
    if (builder != null) {
      builder = builder.entity("ETag mismatch");
    } else {
      builder = request.evaluatePreconditions(roundedDate);
      if (builder != null) {
        builder = builder.entity("Date mismatch");
      }
    }

    if (builder != null && cacheControl) {
      final CacheControl cc = new CacheControl();
      cc.setMaxAge(0);
      cc.setMustRevalidate(true);
      // here we are implicitly emitting a 304
      // the exception is not an error, it's genuinely
      // an exceptional condition
      builder = builder.cacheControl(cc).lastModified(date).tag(etag);
    }
    if (builder != null) {
      throw new WebApplicationException(builder.build());
    }
  }