portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tay...@apache.org
Subject svn commit: r545356 - in /portals/jetspeed-2/trunk: applications/gems/src/java/org/apache/portals/gems/util/ components/cm/ components/cm/src/java/org/apache/jetspeed/cache/impl/ components/cm/src/test/org/apache/jetspeed/cache/ components/page-manager...
Date Fri, 08 Jun 2007 00:49:08 GMT
Author: taylor
Date: Thu Jun  7 17:49:07 2007
New Revision: 545356

URL: http://svn.apache.org/viewvc?view=rev&rev=545356
Log:
https://issues.apache.org/jira/browse/JS2-663

Enhanced the JSR 168 portlet cache to cache on a configurable set of keys based on a Spring configuration per Joachim's specifications.
See src/webapp/WEB-INF/assembly/cache.xml for key configuration details
There are three required keys: username or sessionid, pipeline (desktop or portal), and windowid
Other optional values are session attribute, and request parameter
NOTE: this fixes the bug (unlogged) where switching between /desktop and /portal rendered bad links from the cache

Added:
    portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/JetspeedCacheKeyGenerator.java
    portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/JetspeedContentCacheKey.java
    portals/jetspeed-2/trunk/components/cm/src/test/org/apache/jetspeed/cache/TestContentCache.java
    portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheElement.java
    portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheKey.java
    portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheKeyGenerator.java
Modified:
    portals/jetspeed-2/trunk/applications/gems/src/java/org/apache/portals/gems/util/PortletContentImpl.java
    portals/jetspeed-2/trunk/components/cm/maven.xml
    portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhCacheDistributedImpl.java
    portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhCacheImpl.java
    portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhPortletContentCacheElementImpl.java
    portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhPortletContentCacheImpl.java
    portals/jetspeed-2/trunk/components/page-manager/src/java/JETSPEED-INF/castor/page-mapping.xml
    portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/page/psml/FragmentImpl.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletContentImpl.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletRendererImpl.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/PortletWindowSessionNavigationalStates.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/engine/JetspeedServlet.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/pipeline/valve/impl/ActionValveImpl.java
    portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/aggregator/PortletContent.java
    portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/JetspeedCache.java
    portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/mockobjects/request/MockRequestContext.java
    portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/cache.xml

Modified: portals/jetspeed-2/trunk/applications/gems/src/java/org/apache/portals/gems/util/PortletContentImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/applications/gems/src/java/org/apache/portals/gems/util/PortletContentImpl.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/applications/gems/src/java/org/apache/portals/gems/util/PortletContentImpl.java (original)
+++ portals/jetspeed-2/trunk/applications/gems/src/java/org/apache/portals/gems/util/PortletContentImpl.java Thu Jun  7 17:49:07 2007
@@ -20,6 +20,7 @@
 import java.io.PrintWriter;
 
 import org.apache.jetspeed.aggregator.PortletContent;
+import org.apache.jetspeed.cache.ContentCacheKey;
 
 public class PortletContentImpl implements PortletContent
 {
@@ -27,6 +28,7 @@
     private PrintWriter writer;
     private boolean complete = false;
     private String cacheKey;
+    private ContentCacheKey ccKey;    
     private int expiration = 0;
     private String title;
  
@@ -35,6 +37,15 @@
         init();
     }
 
+    PortletContentImpl(ContentCacheKey ccKey, int expiration, String title, boolean complete)
+    {
+        this.ccKey = ccKey;
+        this.expiration = expiration;
+        this.title = title;
+        this.complete = complete;
+        init();
+    }
+    
     PortletContentImpl(String cacheKey, int expiration, String title, boolean complete)
     {
         this.cacheKey = cacheKey;
@@ -116,7 +127,12 @@
        setComplete(true);
     }
         
-    public String getCacheKey()
+    public ContentCacheKey getCacheKey()
+    {
+        return ccKey;
+    }
+
+    public String getStringCacheKey()
     {
         return cacheKey;
     }

Modified: portals/jetspeed-2/trunk/components/cm/maven.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/cm/maven.xml?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/cm/maven.xml (original)
+++ portals/jetspeed-2/trunk/components/cm/maven.xml Thu Jun  7 17:49:07 2007
@@ -18,6 +18,6 @@
 <project default="java:jar" xmlns:j="jelly:core" xmlns:define="jelly:define">
 
     <!-- Target of maven test:single test -->
-    <property name='testcase' value='org.apache.jetspeed.components.TestComponentManager' />
+    <property name='testcase' value='org.apache.jetspeed.cache.TestContentCache' />
 
 </project>

Modified: portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhCacheDistributedImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhCacheDistributedImpl.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhCacheDistributedImpl.java (original)
+++ portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhCacheDistributedImpl.java Thu Jun  7 17:49:07 2007
@@ -32,6 +32,7 @@
 import org.apache.jetspeed.cache.CacheElement;
 import org.apache.jetspeed.cache.DistributedCacheObject;
 import org.apache.jetspeed.cache.JetspeedCache;
+import org.apache.jetspeed.request.RequestContext;
 
 public class EhCacheDistributedImpl extends EhCacheImpl implements JetspeedCache, CacheEventListener
 {
@@ -122,7 +123,7 @@
 
 	}
 
-	public void evictContentForUser(String user)
+	public void evictContentForUser(RequestContext context)
 	{
 		return;
 	}

Modified: portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhCacheImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhCacheImpl.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhCacheImpl.java (original)
+++ portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhCacheImpl.java Thu Jun  7 17:49:07 2007
@@ -24,8 +24,10 @@
 import net.sf.ehcache.Element;
 
 import org.apache.jetspeed.cache.CacheElement;
+import org.apache.jetspeed.cache.ContentCacheKey;
 import org.apache.jetspeed.cache.JetspeedCache;
 import org.apache.jetspeed.cache.JetspeedCacheEventListener;
+import org.apache.jetspeed.request.RequestContext;
 
 public class EhCacheImpl implements JetspeedCache
 {
@@ -101,16 +103,16 @@
 		notifyListeners(true, CacheElement.ActionRemoved,null,null);
     }
     
-    public void evictContentForUser(String user)
+    public void evictContentForUser(String username)
     {
     	return;
     }
-    
-    public String createCacheKey(String primary, String secondary)
+
+    public void evictContentForSession(String session)
     {
-        return primary;
+        return;
     }
-
+    
     public void addEventListener(JetspeedCacheEventListener listener, boolean local)
     {
     	if (local)
@@ -172,10 +174,12 @@
         		e.printStackTrace();
         		
         	}
-        }
-    	
-    	
-    	
+        }    	
+    }
+
+    public ContentCacheKey createCacheKey(RequestContext rc, String windowId)
+    {
+        return null; // not implemented here
     }
 
 }

Modified: portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhPortletContentCacheElementImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhPortletContentCacheElementImpl.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhPortletContentCacheElementImpl.java (original)
+++ portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhPortletContentCacheElementImpl.java Thu Jun  7 17:49:07 2007
@@ -19,7 +19,8 @@
 
 import net.sf.ehcache.Element;
 
-import org.apache.jetspeed.cache.CacheElement;
+import org.apache.jetspeed.cache.ContentCacheElement;
+import org.apache.jetspeed.cache.ContentCacheKey;
 
 /**
  * Wrapper around actual cache element implementation
@@ -27,39 +28,24 @@
  * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
  * @version $Id: $
  */
