001: /*
002: * Copyright 2002 Sun Microsystems, Inc. All
003: * rights reserved. Use of this product is subject
004: * to license terms. Federal Acquisitions:
005: * Commercial Software -- Government Users
006: * Subject to Standard License Terms and
007: * Conditions.
008: *
009: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
010: * are trademarks or registered trademarks of Sun Microsystems,
011: * Inc. in the United States and other countries.
012: */
013:
014: package com.sun.portal.container.portlet.impl;
015:
016: import java.util.HashMap;
017: import java.util.Map;
018:
019: import javax.servlet.http.HttpServletRequest;
020:
021: import com.sun.portal.container.ContainerRequest;
022: import com.sun.portal.container.portlet.CacheManager;
023: import com.sun.portal.container.portlet.PortletCacheEntry;
024: import com.sun.portal.container.portlet.NoSuchCachedContentException;
025: import com.sun.portal.portletcontainercommon.PortletCacheType;
026: import com.sun.portal.portletcontainercommon.PortletContainerConstants;
027: import com.sun.portal.providers.context.ProviderContext;
028:
029: /**
030: * The <code>CacheManagerImpl</code> class provides a default
031: * implementation for the <code>CacheManager</code> interface. In the
032: * initial implementation the only supported PortletState/PortletMode
033: * is NORMAL/VIEW and the cached data contains only the portlet
034: * content.
035: *
036: */
037:
038: public class CacheManagerImpl implements CacheManager {
039:
040: public static final String CACHED_PORTLETS = "javax.portlet.cache_portlets";
041:
042: /**
043: * Returns the <code>PortletCacheEntry</code> for the portlet of i
044: * the specified portlet entity ID encapsulated in the <code>
045: * ContainerRequest</code>.
046: * <p>
047: * This method returns <code>null</code> in the following two
048: * situations:
049: * <p>
050: * <ul>
051: * <li> no cache entry is found for this portlet entity
052: * <li> if the cache type is EXPIRATION and the cached data
053: * has already expired
054: * </ul>
055: *
056: * @param request The <code>ContainerRequest</code> object that
057: * encapsulates the portlet entity ID
058: */
059: public PortletCacheEntry getCachedPortlet(ContainerRequest request) {
060:
061: PortletCacheEntry cacheEntry = null;
062:
063: String portletEntityID = request.getEntityID();
064: Map cachedPortlets = getCachedPortletsMap(request);
065:
066: PortletCacheEntry pce;
067: synchronized (cachedPortlets) {
068: pce = (PortletCacheEntry) cachedPortlets
069: .get(portletEntityID);
070: }
071: if (pce != null) {
072: if (pce.getCacheType() == PortletCacheType.TYPE_EXPIRATION) {
073: long now = System.currentTimeMillis();
074: if (pce.getExpirationTime() > now) {
075: cacheEntry = pce;
076: } else {
077: // remove the cache entry since it's no longer
078: // valid
079: removeCachedPortlet(request);
080: }
081: }
082: }
083: return cacheEntry;
084: }
085:
086: /**
087: * Called by the portlet container to add or update the cache
088: * entry for the protlet of the specified entity ID encapsulated
089: * in the <code>ContainerRequest</code>.
090: * <p>
091: * @param request The <code>ContainerRequest</code> object that
092: * encapsulates the portlet entity ID
093: * @param entry The <code>PortletCacheEntry</code> object
094: *
095: */
096: public void putCachedPortlet(ContainerRequest request,
097: PortletCacheEntry entry) {
098:
099: String portletEntityID = request.getEntityID();
100: Map cachedPortlets = getCachedPortletsMap(request);
101:
102: synchronized (cachedPortlets) {
103: cachedPortlets.put(portletEntityID, entry);
104: }
105: }
106:
107: /**
108: * Called by the portlet container to remove the cache entry
109: * for the protlet of the specified entity ID encapsulated
110: * in the <code>ContainerRequest</code>.
111: * <p>
112: * @param request The <code>ContainerRequest</code> object that
113: * encapsulates the portlet entity ID
114: *
115: */
116: public void removeCachedPortlet(ContainerRequest request) {
117:
118: String portletEntityID = request.getEntityID();
119: Map cachedPortlets = getCachedPortletsMap(request);
120:
121: synchronized (cachedPortlets) {
122: cachedPortlets.remove(portletEntityID);
123: }
124: }
125:
126: /**
127: * Called by the portlet container to remove all the cache
128: * entries in the user session.
129: * <p>
130: * @param request The <code>ContainerRequest</code> object that
131: * encapsulates the information of the cache repository
132: * in the user session.
133: *
134: */
135: public void removeAllCachedPortlets(ContainerRequest request) {
136:
137: Map cachedPortlets = getCachedPortletsMap(request);
138:
139: synchronized (cachedPortlets) {
140: cachedPortlets.clear();
141: }
142: }
143:
144: /**
145: * Return if the cached entry for the portlet with EXPIRATION
146: * cache type already expired.
147: * <P>
148: * @param request The <code>ContainerRequest</code> object that
149: * encapsulates the portlet entity ID
150: * <p>
151: * @return true, if the cached entry for the portlet with
152: * EXPIRATION cache type has already expired
153: *<p>
154: * @exception java.lang.IllegalStateException if the cache
155: * type is not EXPIRATION.
156: * @exception com.sun.portal.container.NoSuchCachedContentException
157: * if the cache entry for the portlet entity is
158: * not found.
159: *
160: **/
161: public boolean isCacheExpired(ContainerRequest request)
162: throws IllegalStateException, NoSuchCachedContentException {
163:
164: boolean cacheExpired = true;
165:
166: String portletEntityID = request.getEntityID();
167: Map cachedPortlets = getCachedPortletsMap(request);
168:
169: PortletCacheEntry pce;
170: synchronized (cachedPortlets) {
171: pce = (PortletCacheEntry) cachedPortlets
172: .get(portletEntityID);
173: }
174: if (pce != null) {
175: if (pce.getCacheType() == PortletCacheType.TYPE_EXPIRATION) {
176: long now = System.currentTimeMillis();
177: if (pce.getExpirationTime() > now) {
178: cacheExpired = false;
179: }
180: }
181: } else { // cached item is not found
182: throw new NoSuchCachedContentException(
183: "CacheManagerImpl.isCacheExpired: Cache entry is not found. EntityID:"
184: + portletEntityID);
185: }
186: return cacheExpired;
187:
188: }
189:
190: /**
191: * convenient method to retrieve the cache Map from the
192: * encapsulated <code>PorviderContext</code> in the <code>
193: * ContainerRequest</code> object.
194: * <p>
195: * @param request The <code>ContainerRequest</code> object that
196: * encapsulates the <code>PorviderContext</code> object
197: * <p>
198: * @return a Map that contains all the cache entries for
199: * the user session
200: */
201: private Map getCachedPortletsMap(ContainerRequest request) {
202:
203: HttpServletRequest req = request.getHttpServletRequest();
204:
205: ProviderContext pc = (ProviderContext) req
206: .getAttribute(PortletContainerConstants.PROVIDER_CONTEXT);
207:
208: // Use DCL mechanism to improve the performance. Although
209: // DCL is known not to be always safe, it should not be a
210: // problem here since the object is retrieved from a
211: // synchronized HashMap in desktop context and will be
212: // instantiated, if not already exists, before being set
213: // in the map.
214:
215: Map cachedPortlets = (Map) pc
216: .getSessionProperty(CACHED_PORTLETS);
217: if (cachedPortlets == null) {
218: synchronized (pc) {
219: if ((cachedPortlets = (Map) pc
220: .getSessionProperty(CACHED_PORTLETS)) == null) {
221: cachedPortlets = new HashMap();
222: pc.setSessionProperty(CACHED_PORTLETS,
223: cachedPortlets);
224: }
225: }
226: }
227: return cachedPortlets;
228: }
229:
230: }
|