portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rwat...@apache.org
Subject svn commit: r918656 [1/3] - in /portals/jetspeed-2/portal/trunk: components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/impl/ components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/ components/jetspeed-page-man...
Date Wed, 03 Mar 2010 19:34:47 GMT
Author: rwatler
Date: Wed Mar  3 19:34:46 2010
New Revision: 918656

URL: http://svn.apache.org/viewvc?rev=918656&view=rev
Log:
Scoped Fragment Property Cache Refactoring
-----------------------------------------------------
- add DBPM cache of user/principal specific scoped fragment properties.
- merge principal and global scoped fragment properties on DBPM access.
- revise DBPM cache notifications to minimize clustered PSML and properties cache notifications.
- upgrade ehcache to 1.7.2 to ensure removeQuiet() operations are not replicated in clustered
environment.
- extend cache test cases to include tests of new scoped fragment properties cache operation.


Added:
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/DatabasePageManagerCachedFragmentPropertyList.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/DatabasePageManagerFragmentKeyCacheObject.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/DatabasePageManagerPrincipalKeyCacheObject.java
Modified:
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/impl/FragmentPropertyList.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/DatabasePageManager.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/DatabasePageManagerCache.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/DatabasePageManagerCacheObject.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/TransactionedOperation.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/java/org/apache/jetspeed/page/cache/DatabasePageManagerServer.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/java/org/apache/jetspeed/page/cache/TestDatabasePageManagerCache.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/resources/database-page-manager-base.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/resources/database-page-manager.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/resources/distributed-ehcache.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/resources/ehcache.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/resources/log4j-stdout.properties
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/resources/log4j.properties
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/resources/secure-database-page-manager.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/resources/secure-permissions-database-page-manager.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-portal-site/src/test/resources/cache-test.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/assembly/cache-test.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/test/resources/cache-test.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-registry/src/test/resources/cache-test.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/resources/cache-test.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-sso/src/test/resources/cache-test.xml
    portals/jetspeed-2/portal/trunk/etc/import/assembly/import-page-manager.xml
    portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/cache.xml
    portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/page-manager.xml
    portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/db-ojb/distributed-ehcache.xml
    portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/db-ojb/ehcache.xml

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/impl/FragmentPropertyList.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/impl/FragmentPropertyList.java?rev=918656&r1=918655&r2=918656&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/impl/FragmentPropertyList.java
(original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/impl/FragmentPropertyList.java
Wed Mar  3 19:34:46 2010
@@ -182,6 +182,18 @@
         }
         return null;
     }