-public class EhPortletContentCacheElementImpl implements CacheElement
+public class EhPortletContentCacheElementImpl implements ContentCacheElement
 {
     Element element;
-    public static final String KEY_SEPARATOR = "/";
+    ContentCacheKey cckey;
     
+    public static final String KEY_SEPARATOR = "/";
     
- 
-
-	public EhPortletContentCacheElementImpl(Element element)
+	public EhPortletContentCacheElementImpl(Element element, ContentCacheKey cckey)
     {
         this.element = element;
+        this.cckey = cckey;
     }
 
-
-
-	
     public Object getKey()
     {
         return element.getObjectKey();
     }
-    
-    public String getUserKey()
-    {
-        String key = (String)element.getObjectKey();
-        return key.substring(0, key.indexOf(KEY_SEPARATOR));
-    }
-
-    public String getEntityKey()
-    {
-        String key = (String)element.getObjectKey();
-        return key.substring(key.indexOf(KEY_SEPARATOR) + 1);
-    }
-    
+        
     public Object getContent()
     {
         return element.getObjectValue();
@@ -98,5 +84,10 @@
     public void setTimeToLiveSeconds(int timeToLive)
     {
         element.setTimeToLive(timeToLive);
+    }
+
+    public ContentCacheKey getContentCacheKey()
+    {
+        return cckey;
     }
 }

Modified: portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhPortletContentCacheImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhPortletContentCacheImpl.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhPortletContentCacheImpl.java (original)
+++ portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/EhPortletContentCacheImpl.java Thu Jun  7 17:49:07 2007
@@ -27,8 +27,12 @@
 import net.sf.ehcache.Element;
 
 import org.apache.jetspeed.cache.CacheElement;
+import org.apache.jetspeed.cache.ContentCacheElement;
+import org.apache.jetspeed.cache.ContentCacheKey;
+import org.apache.jetspeed.cache.ContentCacheKeyGenerator;
 import org.apache.jetspeed.cache.JetspeedCache;
 import org.apache.jetspeed.cache.JetspeedCacheEventListener;
+import org.apache.jetspeed.request.RequestContext;
 
 /**
  * Wrapper around actual cache implementation
@@ -38,91 +42,123 @@
  */
 public class EhPortletContentCacheImpl extends EhCacheImpl implements JetspeedCache, JetspeedCacheEventListener
 {
-	
-    public static final String KEY_ENTITY_KEY = EhPortletContentCacheElementImpl.KEY_SEPARATOR + "portlet_entity" + EhPortletContentCacheElementImpl.KEY_SEPARATOR ;
-    public static final int KEY_ENTITY_KEY_LENGTH = KEY_ENTITY_KEY.length();
 
-	   JetspeedCache preferenceCache = null;
+	JetspeedCache preferenceCache = null;
+    ContentCacheKeyGenerator keyGenerator = null;    
 
-	   public void notifyElementAdded(JetspeedCache cache, boolean local, Object key, Object element)
+    public EhPortletContentCacheImpl(Cache ehcache, JetspeedCache preferenceCache, ContentCacheKeyGenerator keyGenerator)
+    {
+        this(ehcache);
+        this.preferenceCache = preferenceCache;
+        this.keyGenerator = keyGenerator;
+        preferenceCache.addEventListener(this,false); //only listen to remote events
+    }
+    
+    public EhPortletContentCacheImpl(Cache ehcache, JetspeedCache preferenceCache)
+    {
+        this(ehcache);
+        this.preferenceCache = preferenceCache;
+        preferenceCache.addEventListener(this,false); //only listen to remote events
+    }
+        
+    public EhPortletContentCacheImpl(Cache ehcache)
+    {
+        super(ehcache);
+    }
+
+    public EhPortletContentCacheImpl(Cache ehcache, ContentCacheKeyGenerator keyGenerator)
+    {
+        this(ehcache);
+        this.keyGenerator = keyGenerator;
+    }
+    
+
+	public void notifyElementAdded(JetspeedCache cache, boolean local, Object key, Object element)
 	{
-		// TODO Auto-generated method stub
-		
 	}
 
 	public void notifyElementChanged(JetspeedCache cache, boolean local, Object key, Object element)
 	{
-		// TODO Auto-generated method stub
-		
 	}
 
 	public void notifyElementEvicted(JetspeedCache cache, boolean local, Object key, Object element)
 	{
-		// TODO Auto-generated method stub
-		
-		notifyElementRemoved(cache,local,key,element);
 	}
 
 	public void notifyElementExpired(JetspeedCache cache, boolean local, Object key, Object element)
 	{
-		// TODO Auto-generated method stub
 		notifyElementRemoved(cache,local,key,element);
-		
 	}
 
-	public void notifyElementRemoved(JetspeedCache cache, boolean local, Object key, Object element)
-		{
-		   if (local)
-			   return; //not interested in local changes
-			   
-		   	//System.out.println("notifying PortletContent that element " + key.toString() + " has been removed");		   
-			if (!(key instanceof String))
-				return;
-			String s = (String) key;
-			if (!(s.startsWith(KEY_ENTITY_KEY)))
-				return;
-			StringTokenizer st = new StringTokenizer(s,EhPortletContentCacheElementImpl.KEY_SEPARATOR);
-			int count = 0;
-			String pe = null; String user = null;
-		     while (st.hasMoreTokens()) 
-		     {
-		    	 String temp = st.nextToken();
-		    	 switch (count)
-		    	 {
-		    		 case 0: 
-		    			 break;
-		    		 case 1: 	pe = temp;
-		    	 		break;
-		    		 case 2: 	user = temp;
-		    		 break;
-		    	 }
-		    	 count++;
-		    	 if (count> 2)
-		    		 break;
-		     }
-			 if ((pe != null) && (user != null))
-				 removeOneEntry(user,pe);
-		}
-	    
-	public EhPortletContentCacheImpl(Cache ehcache,JetspeedCache preferenceCache )
-    {
-        this(ehcache);
-        this.preferenceCache = preferenceCache;
-        preferenceCache.addEventListener(this,false); //only listen to remote events
-    }
 
-	    
-    public EhPortletContentCacheImpl(Cache ehcache)
+    public static final String KEY_ENTITY_KEY = 
+        EhPortletContentCacheElementImpl.KEY_SEPARATOR + "portlet_entity" + EhPortletContentCacheElementImpl.KEY_SEPARATOR ;
+	public static final int KEY_ENTITY_KEY_LENGTH = KEY_ENTITY_KEY.length();
+    
+	public void notifyElementRemoved(JetspeedCache cache, boolean local,
+            Object key, Object element)
     {
-        super(ehcache);
+        if (local) return; // not interested in local changes
+
+        // System.out.println("notifying PortletContent that element " +
+        // key.toString() + " has been removed");
+        if (!(key instanceof String)) return;
+        String s = (String) key;
+        if (!(s.startsWith(KEY_ENTITY_KEY))) return;
+        StringTokenizer st = new StringTokenizer(s,
+                EhPortletContentCacheElementImpl.KEY_SEPARATOR);
+        int count = 0;
+        String pe = null;
+        String user = null;
+        while (st.hasMoreTokens())
+        {
+            String temp = st.nextToken();
+            switch (count)
+            {
+            case 0:
+                break;
+            case 1:
+                pe = temp; 
+                break;
+            case 2:
+                user = temp;
+                break;
+            }
+            count++;
+            if (count > 2) break;
+        }
+        if ((pe != null) && (user != null))
+        {
+            removeUserEntry(user, "portal", pe);     
+            removeUserEntry(user, "desktop", pe);
+        }
     }
 
+    void removeUserEntry(String username, String pipeline, String windowId)
+    {        
+        ContentCacheKey key = keyGenerator.createUserCacheKey(username, pipeline, windowId);
+        if (ehcache.remove(key.getKey()))
+        {
+            Element userElement = ehcache.get(username);
+                
+            if (userElement != null)
+            {
+                Map map = (Map)userElement.getObjectValue();
+                if (map != null)
+                {
+                    map.remove(windowId);
+                }
+            }
+        }
+    }
+    
     public CacheElement get(Object key)
     {
-        Element element = ehcache.get(key);
+        ContentCacheKey cckey = (ContentCacheKey)key;
+        Element element = ehcache.get(cckey.getKey());
         if (element == null)
             return null;
-        return new EhPortletContentCacheElementImpl(element);
+        return new EhPortletContentCacheElementImpl(element, cckey);
     }
 
     public int getTimeToIdleSeconds()
@@ -137,35 +173,49 @@
 
     public boolean isKeyInCache(Object key)
     {
-        return ehcache.isKeyInCache(key);
+        ContentCacheKey cckey = (ContentCacheKey)key;        
+        return ehcache.isKeyInCache(cckey.getKey());
     }
 
     public void put(CacheElement element)
     {
+        ContentCacheElement ccElement = (ContentCacheElement)element;
         EhPortletContentCacheElementImpl impl = (EhPortletContentCacheElementImpl)element;
-        Element ehl = impl.getImplElement();
-        String userKey = impl.getUserKey();
-        String entity = impl.getEntityKey();
-        ehcache.put(ehl);
+        Element ehl = impl.getImplElement();        
+        String userKey = ccElement.getContentCacheKey().getSessionId();
+        if (userKey == null)
+        {
+            userKey = ccElement.getContentCacheKey().getUsername();
+        }
+        String windowId = ccElement.getContentCacheKey().getWindowId();
+        try
+        {
+            ehcache.put(ehl);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
         Element userElement = ehcache.get(userKey);
         if (userElement == null)
         {
             Map map = Collections.synchronizedMap(new HashMap());
-            map.put(entity, entity);
+            map.put(windowId, ccElement.getContentCacheKey());
             userElement = new Element(userKey, map);
             ehcache.put(userElement);           
         }
         else
         {
             Map map = (Map)userElement.getObjectValue();
-            map.put(entity, entity);
+            map.put(windowId, ccElement.getContentCacheKey());
         }        
     }
     
     public CacheElement createElement(Object key, Object content)
     {
-        Element cachedElement = new Element(key, content);        
-        return new EhPortletContentCacheElementImpl(cachedElement);
+        ContentCacheKey cckey = (ContentCacheKey)key;
+        Element cachedElement = new Element(cckey.getKey(), content);        
+        return new EhPortletContentCacheElementImpl(cachedElement, cckey);
     }
 
     public boolean remove(Object key)
@@ -174,57 +224,64 @@
         boolean removed = false;
         if (element == null)
             return false;
-        removed = ehcache.remove(key);
+        
+        ContentCacheElement ccElement = (ContentCacheElement)element;
         EhPortletContentCacheElementImpl impl = (EhPortletContentCacheElementImpl)element;
-        String userKey = impl.getUserKey();
-        String entity = impl.getEntityKey();
+        Element ehl = impl.getImplElement();        
+        String userKey = ccElement.getContentCacheKey().getSessionId();
+        if (userKey == null)
+        {
+            userKey = ccElement.getContentCacheKey().getUsername();
+        }        
+        String windowId = ccElement.getContentCacheKey().getWindowId();        
+        removed = ehcache.remove(ccElement.getContentCacheKey().getKey());
         Element userElement = ehcache.get(userKey);
         if (userElement != null)
         {
             Map map = (Map)userElement.getObjectValue();
             if (map != null)
             {
-                map.remove(entity);
+                map.remove(windowId);
             }
         }
         return removed;
     }
-    
-    public void removeOneEntry(String pe, String user)
+        
+    public void evictContentForUser(String username)
     {
-        String key = createCacheKey(pe,user);
-        if (ehcache.remove(key))
+        Element userElement = ehcache.get(username);
+        if (userElement != null)
         {
-        	Element userElement = ehcache.get(user);
-	        	
-	        if (userElement != null)
-	        {
-	            Map map = (Map)userElement.getObjectValue();
-	            if (map != null)
-	            {
-	            	map.remove(pe);
-	            }
-	        }
+            Map map = (Map)userElement.getObjectValue();
+            if (map != null)
+            {
+                Iterator entities = map.values().iterator();
+                while (entities.hasNext())
+                {
+                    ContentCacheKey ccKey = (ContentCacheKey)entities.next();
+                    ehcache.remove(ccKey.getKey());
+                }
+            }
+            ehcache.remove(username);
         }
     }
-    
-    public void evictContentForUser(String user)
+
+    public void evictContentForSession(String session)
     {
-        Element userElement = ehcache.get(user);
+        Element userElement = ehcache.get(session);
         if (userElement != null)
         {
             Map map = (Map)userElement.getObjectValue();
             if (map != null)
             {
-                Iterator entities = map.keySet().iterator();
+                Iterator entities = map.values().iterator();
                 while (entities.hasNext())
                 {
-                    String entity = (String)entities.next();
-                    String key = createCacheKey(user, entity);
-                    ehcache.remove(key);
+                    ContentCacheKey ccKey = (ContentCacheKey)entities.next();
+                    ehcache.remove(ccKey.getKey());
                 }
             }
-            ehcache.remove(user);
+            ehcache.remove(session);
         }
     }
     
@@ -232,10 +289,11 @@
     {
         ehcache.removeAll();
     }
-    
-    public String createCacheKey(String primary, String secondary)
+        
+    public ContentCacheKey createCacheKey(RequestContext context, String windowId)
     {
-        return primary + EhPortletContentCacheElementImpl.KEY_SEPARATOR + secondary;
+        return this.keyGenerator.createCacheKey(context, windowId);        
     }
+    
 
 }

Added: portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/JetspeedCacheKeyGenerator.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/JetspeedCacheKeyGenerator.java?view=auto&rev=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/JetspeedCacheKeyGenerator.java (added)
+++ portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/JetspeedCacheKeyGenerator.java Thu Jun  7 17:49:07 2007
@@ -0,0 +1,73 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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.apache.jetspeed.cache.impl;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.jetspeed.cache.ContentCacheKey;
+import org.apache.jetspeed.cache.ContentCacheKeyGenerator;
+import org.apache.jetspeed.request.RequestContext;
+
+/**
+ * Wrapper around actual cache implementation
+ * 
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: $
+ */
+public class JetspeedCacheKeyGenerator implements ContentCacheKeyGenerator
+{
+    private List segments;
+    private boolean cacheBySessionId = true;
+        
+    public JetspeedCacheKeyGenerator(List segments)
+    {
+        this.segments = segments;
+        this.cacheBySessionId = (segments.contains("sessionid"));            
+    }
+    
+    public ContentCacheKey createCacheKey(RequestContext context, String windowId)
+    {
+        ContentCacheKey key = new JetspeedContentCacheKey(segments, context, windowId);
+        return key;
+    }
+
+    public ContentCacheKey createUserCacheKey(String username, String pipeline, String windowId)
+    {
+        ContentCacheKey key = new JetspeedContentCacheKey();
+        key.createFromUser(username, pipeline, windowId);
+        return key;
+    }
+
+    public ContentCacheKey createSessionCacheKey(String sessionId, String pipeline, String windowId)
+    {
+        ContentCacheKey key = new JetspeedContentCacheKey();
+        key.createFromSession(sessionId, pipeline, windowId);
+        return key;
+    }
+    
+    public boolean isCacheBySessionId()
+    {
+        return cacheBySessionId;
+    }
+    
+    public boolean isCacheByUsername()
+    {
+        return !cacheBySessionId;        
+    }
+}

Added: portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/JetspeedContentCacheKey.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/JetspeedContentCacheKey.java?view=auto&rev=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/JetspeedContentCacheKey.java (added)
+++ portals/jetspeed-2/trunk/components/cm/src/java/org/apache/jetspeed/cache/impl/JetspeedContentCacheKey.java Thu Jun  7 17:49:07 2007
@@ -0,0 +1,222 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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.apache.jetspeed.cache.impl;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.jetspeed.cache.ContentCacheKey;
+import org.apache.jetspeed.desktop.JetspeedDesktop;
+import org.apache.jetspeed.request.RequestContext;
+
+/**
+ * The content cache key holds an immutable cache key definition.
+ * Cache key definitions are based on the following required properties:
+ * <ul>
+ * <li>username</li>
+ * <li>windowid</li>
+ * <li>pipeline</li>
+ * </ul>
+ * and the following optional properties:
+ * <ul>
+ * <li>sessionid</li>
+ * <li></li>
+ * <li>request.{parameter}</li>
+ * <li>session.{attribute}</li>
+ * </ul>
+ * The string representation of this key is calculated once upon construction.
+ * 
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: $
+ */
+public class JetspeedContentCacheKey implements ContentCacheKey, Serializable
+{
+    private String username = null;
+    private String pipeline = null;
+    private String windowId = null;
+    private String sessionId = null;
+    private String requestParameter = null;
+    private String sessionAttribute = null;
+    private String key = "";
+    
+    public JetspeedContentCacheKey(List segments, RequestContext context, String windowId)
+    {
+        boolean first = true;
+        Iterator si = segments.iterator();
+        while (si.hasNext())
+        {
+            String segment = (String)si.next();
+            if (segment.equals("username"))
+            {
+                this.username = context.getUserPrincipal().getName();
+                key = (first) ? this.username : key + EhPortletContentCacheElementImpl.KEY_SEPARATOR + this.username;                 
+            }
+            else if (segment.equals("windowid"))
+            {
+                this.windowId = windowId;
+                key = (first) ? this.windowId : key + EhPortletContentCacheElementImpl.KEY_SEPARATOR + this.windowId;
+            }
+            else if (segment.equals("sessionid"))
+            {
+                this.sessionId = context.getRequest().getSession().getId();
+                key = (first) ? this.sessionId : key + EhPortletContentCacheElementImpl.KEY_SEPARATOR + this.sessionId;                
+            }
+            else if (segment.equals("pipeline"))
+            {
+                String encoder = context.getRequestParameter(JetspeedDesktop.DESKTOP_ENCODER_REQUEST_PARAMETER);
+                if (encoder != null && encoder.equals(JetspeedDesktop.DESKTOP_ENCODER_REQUEST_PARAMETER_VALUE))
+                {
+                    this.pipeline = "desktop";
+                }
+                else
+                {
+                    this.pipeline = "portal";
+                }
+                key = (first) ? this.pipeline : key + EhPortletContentCacheElementImpl.KEY_SEPARATOR + this.pipeline;                
+            }
+            else if (segment.startsWith("request"))
+            {
+                int pos = segment.indexOf(".");
+                if (pos > -1)
+                {
+                    String parameterName = segment.substring(pos);
+                    this.requestParameter = context.getRequestParameter(parameterName);
+                    if (this.requestParameter != null)
+                    {
+                        key = (first) ? this.requestParameter : key + EhPortletContentCacheElementImpl.KEY_SEPARATOR + this.requestParameter;
+                    }
+                }
+            }
+            else if (segment.startsWith("session"))
+            {
+                int pos = segment.indexOf(".");
+                if (pos > -1)
+                {
+                    String attributeName = segment.substring(pos);
+                    this.sessionAttribute = context.getRequestParameter(attributeName);
+                    if (this.sessionAttribute != null)
+                    {
+                        key = (first) ? this.sessionAttribute : key + EhPortletContentCacheElementImpl.KEY_SEPARATOR + this.sessionAttribute;
+                    }
+                }                
+            }                              
+            first = false;
+        }
+        //System.out.println("*** CACHE KEY IS [" + key + "]");
+    }
+    
+    public JetspeedContentCacheKey()
+    {        
+    }
+    
+    public void createFromUser(String username, String pipeline, String windowId)
+    {
+        this.setUsername(username);
+        this.setPipeline(pipeline);
+        this.setWindowId(windowId);
+        this.key = this.getUsername() + 
+                    EhPortletContentCacheElementImpl.KEY_SEPARATOR + 
+                    this.getPipeline() +
+                    EhPortletContentCacheElementImpl.KEY_SEPARATOR + 
+                    this.getWindowId();
+    }
+
+    public void createFromSession(String sessionId, String pipeline, String windowId)
+    {
+        this.setSessionId(sessionId);
+        this.setPipeline(pipeline);
+        this.setWindowId(windowId);
+        this.key = this.getSessionId() + 
+        EhPortletContentCacheElementImpl.KEY_SEPARATOR + 
+        this.getPipeline() +
+        EhPortletContentCacheElementImpl.KEY_SEPARATOR + 
+        this.getWindowId();        
+    }
+    
+    public String getKey()
+    {
+        return this.key;
+    }
+
+    public String getPipeline()
+    {
+        return this.pipeline;
+    }
+
+    public String getRequestParameter()
+    {
+        return this.requestParameter;
+    }
+
+    public String getSessionAttribute()
+    {
+        return this.sessionAttribute;
+    }
+
+    public String getSessionId()
+    {
+        return this.sessionId;
+    }
+
+    public String getUsername()
+    {
+        return this.username;
+    }
+
+    public String getWindowId()
+    {
+        return this.windowId;
+    }
+
+    
+    public void setPipeline(String pipeline)
+    {
+        this.pipeline = pipeline;
+    }
+
+    
+    public void setRequestParameter(String requestParameter)
+    {
+        this.requestParameter = requestParameter;
+    }
+
+    
+    public void setSessionAttribute(String sessionAttribute)
+    {
+        this.sessionAttribute = sessionAttribute;
+    }
+
+    
+    public void setSessionId(String sessionId)
+    {
+        this.sessionId = sessionId;
+    }
+
+    
+    public void setUsername(String username)
+    {
+        this.username = username;
+    }
+
+    
+    public void setWindowId(String windowId)
+    {
+        this.windowId = windowId;
+    }
+}

Added: portals/jetspeed-2/trunk/components/cm/src/test/org/apache/jetspeed/cache/TestContentCache.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/cm/src/test/org/apache/jetspeed/cache/TestContentCache.java?view=auto&rev=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/cm/src/test/org/apache/jetspeed/cache/TestContentCache.java (added)
+++ portals/jetspeed-2/trunk/components/cm/src/test/org/apache/jetspeed/cache/TestContentCache.java Thu Jun  7 17:49:07 2007
@@ -0,0 +1,364 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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.apache.jetspeed.cache;
+
+import java.io.CharArrayWriter;
+import java.io.PrintWriter;
+import java.security.Principal;
+import java.util.LinkedList;
+import java.util.List;
+
+import junit.framework.TestCase;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+
+import org.apache.jetspeed.aggregator.PortletContent;
+import org.apache.jetspeed.aggregator.PortletRenderer;
+import org.apache.jetspeed.cache.impl.EhPortletContentCacheImpl;
+import org.apache.jetspeed.cache.impl.JetspeedCacheKeyGenerator;
+import org.apache.jetspeed.mockobjects.request.MockRequestContext;
+
+import com.mockrunner.mock.web.MockHttpServletRequest;
+import com.mockrunner.mock.web.MockHttpServletResponse;
+import com.mockrunner.mock.web.MockHttpSession;
+
+/**
+ * <p>
+ * Test Content Cache
+ * </p>
+ * <p>
+ *
+ * </p>
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
+ * @version $Id: TestCachingInterceptors.java 516448 2007-03-09 16:25:47Z ate $
+ *
+ */
+public class TestContentCache extends TestCase
+{
+       
+    public void testContentCacheByUser() throws Exception
+    {
+        // initialize ehCache
+        CacheManager cacheManager = new CacheManager();
+        Cache ehContentCache = new Cache("ehPortletContentCache", 10000, false, false, 28800, 28800);
+        cacheManager.addCache(ehContentCache);
+        ehContentCache.setCacheManager(cacheManager);       
+        
+        // initial Jetspeed caches
+        List segments = new LinkedList();
+        segments.add("username");
+        segments.add("pipeline");
+        segments.add("windowid");
+        ContentCacheKeyGenerator generator = new JetspeedCacheKeyGenerator(segments);
+        JetspeedCache contentCache = new EhPortletContentCacheImpl(ehContentCache, generator);
+        
+        // create the mock request context
+        MockHttpServletRequest request = new MockHttpServletRequest();       
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        request.setUserPrincipal(new MockPrincipal("david"));
+        MockRequestContext context = new MockRequestContext(request, response);
+        
+        // create a simple key
+        String window1 = "555-01";
+        ContentCacheKey cckey1 = contentCache.createCacheKey(context, window1);
+        assertEquals(cckey1.getKey(), "david/portal/555-01");
+
+        // create a another key for desktop
+        String window2 = "555-02";
+        context.getParameterMap().put("encoder", "desktop");
+        ContentCacheKey cckey2 = contentCache.createCacheKey(context, window2);
+        assertEquals(cckey2.getKey(), "david/desktop/555-02");
+        
+        // create some PortletContent mock objects
+        PortletContent content1 = new MockPortletContent(cckey1, 100, "ContentOne", "content1content1content1content1");
+        PortletContent content2 = new MockPortletContent(cckey2, 200, "ContentTwo", "content2content2content2content2");
+        
+        // put it in the cache
+        CacheElement element1 = contentCache.createElement(cckey1, content1);
+        contentCache.put(element1);
+        CacheElement element2 = contentCache.createElement(cckey2, content2);
+        contentCache.put(element2);
+        
+        // assert the gets
+        Object result1 = contentCache.get(cckey1);
+        assertNotNull(result1);
+        System.out.println("result 1 = " + result1);
+        Object result2 = contentCache.get(cckey2);
+        assertNotNull(result2);
+        System.out.println("result 2 = " + result2);
+        
+        // assert isKey Apis        
+        assertTrue(contentCache.isKeyInCache(cckey1));
+                
+        
+        // test removes
+        contentCache.remove(cckey1);
+        assertFalse(contentCache.isKeyInCache(cckey1));        
+        assertTrue(contentCache.isKeyInCache(cckey2));
+        
+        // test user stuff
+        request.setUserPrincipal(new MockPrincipal("sean"));        
+        // create a simple key
+        String window3 = "555-03";
+        ContentCacheKey cckey3 = contentCache.createCacheKey(context, window3);
+        assertEquals(cckey3.getKey(), "sean/desktop/555-03");
+
+        // create a another key for desktop
+        String window4 = "555-04";
+        ContentCacheKey cckey4 = contentCache.createCacheKey(context, window4);
+        assertEquals(cckey4.getKey(), "sean/desktop/555-04");
+        
+        // create some PortletContent mock objects
+        PortletContent content3 = new MockPortletContent(cckey3, 300, "ContentThree", "content3content3content3content3");
+        PortletContent content4 = new MockPortletContent(cckey4, 400, "ContentTwo", "content4content4content4content4");
+        
+        // put it in the cache
+        CacheElement element3 = contentCache.createElement(cckey3, content3);
+        contentCache.put(element3);
+        CacheElement element4 = contentCache.createElement(cckey4, content4);
+        contentCache.put(element4);
+
+        // assert 3 and 4
+        assertTrue(contentCache.isKeyInCache(cckey3));
+        assertTrue(contentCache.isKeyInCache(cckey4));
+        
+        // remove for user
+        contentCache.evictContentForUser("sean");
+        assertFalse(contentCache.isKeyInCache(cckey3));
+        assertFalse(contentCache.isKeyInCache(cckey4));
+        assertTrue(contentCache.isKeyInCache(cckey2));        
+    }
+
+    public void testContentCacheBySession() throws Exception
+    {
+        // initialize ehCache
+        CacheManager cacheManager = new CacheManager();
+        Cache ehContentCache = new Cache("ehPortletContentCache", 10000, false, false, 28800, 28800);
+        cacheManager.addCache(ehContentCache);
+        ehContentCache.setCacheManager(cacheManager);       
+        
+        // initial Jetspeed caches
+        List segments = new LinkedList();
+        segments.add("sessionid");
+        segments.add("pipeline");
+        segments.add("windowid");
+        ContentCacheKeyGenerator generator = new JetspeedCacheKeyGenerator(segments);
+        JetspeedCache contentCache = new EhPortletContentCacheImpl(ehContentCache, generator);
+        
+        // create the mock request context
+        MockHttpServletRequest request = new MockHttpServletRequest();       
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        request.setUserPrincipal(new MockPrincipal("david"));
+        MockHttpSession session = new MockHttpSession();
+        request.setSession(session);
+        String sessionId = session.getId();
+
+        MockRequestContext context = new MockRequestContext(request, response);
+        
+        // create a simple key
+        String window1 = "555-01";
+        ContentCacheKey cckey1 = contentCache.createCacheKey(context, window1);
+        assertEquals(cckey1.getKey(), sessionId + "/portal/555-01");
+
+        // create a another key for desktop
+        String window2 = "555-02";
+        context.getParameterMap().put("encoder", "desktop");
+        ContentCacheKey cckey2 = contentCache.createCacheKey(context, window2);
+        assertEquals(cckey2.getKey(), sessionId + "/desktop/555-02");
+        
+        // create some PortletContent mock objects
+        PortletContent content1 = new MockPortletContent(cckey1, 100, "ContentOne", "content1content1content1content1");
+        PortletContent content2 = new MockPortletContent(cckey2, 200, "ContentTwo", "content2content2content2content2");
+        
+        // put it in the cache
+        CacheElement element1 = contentCache.createElement(cckey1, content1);
+        contentCache.put(element1);
+        CacheElement element2 = contentCache.createElement(cckey2, content2);
+        contentCache.put(element2);
+        
+        // assert the gets
+        Object result1 = contentCache.get(cckey1);
+        assertNotNull(result1);
+        System.out.println("result 1 = " + result1);
+        Object result2 = contentCache.get(cckey2);
+        assertNotNull(result2);
+        System.out.println("result 2 = " + result2);
+        
+        // assert isKey Apis        
+        assertTrue(contentCache.isKeyInCache(cckey1));
+                
+        
+        // test removes
+        contentCache.remove(cckey1);
+        assertFalse(contentCache.isKeyInCache(cckey1));        
+        assertTrue(contentCache.isKeyInCache(cckey2));
+        
+        // test user stuff
+        session = new MockHttpSession();
+        request.setSession(session);        
+        sessionId = session.getId();        
+        request.setUserPrincipal(new MockPrincipal("sean"));        
+        // create a simple key
+        String window3 = "555-03";
+        ContentCacheKey cckey3 = contentCache.createCacheKey(context, window3);
+        assertEquals(cckey3.getKey(), sessionId + "/desktop/555-03");
+
+        // create a another key for desktop
+        String window4 = "555-04";
+        ContentCacheKey cckey4 = contentCache.createCacheKey(context, window4);
+        assertEquals(cckey4.getKey(), sessionId + "/desktop/555-04");
+        
+        // create some PortletContent mock objects
+        PortletContent content3 = new MockPortletContent(cckey3, 300, "ContentThree", "content3content3content3content3");
+        PortletContent content4 = new MockPortletContent(cckey4, 400, "ContentTwo", "content4content4content4content4");
+        
+        // put it in the cache
+        CacheElement element3 = contentCache.createElement(cckey3, content3);
+        contentCache.put(element3);
+        CacheElement element4 = contentCache.createElement(cckey4, content4);
+        contentCache.put(element4);
+
+        // assert 3 and 4
+        assertTrue(contentCache.isKeyInCache(cckey3));
+        assertTrue(contentCache.isKeyInCache(cckey4));
+        
+        // remove for user
+        contentCache.evictContentForSession(sessionId);
+        assertFalse(contentCache.isKeyInCache(cckey3));
+        assertFalse(contentCache.isKeyInCache(cckey4));
+        assertTrue(contentCache.isKeyInCache(cckey2));                      
+    }
+    
+    class MockPrincipal implements Principal
+    {
+        private String name;
+        public MockPrincipal(String name)
+        {
+            this.name = name;
+        }
+        
+        public String getName()
+        {
+            return name;
+        }
+    }
+        
+    class MockPortletContent implements PortletContent
+    {
+        private boolean complete = false;
+        private ContentCacheKey cacheKey;
+        private int expiration = 0;
+        private String title;
+        private String content;
+        
+        
+        MockPortletContent(ContentCacheKey cacheKey, int expiration, String title, String content)
+        {
+            this.cacheKey = cacheKey;
+            this.expiration = expiration;
+            this.title = title;
+            this.content = content;
+        }
+
+       
+        public PrintWriter getWriter()
+        {
+            return null;
+        }
+
+        public void init()
+        {
+        }
+
+        public void release()
+        {
+        }
+
+        public String toString()
+        {
+            return content;
+        }
+
+        public void writeTo( java.io.Writer out ) throws java.io.IOException
+        {
+        }
+
+        public char[] toCharArray()
+        {
+            return content.toCharArray();
+        }
+
+        public boolean isComplete()
+        {
+            return complete;
+        }
+
+        void setComplete(boolean state, boolean notify)
+        {
+            this.complete = state;
+        }
+        
+        public String getContent()
+        {
+            return toString();
+        }
+        /**
+         * <p>
+         * complete
+         * </p>
+         *
+         * @see org.apache.jetspeed.aggregator.PortletContent#complete()
+         * 
+         */
+        public void complete()
+        {
+           setComplete(true, true);
+        }
+        
+        // error case, don't notify 
+        public void completeWithError()
+        {
+            setComplete(true, false);
+        }
+        
+        public ContentCacheKey getCacheKey()
+        {
+            return cacheKey;
+        }
+       
+        public int getExpiration()
+        {
+            return expiration;
+        }
+        
+        public void setExpiration(int expiration)
+        {
+            this.expiration = expiration;
+        }
+        
+        public String getTitle()
+        {
+            return title;
+        }
+        
+        public void setTitle(String title)
+        {
+            this.title = title;
+        }
+    }
+        
+}

Modified: portals/jetspeed-2/trunk/components/page-manager/src/java/JETSPEED-INF/castor/page-mapping.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/page-manager/src/java/JETSPEED-INF/castor/page-mapping.xml?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/page-manager/src/java/JETSPEED-INF/castor/page-mapping.xml (original)
+++ portals/jetspeed-2/trunk/components/page-manager/src/java/JETSPEED-INF/castor/page-mapping.xml Thu Jun  7 17:49:07 2007
@@ -136,7 +136,7 @@
     </field>
 
     <field name="propertiesList"
-           type="org.apache.jetspeed.om.page.psml.PropertyImpl" collection="vector">
+           type="org.apache.jetspeed.om.page.psml.PropertyImpl" collection="arraylist">
       <bind-xml name="property"/>
     </field>
     

Modified: portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/page/psml/FragmentImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/page/psml/FragmentImpl.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/page/psml/FragmentImpl.java (original)
+++ portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/page/psml/FragmentImpl.java Thu Jun  7 17:49:07 2007
@@ -23,7 +23,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Vector;
 
 import org.apache.jetspeed.JetspeedActions;
 import org.apache.jetspeed.om.folder.Folder;
@@ -47,9 +46,9 @@
 
     private String skin = null;
 
-    private List fragments = new Vector();
+    private List fragments = new ArrayList();
 
-    private List propertiesList = new Vector();
+    private List propertiesList = new ArrayList();
     
     private List preferences = new ArrayList();
     
@@ -141,9 +140,9 @@
         return filterFragmentsByAccess(fragmentsList);
     }
 
