protected PageInfo buildNewPageInfo(
      HttpServletRequest request,
      HttpServletResponse response,
      FilterChain chain,
      CacheStatus cacheStatus,
      Map<String, Collection<CacheOperationContext>> operationsByType)
      throws Exception {

    Timer timer = new Timer(getCachedUri(request));
    timer.start();

    String key = calculateKey(request);
    PageInfo pageInfo;
    try {
      // Page is not cached - build the response, cache it, and send to client
      pageInfo = buildPage(request, response, chain);
      if (pageInfo.isOk()) {
        Object noCache = pageInfo.getCacheDirectives().get("no-cache");
        if (noCache instanceof Boolean && ((Boolean) noCache)) {
          log.debug("Response ok but Cache-Control: no-cache is present, not caching");
          releaseCacheLocks(operationsByType, key);
        } else {
          Collection<Cache> caches = new ArrayList<Cache>();
          for (CacheOperationContext operationContext : operationsByType.get(UPDATE)) {
            for (Cache cache : operationContext.getCaches()) {
              caches.add(cache);
            }
          }
          update(caches, pageInfo, cacheStatus, key);
        }
      } else {
        for (CacheOperationContext operationContext : operationsByType.get(UPDATE)) {
          for (Cache cache : operationContext.getCaches()) {
            log.debug(
                "Response not ok ({}). Putting null into cache {} with key {}",
                pageInfo.getStatusCode(),
                cache.getName(),
                key);
          }
        }
        releaseCacheLocks(operationsByType, key);
      }
    } catch (Exception e) {
      if ("net.sf.ehcache.constructs.blocking.LockTimeoutException"
          .equals(e.getClass().getName())) {
        // do not release the lock, because you never acquired it
        throw e;
      }
      // Must unlock the cache if the above fails. Will be logged at Filter
      releaseCacheLocks(operationsByType, key);
      throw e;
    }

    timer.stop(false);
    response.addHeader(X_CACHED, String.valueOf(false));
    return pageInfo;
  }
 protected void update(
     Collection<Cache> caches, PageInfo pageInfo, CacheStatus cacheStatus, String key) {
   ValueWrapper element = cacheStatus == null ? null : cacheStatus.valueWrapper;
   Object maxAge = pageInfo.getCacheDirectives().get("max-age");
   int timeToLive =
       (maxAge instanceof Integer) ? ((Integer) maxAge) : (int) pageInfo.getTimeToLiveSeconds();
   for (Cache cache : caches) {
     log.debug(
         "Response ok. Adding to cache {} with key {} and ttl {}",
         cache.getName(),
         key,
         getTimeToLive(element));
     put(cache, key, pageInfo, timeToLive);
   }
 }