+    
+    /**
+     * Clear all transient properties.
+     */
+    public synchronized void clearProperties()
+    {
+        properties.clear();
+        if (removedProperties != null)
+        {
+            removedProperties.clear();
+        }
+    }
 
     /**
      * Recycle removed property.

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/DatabasePageManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/DatabasePageManager.java?rev=918656&r1=918655&r2=918656&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/DatabasePageManager.java
(original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/impl/DatabasePageManager.java
Wed Mar  3 19:34:46 2010
@@ -18,6 +18,7 @@
 
 import java.security.AccessController;
 import java.security.Principal;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -117,6 +118,9 @@
 import org.apache.ojb.broker.query.QueryByCriteria;
 import org.apache.ojb.broker.query.QueryFactory;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * DatabasePageManager
  * 
@@ -126,6 +130,8 @@
  */
 public class DatabasePageManager extends InitablePersistenceBrokerDaoSupport implements PageManager
 {
+    private static Logger log = LoggerFactory.getLogger(DatabasePageManager.class);
+    
     private static ThreadLocal fragmentPropertyListsCache = new ThreadLocal();
     
     private static Map modelClasses = new HashMap();
@@ -166,11 +172,12 @@
     
     private PageManager pageManagerProxy;
 
-    public DatabasePageManager(String repositoryPath, IdGenerator generator, boolean isPermissionsSecurity,
boolean isConstraintsSecurity, JetspeedCache oidCache, JetspeedCache pathCache, JetspeedCache
propertiesCache, JetspeedCache propertiesPathCache)
+    public DatabasePageManager(String repositoryPath, IdGenerator generator, boolean isPermissionsSecurity,
boolean isConstraintsSecurity, JetspeedCache oidCache, JetspeedCache pathCache,
+                               JetspeedCache propertiesCache, JetspeedCache propertiesPathCache,
JetspeedCache principalPropertiesCache, JetspeedCache principalPropertiesPathCache)
     {
         super(repositoryPath);
         delegator = new DelegatingPageManager(generator, isPermissionsSecurity, isConstraintsSecurity,
modelClasses);
-        DatabasePageManagerCache.cacheInit(oidCache, pathCache, propertiesCache, propertiesPathCache,
this);
+        DatabasePageManagerCache.cacheInit(oidCache, pathCache, propertiesCache, propertiesPathCache,
principalPropertiesCache, principalPropertiesPathCache, this);
     }
 
     /**
@@ -2561,11 +2568,11 @@
         if (pages.length > 0 && pages[0].getPath().equals("/tx__test1.psml"))
         {
             // for tx testing
-            System.out.println("Adding first page");
+            log.debug("Adding first page");
             this.updatePage(pages[0]);
-            System.out.println("Adding second page");
+            log.debug("Adding second page");
             this.updatePage(pages[1]);
-            System.out.println("About to throw ex");
+            log.debug("About to throw ex");
             throw new NodeException("Its gonna blow captain!");
         }
         for (int ix = 0; ix < pages.length; ix++)
@@ -2663,41 +2670,32 @@
     public FragmentPropertyList getFragmentPropertyList(BaseFragmentElementImpl baseFragmentElementImpl,
FragmentPropertyList transientList)
     {
         // access thread local fragment property lists cache
-        String cacheKey = getFragmentPropertyListCacheKey(baseFragmentElementImpl);
+        String fragmentKey = getFragmentPropertyListFragmentKey(baseFragmentElementImpl);
+        Subject subject = JSSubject.getSubject(AccessController.getContext());
+        Principal userPrincipal = ((subject != null) ? SubjectHelper.getBestPrincipal(subject,
User.class) : null);
+        String fragmentListKey = getFragmentPropertyListKey(fragmentKey, userPrincipal);
         Map threadLocalCache = (Map)fragmentPropertyListsCache.get();
+        FragmentPropertyList list = ((threadLocalCache != null) ? (FragmentPropertyList)threadLocalCache.get(fragmentListKey)
: null);
 
-        // get cached persistent list
-        FragmentPropertyList list = ((threadLocalCache != null) ? (FragmentPropertyList)threadLocalCache.get(cacheKey)
: null);
+        // get and cache persistent list
         if (list == null)
         {
-            // lookup fragment property list in cache
-            list = DatabasePageManagerCache.fragmentPropertyListCacheLookup(cacheKey);
-            
-            // save fragment property list in thread local cache
-            if (list != null)
+            // get cached fragment property list components or
+            // query from database if not cached and cache
+            DatabasePageManagerCachedFragmentPropertyList globalFragmentPropertyList = DatabasePageManagerCache.fragmentPropertyListCacheLookup(fragmentKey);
+            if (globalFragmentPropertyList == null)
             {
-                if (threadLocalCache == null)
-                {
-                    threadLocalCache = new HashMap();
-                    fragmentPropertyListsCache.set(threadLocalCache);
-                }
-                threadLocalCache.put(cacheKey, list);
+                globalFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(baseFragmentElementImpl.getBaseFragmentsElement().getPath());
+                Criteria filter = new Criteria();
+                filter.addEqualTo("fragment", new Integer(baseFragmentElementImpl.getIdentity()));
+                filter.addIsNull("scope");
+                QueryByCriteria query = QueryFactory.newQuery(FragmentPropertyImpl.class,
filter);
+                Collection fragmentProperties = getPersistenceBrokerTemplate().getCollectionByQuery(query);
+                globalFragmentPropertyList.addAll(fragmentProperties);
+                DatabasePageManagerCache.fragmentPropertyListCacheAdd(fragmentKey, globalFragmentPropertyList,
false);
             }
-        }
-        if (list == null)
-        {
-            // use transient list or create new fragment property list
-            list = ((transientList != null) ? transientList : new FragmentPropertyList(baseFragmentElementImpl));
-            
-            // build fragment properties database query
-            Criteria filter = new Criteria();
-            filter.addEqualTo("fragment", new Integer(baseFragmentElementImpl.getIdentity()));
-            Criteria scopesFilter = new Criteria();
-            Criteria globalScopeFilter = new Criteria();
-            globalScopeFilter.addIsNull("scope");
-            scopesFilter.addOrCriteria(globalScopeFilter);
-            // add scopes for current user, groups, and roles
-            Subject subject = JSSubject.getSubject(AccessController.getContext());
+            Map principalFragmentPropertyLists = null;
+            DatabasePageManagerCachedFragmentPropertyList userFragmentPropertyList = null;
             if (subject != null)
             {
                 if (GROUP_AND_ROLE_PROPERTY_SCOPES_ENABLED)
@@ -2707,61 +2705,116 @@
                     while (principalsIter.hasNext())
                     {
                         Principal principal = (Principal)principalsIter.next();
+                        String principalScope = null;
                         if (principal instanceof User)
                         {
-                            Criteria userScopeFilter = new Criteria();
-                            userScopeFilter.addEqualTo("scope", USER_PROPERTY_SCOPE);
-                            userScopeFilter.addEqualTo("scopeValue", principal.getName());
-                            scopesFilter.addOrCriteria(userScopeFilter);
+                            principalScope = USER_PROPERTY_SCOPE;
                         }
                         else if (principal instanceof Group)
                         {
-                            Criteria groupScopeFilter = new Criteria();
-                            groupScopeFilter.addEqualTo("scope", GROUP_PROPERTY_SCOPE);
-                            groupScopeFilter.addEqualTo("scopeValue", principal.getName());
-                            scopesFilter.addOrCriteria(groupScopeFilter);
+                            principalScope = GROUP_PROPERTY_SCOPE;
                         }
                         else if (principal instanceof Role)
                         {
-                            Criteria roleScopeFilter = new Criteria();
-                            roleScopeFilter.addEqualTo("scope", ROLE_PROPERTY_SCOPE);
-                            roleScopeFilter.addEqualTo("scopeValue", principal.getName());
-                            scopesFilter.addOrCriteria(roleScopeFilter);
+                            principalScope = ROLE_PROPERTY_SCOPE;
+                        }
+                        if (principalScope != null)
+                        {
+                            String principalKey = getFragmentPropertyListPrincipalKey(principalScope,
principal.getName());
+                            DatabasePageManagerCachedFragmentPropertyList principalFragmentPropertyList
= DatabasePageManagerCache.principalFragmentPropertyListCacheLookup(principalKey);
+                            if (principalFragmentPropertyList == null)
+                            {
+                                principalFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(principalScope,
principalKey);
+                                Criteria filter = new Criteria();
+                                filter.addEqualTo("scope", principalScope);
+                                filter.addEqualTo("scopeValue", principal.getName());
+                                QueryByCriteria query = QueryFactory.newQuery(FragmentPropertyImpl.class,
filter);
+                                Collection fragmentProperties = getPersistenceBrokerTemplate().getCollectionByQuery(query);
+                                principalFragmentPropertyList.addAll(fragmentProperties);
+                                DatabasePageManagerCache.principalFragmentPropertyListCacheAdd(principalKey,
principalFragmentPropertyList, false);
+                            }
+                            if (principalFragmentPropertyList != null)
+                            {
+                                if (principalFragmentPropertyLists == null)
+                                {
+                                    principalFragmentPropertyLists = new HashMap();
+                                }
+                                principalFragmentPropertyLists.put(principalKey, principalFragmentPropertyList);
+                            }
                         }
                     }
                 }
-                else
+                else if (userPrincipal != null)
                 {
-                    Principal userPrincipal = SubjectHelper.getBestPrincipal(subject, User.class);
-                    if (userPrincipal != null)
+                    String principalKey = getFragmentPropertyListPrincipalKey(USER_PROPERTY_SCOPE,
userPrincipal.getName());
+                    userFragmentPropertyList = DatabasePageManagerCache.principalFragmentPropertyListCacheLookup(principalKey);
+                    if (userFragmentPropertyList == null)
                     {
-                        Criteria userScopeFilter = new Criteria();
-                        userScopeFilter.addEqualTo("scope", USER_PROPERTY_SCOPE);
-                        userScopeFilter.addEqualTo("scopeValue", userPrincipal.getName());
-                        scopesFilter.addOrCriteria(userScopeFilter);
+                        userFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(USER_PROPERTY_SCOPE,
principalKey);
+                        Criteria filter = new Criteria();
+                        filter.addEqualTo("scope", USER_PROPERTY_SCOPE);
+                        filter.addEqualTo("scopeValue", userPrincipal.getName());
+                        QueryByCriteria query = QueryFactory.newQuery(FragmentPropertyImpl.class,
filter);
+                        Collection fragmentProperties = getPersistenceBrokerTemplate().getCollectionByQuery(query);
+                        userFragmentPropertyList.addAll(fragmentProperties);
+                        DatabasePageManagerCache.principalFragmentPropertyListCacheAdd(principalKey,
userFragmentPropertyList, false);
                     }
                 }
             }
-            filter.addAndCriteria(scopesFilter);
-            // query for fragment properties for list using database query
-            QueryByCriteria query = QueryFactory.newQuery(FragmentPropertyImpl.class, filter);
-            Collection fragmentProperties = getPersistenceBrokerTemplate().getCollectionByQuery(query);
-            list.getProperties().addAll(fragmentProperties);
-        
-            // save fragment property list in thread local cache
-            if (threadLocalCache == null)
+            
+            // assemble fragment property list instance, (use transient
+            // list or create new fragment property list)
+            list = new FragmentPropertyList(baseFragmentElementImpl);
+            list.getProperties().addAll(globalFragmentPropertyList);
+            if (subject != null)
             {
-                threadLocalCache = new HashMap();
-                fragmentPropertyListsCache.set(threadLocalCache);
+                if (GROUP_AND_ROLE_PROPERTY_SCOPES_ENABLED)
+                {
+                    if (principalFragmentPropertyLists != null)
+                    {                        
+                        Set principals = subject.getPrincipals();
+                        Iterator principalsIter = principals.iterator();
+                        while (principalsIter.hasNext())
+                        {
+                            Principal principal = (Principal)principalsIter.next();
+                            String principalScope = null;
+                            if (principal instanceof User)
+                            {
+                                principalScope = USER_PROPERTY_SCOPE;
+                            }
+                            else if (principal instanceof Group)
+                            {
+                                principalScope = GROUP_PROPERTY_SCOPE;
+                            }
+                            else if (principal instanceof Role)
+                            {
+                                principalScope = ROLE_PROPERTY_SCOPE;
+                            }
+                            if (principalScope != null)
+                            {
+                                String principalKey = getFragmentPropertyListPrincipalKey(principalScope,
principal.getName());
+                                DatabasePageManagerCachedFragmentPropertyList principalFragmentPropertyList
= (DatabasePageManagerCachedFragmentPropertyList)principalFragmentPropertyLists.get(principalKey);
+                                List principalFragmentProperties = filterPrincipalFragmentPropertyList(principalFragmentPropertyList,
baseFragmentElementImpl);
+                                if (principalFragmentProperties != null)
+                                {
+                                    list.getProperties().addAll(principalFragmentProperties);
+                                }
+                            }
+                        }
+                    }
+                }
+                else if (userFragmentPropertyList != null)
+                {
+                    List userFragmentProperties = filterPrincipalFragmentPropertyList(userFragmentPropertyList,
baseFragmentElementImpl);
+                    if (userFragmentProperties != null)
+                    {
+                        list.getProperties().addAll(userFragmentProperties);
+                    }
+                }
             }
-            threadLocalCache.put(cacheKey, list);
 
-            // save fragment property list in cache
-            DatabasePageManagerCache.fragmentPropertyListCacheAdd(cacheKey, list, false,
false);
-        }
-        else if (transientList != null)
-        {
-            synchronized (list)
+            // merge results into transient list if specified
+            if ((list != null) && (transientList != null))
             {
                 synchronized (transientList)
                 {
@@ -2786,14 +2839,17 @@
                     }
                     
                     // clear transient list
-                    transientList.getProperties().clear();
-                    List removedProperties = transientList.getRemovedProperties();
-                    if (removedProperties != null)
-                    {
-                        removedProperties.clear();
-                    }
+                    transientList.clearProperties();
                 }
             }
+
+            // save fragment property list in thread local cache
+            if (threadLocalCache == null)
+            {
+                threadLocalCache = new HashMap();
+                fragmentPropertyListsCache.set(threadLocalCache);
+            }
+            threadLocalCache.put(fragmentListKey, list);
         }
         return list;
     }
@@ -2811,35 +2867,141 @@
         FragmentPropertyList list = getFragmentPropertyList(baseFragmentElementImpl, transientList);
         if (list != null)
         {
+            // get subject
+            Subject subject = JSSubject.getSubject(AccessController.getContext());
+            Principal userPrincipal = ((subject != null) ? SubjectHelper.getBestPrincipal(subject,
User.class) : null);
+            String userPrincipalKey = ((userPrincipal != null) ? getFragmentPropertyListPrincipalKey(USER_PROPERTY_SCOPE,
userPrincipal.getName()) : null);
+            
             // update fragment properties in list in database
             boolean updateAllScopes = ((scope != null) && scope.equals(ALL_PROPERTY_SCOPE));
             synchronized (list)
             {
-                // store property objects for add/update
-                boolean update = false;
-                boolean sharedUpdate = false;
-                Iterator propertiesIter = list.getProperties().iterator();
+                // store property objects for add/update and decompose
+                // update into cache updates, (assumes scoped property
+                // extents are fully represented in list).
+                boolean updateTransaction = false;
+                DatabasePageManagerCachedFragmentPropertyList globalFragmentPropertyList
= null;
+                Map principalPartialFragmentPropertyLists = null;
+                String fragmentKey = getFragmentPropertyListFragmentKey(baseFragmentElementImpl);
+                List properties = list.getProperties();
+                List removedProperties = list.getRemovedProperties();
+                
+                // construct scoped properties lists for cache updates from
+                // all properties, (add, update, and remove)
+                List allProperties = new ArrayList(properties);
+                if (removedProperties != null)
+                {
+                    allProperties.addAll(removedProperties);                    
+                }
+                Iterator allPropertiesIter = allProperties.iterator();
+                while (allPropertiesIter.hasNext())
+                {
+                    FragmentPropertyImpl property = (FragmentPropertyImpl)allPropertiesIter.next();
+                    property.setFragment(baseFragmentElementImpl);
+                    String propertyScope = property.getScope();
+                    String propertyScopeValue = property.getScopeValue();
+                    if (updateAllScopes || ((scope == null) && (propertyScope ==
null)) || ((scope != null) && scope.equals(propertyScope)))
+                    {
+                        // classify property by scopes and create scoped lists
+                        if (propertyScope == null)
+                        {
+                            if (globalFragmentPropertyList == null)
+                            {
+                                globalFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(baseFragmentElementImpl.getBaseFragmentsElement().getPath());
+                            }
+                        }
+                        else if ((subject != null) && GROUP_AND_ROLE_PROPERTY_SCOPES_ENABLED)
+                        {
+                            boolean subjectHasPrincipal = false;
+                            if (propertyScope.equals(USER_PROPERTY_SCOPE))
+                            {
+                                subjectHasPrincipal = ((userPrincipal != null) &&
userPrincipal.getName().equals(propertyScopeValue));
+                            }
+                            else if (propertyScope.equals(GROUP_PROPERTY_SCOPE))
+                            {
+                                subjectHasPrincipal = (SubjectHelper.getPrincipal(subject,
Group.class, propertyScopeValue) != null);
+                            }
+                            else if (propertyScope.equals(ROLE_PROPERTY_SCOPE))
+                            {
+                                subjectHasPrincipal = (SubjectHelper.getPrincipal(subject,
Role.class, propertyScopeValue) != null);
+                            }
+                            if (subjectHasPrincipal)
+                            {
+                                if (principalPartialFragmentPropertyLists == null)
+                                {
+                                    principalPartialFragmentPropertyLists = new HashMap();
+                                }
+                                String principalKey = getFragmentPropertyListPrincipalKey(propertyScope,
propertyScopeValue);
+                                DatabasePageManagerCachedFragmentPropertyList principalPartialFragmentPropertyList
= (DatabasePageManagerCachedFragmentPropertyList)principalPartialFragmentPropertyLists.get(principalKey);
+                                if (principalPartialFragmentPropertyList == null)
+                                {
+                                    principalPartialFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(propertyScope,
principalKey);
+                                    principalPartialFragmentPropertyLists.put(principalKey,
principalPartialFragmentPropertyList);
+                                }
+                            }
+                        }
+                        else if ((subject != null) && propertyScope.equals(USER_PROPERTY_SCOPE))
+                        {
+                            if ((userPrincipal != null) && userPrincipal.getName().equals(propertyScopeValue))
+                            {
+                                if (principalPartialFragmentPropertyLists == null)
+                                {
+                                    principalPartialFragmentPropertyLists = new HashMap();
+                                }
+                                DatabasePageManagerCachedFragmentPropertyList principalPartialFragmentPropertyList
= (DatabasePageManagerCachedFragmentPropertyList)principalPartialFragmentPropertyLists.get(userPrincipalKey);
+                                if (principalPartialFragmentPropertyList == null)
+                                {
+                                    principalPartialFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(USER_PROPERTY_SCOPE,
userPrincipalKey);
+                                    principalPartialFragmentPropertyLists.put(userPrincipalKey,
principalPartialFragmentPropertyList);
+                                }
+                            }
+                        }
+                    }
+                }
+                
+                // populate properties lists for cache updates and
+                // update persistent properties
+                Iterator propertiesIter = properties.iterator();
                 while (propertiesIter.hasNext())
                 {
                     FragmentPropertyImpl storeProperty = (FragmentPropertyImpl)propertiesIter.next();
-                    storeProperty.setFragment(baseFragmentElementImpl);
                     String storePropertyScope = storeProperty.getScope();
+                    String storePropertyScopeValue = storeProperty.getScopeValue();
                     if (updateAllScopes || ((scope == null) && (storePropertyScope
== null)) || ((scope != null) && scope.equals(storePropertyScope)))
                     {
-                        // track operation type
-                        if (storeProperty.getIdentity() != 0)
+                        // classify and decompose update into individual caches:
+                        // allow update only if scoped properties list created above
+                        // exists since the subject matching rules are checked there
+                        updateTransaction = (updateTransaction || (storeProperty.getIdentity()
!= 0));
+                        boolean store = false;
+                        if (storePropertyScope == null)
+                        {
+                            if (globalFragmentPropertyList != null)
+                            {
+                                globalFragmentPropertyList.add(storeProperty);
+                                store = true;
+                            }
+                        }
+                        else if (subject != null)
                         {
-                            update = true;
+                            if (principalPartialFragmentPropertyLists != null)
+                            {
+                                String principalKey = getFragmentPropertyListPrincipalKey(storePropertyScope,
storePropertyScopeValue);
+                                DatabasePageManagerCachedFragmentPropertyList principalPartialFragmentPropertyList
= (DatabasePageManagerCachedFragmentPropertyList)principalPartialFragmentPropertyLists.get(principalKey);
+                                if (principalPartialFragmentPropertyList != null)
+                                {
+                                    principalPartialFragmentPropertyList.add(storeProperty);
+                                    store = true;
+                                }
+                            }
                         }
-                        if ((storePropertyScope == null) || !storePropertyScope.equals(USER_PROPERTY_SCOPE))
+                        // store persistent property object
+                        if (store)
                         {
-                            sharedUpdate = true;
+                            getPersistenceBrokerTemplate().store(storeProperty);
                         }
-                        // store property object
-                        getPersistenceBrokerTemplate().store(storeProperty);
                     }
                 }
-                List removedProperties = list.getRemovedProperties();
                 if (removedProperties != null)
                 {
                     Iterator removedPropertiesIter = removedProperties.iterator();
@@ -2848,25 +3010,66 @@
                         FragmentPropertyImpl deleteProperty = (FragmentPropertyImpl)removedPropertiesIter.next();
                         deleteProperty.setFragment(baseFragmentElementImpl);
                         String deletePropertyScope = deleteProperty.getScope();
+                        String deletePropertyScopeValue = deleteProperty.getScopeValue();
                         if (updateAllScopes || ((scope == null) && (deletePropertyScope
== null)) || ((scope != null) && scope.equals(deletePropertyScope)))
                         {
-                            // track operation type
-                            update = true;
-                            if ((deletePropertyScope == null) || !deletePropertyScope.equals(USER_PROPERTY_SCOPE))
+                            // classify and decompose delete: allow delete only
+                            // if scoped properties list created above exists
+                            // since the subject matching rules are checked there
+                            updateTransaction = true;
+                            boolean delete = false;
+                            if (deletePropertyScope == null)
                             {
-                                sharedUpdate = true;
+                                delete = (globalFragmentPropertyList != null);
+                            }
+                            else if (subject != null)
+                            {
+                                if (principalPartialFragmentPropertyLists != null)
+                                {
+                                    String principalKey = getFragmentPropertyListPrincipalKey(deletePropertyScope,
deletePropertyScopeValue);
+                                    delete = principalPartialFragmentPropertyLists.containsKey(principalKey);
+                                }
+                            }
+                            // delete persistent property object
+                            if (delete)
+                            {
+                                getPersistenceBrokerTemplate().delete(deleteProperty);
                             }
-                            // delete property object
-                            getPersistenceBrokerTemplate().delete(deleteProperty);
                         }
                     }
                 }
                 
                 // interoperate with cache to signal update operations and
                 // record thread transactions
-                String cacheKey = getFragmentPropertyListCacheKey(baseFragmentElementImpl);
-                String transactionOperationPath = DatabasePageManagerCache.fragmentPropertyListCacheAdd(cacheKey,
list, (update || sharedUpdate), sharedUpdate);
-                DatabasePageManagerCache.addTransaction(new TransactionedOperation(transactionOperationPath,
(update ? TransactionedOperation.UPDATE_FRAGMENT_PROPERTIES_OPERATION : TransactionedOperation.ADD_FRAGMENT_PROPERTIES_OPERATION)));
+                if (globalFragmentPropertyList != null)
+                {
+                    // cache new global fragment property list
+                    DatabasePageManagerCache.fragmentPropertyListCacheAdd(fragmentKey, globalFragmentPropertyList,
true);
+                    DatabasePageManagerCache.addTransaction(new TransactionedOperation(fragmentKey,
(updateTransaction ? TransactionedOperation.UPDATE_FRAGMENT_PROPERTIES_OPERATION : TransactionedOperation.ADD_FRAGMENT_PROPERTIES_OPERATION)));
+                }
+                if (principalPartialFragmentPropertyLists != null)
+                {
+                    // update cached principal scoped fragment property lists
+                    Iterator listsIter = principalPartialFragmentPropertyLists.entrySet().iterator();
+                    while (listsIter.hasNext())
+                    {
+                        Map.Entry entry = (Map.Entry)listsIter.next();
+                        String principalKey = (String)entry.getKey();
+                        DatabasePageManagerCachedFragmentPropertyList principalPartialFragmentPropertyList
= (DatabasePageManagerCachedFragmentPropertyList)entry.getValue();
+                        // update cached principal scoped fragment property list
+                        DatabasePageManagerCachedFragmentPropertyList cachedPrincipalFragmentPropertyList
= DatabasePageManagerCache.principalFragmentPropertyListCacheLookup(principalKey);
+                        if (cachedPrincipalFragmentPropertyList != null)
+                        {
+                            synchronized (cachedPrincipalFragmentPropertyList)
+                            {
+                                removeAllPrincipalFragmentPropertyList(cachedPrincipalFragmentPropertyList,
baseFragmentElementImpl);
+                                cachedPrincipalFragmentPropertyList.addAll(principalPartialFragmentPropertyList);
+                            }
+                            DatabasePageManagerCache.principalFragmentPropertyListCacheAdd(principalKey,
cachedPrincipalFragmentPropertyList, true);
+                        }
+                        DatabasePageManagerCache.addTransaction(new TransactionedOperation(principalKey,
(updateTransaction ? TransactionedOperation.UPDATE_PRINCIPAL_FRAGMENT_PROPERTIES_OPERATION
: TransactionedOperation.ADD_PRINCIPAL_FRAGMENT_PROPERTIES_OPERATION)));
+                    }
+                }
             }
         }
     }
@@ -2880,73 +3083,125 @@
     public void removeFragmentPropertyList(BaseFragmentElementImpl baseFragmentElementImpl,
FragmentPropertyList transientList)
     {
         // access thread local fragment property lists cache
-        String cacheKey = getFragmentPropertyListCacheKey(baseFragmentElementImpl);
+        String fragmentKey = getFragmentPropertyListFragmentKey(baseFragmentElementImpl);
+        Subject subject = JSSubject.getSubject(AccessController.getContext());
+        Principal userPrincipal = ((subject != null) ? SubjectHelper.getBestPrincipal(subject,
User.class) : null);
+        String fragmentListKey = getFragmentPropertyListKey(fragmentKey, userPrincipal);
         Map threadLocalCache = (Map)fragmentPropertyListsCache.get();
+        FragmentPropertyList list = ((threadLocalCache != null) ? (FragmentPropertyList)threadLocalCache.get(fragmentListKey)
: null);
 
         // remove cached persistent list
-        FragmentPropertyList list = ((threadLocalCache != null) ? (FragmentPropertyList)threadLocalCache.get(cacheKey)
: null);
         if (list != null)
         {
             // remove list from cache
-            threadLocalCache.remove(cacheKey);
+            threadLocalCache.remove(fragmentKey);
             // cleanup list
-            synchronized (list)
-            {
-                list.getProperties().clear();
-                List removedProperties = list.getRemovedProperties();
-                if (removedProperties != null)
-                {
-                    removedProperties.clear();
-                }
-            }
+            list.clearProperties();
         }
-        
         // cleanup transient list
         if (transientList != null)
         {
-            synchronized (transientList)
-            {
-                transientList.getProperties().clear();
-                List removedProperties = transientList.getRemovedProperties();
-                if (removedProperties != null)
-                {
-                    removedProperties.clear();
-                }
-            }
+            transientList.clearProperties();
         }
 
         // remove all fragment properties in list from database
+        Integer fragmentId = new Integer(baseFragmentElementImpl.getIdentity());
         Criteria filter = new Criteria();
-        filter.addEqualTo("fragment", new Integer(baseFragmentElementImpl.getIdentity()));
+        filter.addEqualTo("fragment", fragmentId);
         QueryByCriteria query = QueryFactory.newQuery(FragmentPropertyImpl.class, filter);
         getPersistenceBrokerTemplate().deleteByQuery(query);
         
         // interoperate with cache to signal remove operations
-        String path = baseFragmentElementImpl.getBaseFragmentsElement().getPath();
-        DatabasePageManagerCache.fragmentPropertyListCacheRemove(path);
+        DatabasePageManagerCache.fragmentPropertyListCacheRemove(fragmentKey);
+        DatabasePageManagerCache.addTransaction(new TransactionedOperation(fragmentKey, TransactionedOperation.UPDATE_FRAGMENT_PROPERTIES_OPERATION));
+    }
+    
+    /**
+     * Compute thread local fragment property list key for fragment properties.
+     * 
+     * @param fragmentKey fragment key
+     * @param userPrincipal current subject user principal
+     * @return fragment property list key string
+     */
+    private static String getFragmentPropertyListKey(String fragmentKey, Principal userPrincipal)
+    {
+        if (userPrincipal != null)
+        {
+            return fragmentKey+"/"+userPrincipal.getName();
+        }
+        return fragmentKey;
     }
     
     /**
-     * Compute thread local cache key for fragment properties.
+     * Compute fragment key for fragment properties.
      * 
      * @param baseFragmentElementImpl owner of fragment properties
-     * @return key string
+     * @return fragment key string
      */
-    private static String getFragmentPropertyListCacheKey(BaseFragmentElementImpl baseFragmentElementImpl)
+    private static String getFragmentPropertyListFragmentKey(BaseFragmentElementImpl baseFragmentElementImpl)
     {
-        // base key
-        String key = baseFragmentElementImpl.getBaseFragmentsElement().getPath()+"/"+baseFragmentElementImpl.getId();
-        // append current user if available
-        Subject subject = JSSubject.getSubject(AccessController.getContext());
-        if (subject != null)
+        return baseFragmentElementImpl.getBaseFragmentsElement().getPath()+"/"+baseFragmentElementImpl.getId()+":"+baseFragmentElementImpl.getIdentity();
+    }
+    
+    /**
+     * Compute principal key for fragment properties.
+     * 
+     * @param principalType principal type
+     * @param principalName principal name
+     * @return principal key string
+     */
+    private static String getFragmentPropertyListPrincipalKey(String principalType, String
principalName)
+    {
+        return principalType+":"+principalName;
+    }
+    
+    /**
+     * Filter principal fragment property list.
+     * 
+     * @param principalFragmentPropertyList principal fragment property list
+     * @param baseFragmentElementImpl fragment property owning fragment
+     * @return fragment property list for owning fragment
+     */
+    private static List filterPrincipalFragmentPropertyList(DatabasePageManagerCachedFragmentPropertyList
principalFragmentPropertyList, BaseFragmentElementImpl baseFragmentElementImpl)
+    {
+        List filteredList = null;
+        synchronized (principalFragmentPropertyList)
+        {
+            for (Iterator iter = principalFragmentPropertyList.iterator(); iter.hasNext();)
+            {
+                FragmentPropertyImpl fragmentProperty = (FragmentPropertyImpl)iter.next();
+                if (((BaseFragmentElementImpl)fragmentProperty.getFragment()).getIdentity()
== baseFragmentElementImpl.getIdentity())
+                {
+                    if (filteredList == null)
+                    {
+                        filteredList = new ArrayList();
+                    }
+                    filteredList.add(fragmentProperty);
+                }
+            }
+        }
+        return filteredList;
+    }
+    
+    /**
+     * Remove matching principal fragment properties from list.
+     * 
+     * @param principalFragmentPropertyList principal fragment property list
+     * @param baseFragmentElementImpl fragment property owning fragment
+     */
+    private static void removeAllPrincipalFragmentPropertyList(DatabasePageManagerCachedFragmentPropertyList
principalFragmentPropertyList, BaseFragmentElementImpl baseFragmentElementImpl)
+    {
+        synchronized (principalFragmentPropertyList)
         {
-            Principal userPrincipal = SubjectHelper.getBestPrincipal(subject, User.class);
-            if (userPrincipal != null)
+            for (Iterator iter = principalFragmentPropertyList.iterator(); iter.hasNext();)
             {
-                key = key+"/"+userPrincipal.getName();
+                FragmentPropertyImpl fragmentProperty = (FragmentPropertyImpl)iter.next();
+                if (((BaseFragmentElementImpl)fragmentProperty.getFragment()).getIdentity()
== baseFragmentElementImpl.getIdentity())
+                {
+                    iter.remove();
+                }
             }
         }
-        return key;
     }
     
     /**



---------------------------------------------------------------------
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