-    public Vector getPropertiesList()
+    public List getPropertiesList()
     {
-        return (Vector) this.propertiesList;
+        return (List) this.propertiesList;
     }
     
     /**

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletContentImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletContentImpl.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletContentImpl.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletContentImpl.java Thu Jun  7 17:49:07 2007
@@ -21,6 +21,7 @@
 
 import org.apache.jetspeed.aggregator.PortletContent;
 import org.apache.jetspeed.aggregator.PortletRenderer;
+import org.apache.jetspeed.cache.ContentCacheKey;
 
 
 public class PortletContentImpl implements PortletContent
@@ -28,7 +29,7 @@
     private CharArrayWriter cw;
     private PrintWriter writer;
     private boolean complete = false;
-    private String cacheKey;
+    private ContentCacheKey cacheKey;
     private int expiration = 0;
     private String title;
     private PortletRenderer renderer = null;
@@ -38,7 +39,7 @@
         init();
     }
     
-    PortletContentImpl(PortletRenderer renderer, String cacheKey, int expiration, String title)
+    PortletContentImpl(PortletRenderer renderer, ContentCacheKey cacheKey, int expiration, String title)
     {
         this.renderer = renderer;
         this.cacheKey = cacheKey;
@@ -47,7 +48,7 @@
         init();
     }
 
-    PortletContentImpl(PortletRenderer renderer, String cacheKey, int expiration)
+    PortletContentImpl(PortletRenderer renderer, ContentCacheKey cacheKey, int expiration)
     {
         this(renderer, cacheKey, expiration,"no title");
     }
@@ -121,7 +122,7 @@
         setComplete(true, false);
     }
     
-    public String getCacheKey()
+    public ContentCacheKey getCacheKey()
     {
         return cacheKey;
     }

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletRendererImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletRendererImpl.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletRendererImpl.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletRendererImpl.java Thu Jun  7 17:49:07 2007
@@ -40,6 +40,7 @@
 import org.apache.jetspeed.aggregator.UnknownPortletDefinitionException;
 import org.apache.jetspeed.aggregator.WorkerMonitor;
 import org.apache.jetspeed.cache.CacheElement;
+import org.apache.jetspeed.cache.ContentCacheKey;
 import org.apache.jetspeed.cache.JetspeedCache;
 import org.apache.jetspeed.components.portletentity.PortletEntityNotStoredException;
 import org.apache.jetspeed.container.window.FailedToRetrievePortletWindow;
@@ -392,7 +393,7 @@
                                             PortletDefinitionComposite portletDefinition)
         throws Exception
     {
-        String cacheKey = portletContentCache.createCacheKey(requestContext.getUserPrincipal().getName(), fragment.getId());
+        ContentCacheKey cacheKey = portletContentCache.createCacheKey(requestContext, fragment.getId());        
         CacheElement cachedElement = portletContentCache.get(cacheKey);
         if (cachedElement != null)
         {
@@ -409,7 +410,7 @@
     
     public ContentDispatcherCtrl createDispatcher(RequestContext request, ContentFragment fragment, int expirationCache)
     {
-        String cacheKey = portletContentCache.createCacheKey(request.getUserPrincipal().getName(), fragment.getId());
+        ContentCacheKey cacheKey = portletContentCache.createCacheKey(request, fragment.getId());                
         PortletContent content = new PortletContentImpl(this, cacheKey, expirationCache);
         ContentDispatcherCtrl dispatcher = new ContentDispatcherImpl(content); 
         return dispatcher;

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/PortletWindowSessionNavigationalStates.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/PortletWindowSessionNavigationalStates.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/PortletWindowSessionNavigationalStates.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/PortletWindowSessionNavigationalStates.java Thu Jun  7 17:49:07 2007
@@ -25,6 +25,7 @@
 import javax.portlet.WindowState;
 
 import org.apache.jetspeed.Jetspeed;
+import org.apache.jetspeed.cache.ContentCacheKey;
 import org.apache.jetspeed.cache.JetspeedCache;
 import org.apache.jetspeed.container.window.PortletWindowAccessor;
 import org.apache.jetspeed.om.page.Page;
@@ -318,7 +319,7 @@
     
     protected void removeFromCache(RequestContext context, String id, JetspeedCache cache)
     {
-        String cacheKey = cache.createCacheKey(context.getUserPrincipal().getName(), id);
+        ContentCacheKey cacheKey = cache.createCacheKey(context, id);
         if (cache.isKeyInCache(cacheKey))
         {
             cache.remove(cacheKey);

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/engine/JetspeedServlet.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/engine/JetspeedServlet.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/engine/JetspeedServlet.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/engine/JetspeedServlet.java Thu Jun  7 17:49:07 2007
@@ -36,6 +36,7 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.jetspeed.Jetspeed;
 import org.apache.jetspeed.PortalReservedParameters;
+import org.apache.jetspeed.cache.ContentCacheKeyGenerator;
 import org.apache.jetspeed.cache.JetspeedCache;
 import org.apache.jetspeed.components.ComponentManager;
 import org.apache.jetspeed.components.SpringComponentManager;
@@ -352,6 +353,10 @@
         String ipAddress = (String)se.getSession().getAttribute(SecurityValve.IP_ADDRESS);
         statistics.logUserLogout(ipAddress, subjectUserPrincipal.getName(), sessionLength);    
         JetspeedCache portletContentCache = (JetspeedCache)engine.getComponentManager().getComponent("portletContentCache");
-        portletContentCache.evictContentForUser(subjectUserPrincipal.getName());
+        ContentCacheKeyGenerator generator = (ContentCacheKeyGenerator)engine.getComponentManager().getComponent("ContentCacheKeyGenerator");
+        if (generator.isCacheBySessionId())
+            portletContentCache.evictContentForUser(se.getSession().getId());
+        else
+            portletContentCache.evictContentForUser(subjectUserPrincipal.getName());        
     }
 }

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/pipeline/valve/impl/ActionValveImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/pipeline/valve/impl/ActionValveImpl.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/pipeline/valve/impl/ActionValveImpl.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/pipeline/valve/impl/ActionValveImpl.java Thu Jun  7 17:49:07 2007
@@ -28,6 +28,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.jetspeed.PortalReservedParameters;
+import org.apache.jetspeed.cache.ContentCacheKey;
 import org.apache.jetspeed.cache.JetspeedCache;
 import org.apache.jetspeed.container.window.PortletWindowAccessor;
 import org.apache.jetspeed.exception.JetspeedException;
@@ -257,7 +258,7 @@
                 }
             } 
         }    
-        String cacheKey = portletContentCache.createCacheKey(context.getUserPrincipal().getName(), f.getId());
+        ContentCacheKey cacheKey = portletContentCache.createCacheKey(context, f.getId());
         if (portletContentCache.isKeyInCache(cacheKey))
         {
             portletContentCache.remove(cacheKey);
@@ -266,7 +267,7 @@
 
     protected void clearTargetCache(ContentFragment f, RequestContext context)
     {
-        String cacheKey = portletContentCache.createCacheKey(context.getUserPrincipal().getName(), f.getId());
+        ContentCacheKey cacheKey = portletContentCache.createCacheKey(context, f.getId());        
         if (portletContentCache.isKeyInCache(cacheKey))
         {
             portletContentCache.remove(cacheKey);

Modified: portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/aggregator/PortletContent.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/aggregator/PortletContent.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/aggregator/PortletContent.java (original)
+++ portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/aggregator/PortletContent.java Thu Jun  7 17:49:07 2007
@@ -24,6 +24,8 @@
 
 import java.io.PrintWriter;
 
+import org.apache.jetspeed.cache.ContentCacheKey;
+
 /**
  * <p>
  * PortletContent
@@ -78,10 +80,11 @@
     void setExpiration(int expiration);
     
     /**
-     * Get the cache key used to cache this content 
+     * Get the cache key used to cache this content
+     * @since 2.1.1 
      * @return
      */
