/** * Licensed to Apereo under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright ownership. Apereo * licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use * this file except in compliance with the License. You may obtain a copy of the License at the * following location: * * <p>http://www.apache.org/licenses/LICENSE-2.0 * * <p>Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package org.apereo.portal.portlet.container.cache; import java.util.concurrent.TimeUnit; import org.apereo.portal.portlet.rendering.PortletResourceOutputHandler; /** * Utility for writing out portlet response caching related headers * */ public final class PortletCachingHeaderUtils { private static final int YEAR_OF_SECONDS = (int) TimeUnit.DAYS.toSeconds(365); private PortletCachingHeaderUtils() {} /** * @param cachedPortletData The {@link CachedPortletData} to base the headers on * @param portletResourceOutputHandler The handler to write the headers to * @see #setCachingHeaders(int, boolean, long, PortletResourceOutputHandler) * @see #setETag(String, PortletResourceOutputHandler) */ public static void setCachingHeaders( CachedPortletData<?> cachedPortletData, PortletResourceOutputHandler portletResourceOutputHandler) { final long expirationTime = cachedPortletData.getExpirationTime(); final int maxAge = (int) TimeUnit.MILLISECONDS.toSeconds(expirationTime - System.currentTimeMillis()); final long timeStored = cachedPortletData.getTimeStored(); final boolean publicScope = cachedPortletData.isPublicScope(); setCachingHeaders(maxAge, publicScope, timeStored, portletResourceOutputHandler); final String etag = cachedPortletData.getEtag(); if (etag != null) { setETag(etag, portletResourceOutputHandler); } } /** * Set the Last-Modified, CacheControl, and Expires headers based on the maxAge, publicScope and * lastModified. * * @param maxAge Maximum age for the content, follows the portlet rules (-1 cache forever, 0 * cache never, N cache seconds) * @param publicScope If the content is public * @param lastModified The last modification timestamp of the content * @param portletResourceOutputHandler The handler to write the headers to */ public static void setCachingHeaders( int maxAge, boolean publicScope, long lastModified, PortletResourceOutputHandler portletResourceOutputHandler) { if (maxAge != 0) { portletResourceOutputHandler.setDateHeader("Last-Modified", lastModified); if (publicScope) { portletResourceOutputHandler.setHeader("CacheControl", "public"); } else { portletResourceOutputHandler.setHeader("CacheControl", "private"); } if (maxAge < 0) { //If caching "forever" set expires and max-age to 1 year maxAge = YEAR_OF_SECONDS; } portletResourceOutputHandler.setDateHeader( "Expires", System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(maxAge)); portletResourceOutputHandler.addHeader("CacheControl", "max-age=" + maxAge); } } /** * Set the ETag header based on the specified token * * @param token ETag value * @param portletResourceOutputHandler The handler to write the header to */ public static void setETag( String token, PortletResourceOutputHandler portletResourceOutputHandler) { portletResourceOutputHandler.setHeader("ETag", token); } }