-    String getCacheKey();
+    ContentCacheKey getCacheKey();
     
     /**
      * Get the title of the portlet, used during caching

Added: portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheElement.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheElement.java?view=auto&rev=545356
==============================================================================
--- portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheElement.java (added)
+++ portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheElement.java Thu Jun  7 17:49:07 2007
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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.apache.jetspeed.cache;
+
+/**
+ * <p>
+ * specialized portlet content cache key 
+ * </p>
+ * 
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: $
+ */
+public interface ContentCacheElement extends CacheElement
+{
+    ContentCacheKey getContentCacheKey();
+}
\ No newline at end of file

Added: portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheKey.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheKey.java?view=auto&rev=545356
==============================================================================
--- portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheKey.java (added)
+++ portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheKey.java Thu Jun  7 17:49:07 2007
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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.apache.jetspeed.cache;
+
+import java.io.Serializable;
+
+
+/**
+ * <p>
+ *  Provides interface to all Content Caches (Portlet API cache)
+ * </p>
+ * 
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: $
+ */
+public interface ContentCacheKey extends Serializable
+{
+    /**
+     * Get the username or null if not used
+     * @return
+     */
+    String getUsername();
+    
+    /**
+     * Get the pipeline name or null if not used
+     * @return
+     */
+    String getPipeline();
+    
+    /**
+     * Get the window (portlet fragment) id
+     * @return
+     */
+    String getWindowId();
+    
+    /**
+     * Get the session id or null if not used
+     * 
+     * @return
+     */
+    String getSessionId();
+    
+    /**
+     * 
+     * @return
+     */
+    String getRequestParameter();
+    
+    /**
+     * 
+     * @return
+     */
+    String getSessionAttribute();
+    
+    /**
+     * Return the full key as a string
+     * @return
+     */
+    String getKey();
+    
+    void createFromUser(String username, String pipeline, String windowId);
+    
+    void createFromSession(String sessionid, String pipeline, String windowId);
+}
\ No newline at end of file

Added: portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheKeyGenerator.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheKeyGenerator.java?view=auto&rev=545356
==============================================================================
--- portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheKeyGenerator.java (added)
+++ portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/ContentCacheKeyGenerator.java Thu Jun  7 17:49:07 2007
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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.apache.jetspeed.cache;
+
+import org.apache.jetspeed.request.RequestContext;
+
+/**
+ * <p>
+ *  Provides interface to Jetspeed for content cache key generation
+ * </p>
+ * 
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: $
+ */
+public interface ContentCacheKeyGenerator
+{
+    /**
+     * Normalized and pluggable cache key generator
+     * 
+     * @param context
+     * @param windowId The window id of the portlet to be cached.
+     * @since 2.1.1
+     * @return
+     */
+    ContentCacheKey createCacheKey(RequestContext context, String windowId);
+    
+    /**
+     * Create a cache key without request context information, but by providing required parameters username and windowid
+     * 
+     * @param username
+     * @param pipeline "desktop" or "portal"
+     * @param windowId
+     * @return
+     */
+    ContentCacheKey createUserCacheKey(String username, String pipeline, String windowId);
+
+    /**
+     * Create a cache key without request context information, but by providing required parameters sessinid and windowid
+     * 
+     * @param sessionid
+     * @param pipeline "desktop" or "portal"
+     * @param windowId
+     * @return
+     */
+    ContentCacheKey createSessionCacheKey(String sessionid, String pipeline, String windowId);
+    
+    /**
+     *  return true if caching is by session id, not username
+     *  
+     * @return
+     */
+    boolean isCacheBySessionId();
+    
+    /**
+     *  return true if caching is by username, not sessionid
+     *  
+     * @return
+     */    
+    boolean isCacheByUsername();
+}
\ No newline at end of file

Modified: portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/JetspeedCache.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/JetspeedCache.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/JetspeedCache.java (original)
+++ portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cache/JetspeedCache.java Thu Jun  7 17:49:07 2007
@@ -16,6 +16,8 @@
  */
 package org.apache.jetspeed.cache;
 
+import org.apache.jetspeed.request.RequestContext;
+
 /**
  * <p>
  *  Provides interface to Jetspeed for cache related activities
@@ -86,20 +88,28 @@
     int getTimeToLiveSeconds();
 
     /**
-     * Evict all cached content for the given user
+     * Evict all cached content for the given username 
      * 
-     * @param user
+     * @param username unique user identifier
      */
-    void evictContentForUser(String user);
+    void evictContentForUser(String username);
+
+    /**
+     * Evict all cached content for the given session identifier 
+     * 
+     * @param sessionid unique session identifier
+     */    
+    void evictContentForSession(String sessionId);
     
     /**
-     * Create a cache key from a primary segment and secondary segment
+     * Create a portlet content cache key based on dynamic request context information and a window id
      * 
-     * @param primary
-     * @param secondary
+     * @param rc
+     * @param windowId
+     * @since 2.1.1
      * @return
      */
-    String createCacheKey(String primary, String secondary);
+    ContentCacheKey createCacheKey(RequestContext rc, String windowId);
     
     /**
      * Add a cache listener for supported cache events, either for local or remote cache events

Modified: portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/mockobjects/request/MockRequestContext.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/mockobjects/request/MockRequestContext.java?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/mockobjects/request/MockRequestContext.java (original)
+++ portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/mockobjects/request/MockRequestContext.java Thu Jun  7 17:49:07 2007
@@ -285,8 +285,7 @@
     
     public Principal getUserPrincipal()
     {
-        // TODO: implement
-        return null;
+        return request.getUserPrincipal();
     }
 
     /*

Modified: portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/cache.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/cache.xml?view=diff&rev=545356&r1=545355&r2=545356
==============================================================================
--- portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/cache.xml (original)
+++ portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/cache.xml Thu Jun  7 17:49:07 2007
@@ -35,6 +35,26 @@
 		<property name="cacheName" value="portletContentCache" />
 	</bean>
 
+    <bean id="ContentCacheKeyGenerator" class="org.apache.jetspeed.cache.impl.JetspeedCacheKeyGenerator">
+    	<!-- Keys are order specific in the list:
+    		 where username  == the user principal name of the current user
+    		       pipeline  == the name of the active pipeline for the current request (portal | desktop)
+    		       windowid  == the window id (fragment id) of the portlet
+    		       sessionid == the current session id 
+    		       request.{param.name} == request parameter name, such "request.myparam"
+    		       session.{attribute-name} == session attribute name, such "session.myattribute"
+    		       
+    		       username|sessionid AND windowid are required
+    	-->
+    	<constructor-arg index='0'>
+    		<list>
+    			<value>sessionid</value>
+    			<value>pipeline</value>
+    			<value>windowid</value>
+    		</list>
+    	</constructor-arg>
+    </bean>
+    
 	<bean id="portletContentCache"
 		class="org.apache.jetspeed.cache.impl.EhPortletContentCacheImpl">
 		<constructor-arg index="0">
@@ -42,6 +62,9 @@
 		</constructor-arg>
 		<constructor-arg index="1">
 			<ref bean="preferencesCache" />
+		</constructor-arg>
+		<constructor-arg index="2">
+		   <ref bean="ContentCacheKeyGenerator"/>
 		</constructor-arg>
 	</bean>
 



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


Mime
View raw message