portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rwat...@apache.org
Subject svn commit: r1678139 [1/3] - in /portals/jetspeed-2/portal/trunk: components/jetspeed-cm/src/main/java/org/apache/jetspeed/cache/impl/ components/jetspeed-profiler/src/test/resources/ components/jetspeed-security/src/main/java/org/apache/jetspeed/secur...
Date Thu, 07 May 2015 06:48:07 GMT
Author: rwatler
Date: Thu May  7 06:48:06 2015
New Revision: 1678139

URL: http://svn.apache.org/r1678139
Log:
JS2-1324: Checkpoint commit with initial JetspeedSecurityPersistenceManager, (JSPM), cache integration.

Added:
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/cache/
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/cache/JSPMCache.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/cache/JSPMCacheImpl.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/cache/JSPMQueryCacheElement.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/cache/JSPMQueryEhCacheElementImpl.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/cache/JSPMQueryEhCacheImpl.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/spi/TestJSPMCache.java
    portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/cache/JetspeedCacheEventAdapter.java
Modified:
    portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/cache/impl/EhCacheConfigResource.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/cache/impl/EhCacheElementImpl.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/test/resources/cache-test.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/PersistentJetspeedPrincipal.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/SecurityDomainImpl.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedSecurityPersistenceManager.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/PersistentJetspeedPermissionImpl.java
    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/jetspeed-portal-resources/src/main/resources/assembly/alternate/credentials/security-spi.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/security-spi.xml
    portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/conf/jetspeed/jetspeed.properties
    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-cm/src/main/java/org/apache/jetspeed/cache/impl/EhCacheConfigResource.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/cache/impl/EhCacheConfigResource.java?rev=1678139&r1=1678138&r2=1678139&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/cache/impl/EhCacheConfigResource.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/cache/impl/EhCacheConfigResource.java Thu May  7 06:48:06 2015
@@ -16,24 +16,21 @@
  */
 package org.apache.jetspeed.cache.impl;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Map;
-import java.util.HashMap;
-
 import net.sf.ehcache.Cache;
-
+import org.apache.jetspeed.components.util.ConfigurationProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
 import org.springframework.core.io.AbstractResource;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.core.io.Resource;
-import org.springframework.beans.factory.InitializingBean;
 
-import org.apache.jetspeed.components.util.ConfigurationProperties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * EhCacheConfigResource
@@ -74,6 +71,11 @@ public class EhCacheConfigResource exten
     public static final String EHCACHE_PAGE_MANAGER_MAX_FILES_PROP_NAME = "org.apache.jetspeed.ehcache.pagemanager.maxfiles";
     public static final String EHCACHE_PAGE_MANAGER_MAX_FILES_DEFAULT = "1000";
 
+    public static final String EHCACHE_JSPM_MAX_ELEMENTS_PROP_NAME = "org.apache.jetspeed.ehcache.jspm.maxelements";
+    public static final String EHCACHE_JSPM_MAX_ELEMENTS_DEFAULT = "128";
+    public static final String EHCACHE_JSPM_ELEMENT_TTL_PROP_NAME = "org.apache.jetspeed.ehcache.jspm.element.ttl";
+    public static final String EHCACHE_JSPM_ELEMENT_TTL_DEFAULT = "150";
+
     // Class Members
     
     private static Map overrideSystemProperties;
@@ -108,7 +110,9 @@ public class EhCacheConfigResource exten
     private String defaultPageManagerMaxElements;
     private String defaultPageManagerElementTTL;
     private String defaultPageManagerMaxFiles;
-    
+    private String defaultJSPMMaxElements;
+    private String defaultJSPMElementTTL;
+
     private ClassPathResource classPathResource;
     
     // InitializingBean implementation
@@ -169,6 +173,14 @@ public class EhCacheConfigResource exten
                 {
                     defaultPageManagerMaxFiles = configuration.getString(EHCACHE_PAGE_MANAGER_MAX_FILES_PROP_NAME);
                 }
+                if (configuration.getString(EHCACHE_JSPM_MAX_ELEMENTS_PROP_NAME) != null)
+                {
+                    defaultJSPMMaxElements = configuration.getString(EHCACHE_JSPM_MAX_ELEMENTS_PROP_NAME);
+                }
+                if (configuration.getString(EHCACHE_JSPM_ELEMENT_TTL_PROP_NAME) != null)
+                {
+                    defaultJSPMElementTTL = configuration.getString(EHCACHE_JSPM_ELEMENT_TTL_PROP_NAME);
+                }
             }
 
             // save override system properties
@@ -220,6 +232,16 @@ public class EhCacheConfigResource exten
                 {
                     overrideSystemProperties.put(EHCACHE_PAGE_MANAGER_MAX_FILES_PROP_NAME, overridePageManagerMaxFiles);
                 }
+                String overrideJSPMMaxElements = System.getProperty(EHCACHE_JSPM_MAX_ELEMENTS_PROP_NAME);
+                if (overrideJSPMMaxElements != null)
+                {
+                    overrideSystemProperties.put(EHCACHE_JSPM_MAX_ELEMENTS_PROP_NAME, overrideJSPMMaxElements);
+                }
+                String overrideJSPMElementTTL = System.getProperty(EHCACHE_JSPM_ELEMENT_TTL_PROP_NAME);
+                if (overrideJSPMElementTTL != null)
+                {
+                    overrideSystemProperties.put(EHCACHE_JSPM_ELEMENT_TTL_PROP_NAME, overrideJSPMElementTTL);
+                }
             }
             
             // set system properties used in global cache configuration
@@ -288,6 +310,28 @@ public class EhCacheConfigResource exten
             }
             System.setProperty(EHCACHE_PAGE_MANAGER_MAX_FILES_PROP_NAME, setPageManagerMaxFiles);
 
+            // set system properties used in jetspeed security persistence manager cache configuration
+            String setJSPMMaxElements = (String)overrideSystemProperties.get(EHCACHE_JSPM_MAX_ELEMENTS_PROP_NAME);
+            if (setJSPMMaxElements == null)
+            {
+                setJSPMMaxElements = ((defaultJSPMMaxElements != null) ? defaultJSPMMaxElements : EHCACHE_JSPM_MAX_ELEMENTS_DEFAULT);
+                if ((setJSPMMaxElements != null) && (Integer.parseInt(setJSPMMaxElements) < 0))
+                {
+                    setJSPMMaxElements = EHCACHE_JSPM_MAX_ELEMENTS_DEFAULT;
+                }
+            }
+            System.setProperty(EHCACHE_JSPM_MAX_ELEMENTS_PROP_NAME, setJSPMMaxElements);
+            String setJSPMElementTTL = (String)overrideSystemProperties.get(EHCACHE_JSPM_ELEMENT_TTL_PROP_NAME);
+            if (setJSPMElementTTL == null)
+            {
+                setJSPMElementTTL = ((defaultJSPMElementTTL != null) ? defaultJSPMElementTTL : EHCACHE_JSPM_ELEMENT_TTL_DEFAULT);
+                if ((setJSPMElementTTL != null) && (Integer.parseInt(setJSPMElementTTL) < 0))
+                {
+                    setJSPMElementTTL = EHCACHE_JSPM_ELEMENT_TTL_DEFAULT;
+                }
+            }
+            System.setProperty(EHCACHE_JSPM_ELEMENT_TTL_PROP_NAME, setJSPMElementTTL);
+
             // setup delegate ClassPathResource
             String configResource = System.getProperty(EHCACHE_CONFIG_RESOURCE_PROP_NAME);
             log.info("Configured with resource: "+configResource);
@@ -443,4 +487,20 @@ public class EhCacheConfigResource exten
     {
         this.defaultPageManagerMaxFiles = defaultPageManagerMaxFiles;
     }
+
+    /**
+     * @param defaultJSPMMaxElements the defaultPageManagerMaxElements to set
+     */
+    public void setDefaultJSPMMaxElements(String defaultJSPMMaxElements)
+    {
+        this.defaultJSPMMaxElements = defaultJSPMMaxElements;
+    }
+
+    /**
+     * @param defaultJSPMElementTTL the defaultJSPMElementTTL to set
+     */
+    public void setDefaultJSPMElementTTL(String defaultJSPMElementTTL)
+    {
+        this.defaultJSPMElementTTL = defaultJSPMElementTTL;
+    }
 }

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/cache/impl/EhCacheElementImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/cache/impl/EhCacheElementImpl.java?rev=1678139&r1=1678138&r2=1678139&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/cache/impl/EhCacheElementImpl.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/cache/impl/EhCacheElementImpl.java Thu May  7 06:48:06 2015
@@ -23,7 +23,7 @@ import java.io.Serializable;
 
 public class EhCacheElementImpl implements CacheElement
 {
-	Element element;
+	protected Element element;
 	
 	public EhCacheElementImpl(Element element)
     {

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/test/resources/cache-test.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/test/resources/cache-test.xml?rev=1678139&r1=1678138&r2=1678139&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/test/resources/cache-test.xml (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/test/resources/cache-test.xml Thu May  7 06:48:06 2015
@@ -330,4 +330,105 @@
         <constructor-arg><ref bean="ehPageManagerPrincipalPropertiesPathCache"/></constructor-arg>
     </bean>    
     
+    <!-- Jetspeed Security Persistence Manager Caches -->
+    <bean id="ehJSPMPrincipalCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+        <meta key="j2:cat" value="default or cache"/>
+        <property name="cacheManager" ref="cacheManager"/>
+        <property name="cacheName" value="jspmPrincipalCache"/>
+    </bean>
+
+    <bean id="ehJSPMPermissionCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+        <meta key="j2:cat" value="default or cache"/>
+        <property name="cacheManager" ref="cacheManager"/>
+        <property name="cacheName" value="jspmPermissionCache"/>
+    </bean>
+
+    <bean id="ehJSPMDomainCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+        <meta key="j2:cat" value="default or cache"/>
+        <property name="cacheManager" ref="cacheManager"/>
+        <property name="cacheName" value="jspmDomainCache"/>
+    </bean>
+
+    <bean id="ehJSPMPrincipalQueryCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+        <meta key="j2:cat" value="default or cache"/>
+        <property name="cacheManager" ref="cacheManager"/>
+        <property name="cacheName" value="jspmPrincipalQueryCache"/>
+    </bean>
+
+    <bean id="ehJSPMAssociationQueryCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+        <meta key="j2:cat" value="default or cache"/>
+        <property name="cacheManager" ref="cacheManager"/>
+        <property name="cacheName" value="jspmAssociationQueryCache"/>
+    </bean>
+
+    <bean id="ehJSPMPasswordCredentialQueryCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+        <meta key="j2:cat" value="default or cache"/>
+        <property name="cacheManager" ref="cacheManager"/>
+        <property name="cacheName" value="jspmPasswordCredentialQueryCache"/>
+    </bean>
+
+    <bean id="ehJSPMPermissionQueryCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+        <meta key="j2:cat" value="default or cache"/>
+        <property name="cacheManager" ref="cacheManager"/>
+        <property name="cacheName" value="jspmPermissionQueryCache"/>
+    </bean>
+
+    <bean id="ehJSPMDomainQueryCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+        <meta key="j2:cat" value="default or cache"/>
+        <property name="cacheManager" ref="cacheManager"/>
+        <property name="cacheName" value="jspmDomainQueryCache"/>
+    </bean>
+
+    <bean id="jspmPrincipalCache" class="org.apache.jetspeed.cache.impl.EhCacheDistributedImpl">
+        <meta key="j2:cat" value="default or cache"/>
+        <constructor-arg><ref bean="ehJSPMPrincipalCache"/></constructor-arg>
+    </bean>
+
+    <bean id="jspmPermissionCache" class="org.apache.jetspeed.cache.impl.EhCacheDistributedImpl">
+        <meta key="j2:cat" value="default or cache"/>
+        <constructor-arg><ref bean="ehJSPMPermissionCache"/></constructor-arg>
+    </bean>
+
+    <bean id="jspmDomainCache" class="org.apache.jetspeed.cache.impl.EhCacheDistributedImpl">
+        <meta key="j2:cat" value="default or cache"/>
+        <constructor-arg><ref bean="ehJSPMDomainCache"/></constructor-arg>
+    </bean>
+
+    <bean id="jspmPrincipalQueryCache" class="org.apache.jetspeed.security.spi.impl.cache.JSPMQueryEhCacheImpl">
+        <meta key="j2:cat" value="default or cache"/>
+        <constructor-arg><ref bean="ehJSPMPrincipalQueryCache"/></constructor-arg>
+    </bean>
+    
+    <bean id="jspmAssociationQueryCache" class="org.apache.jetspeed.security.spi.impl.cache.JSPMQueryEhCacheImpl">
+        <meta key="j2:cat" value="default or cache"/>
+        <constructor-arg><ref bean="ehJSPMAssociationQueryCache"/></constructor-arg>
+    </bean>
+
+    <bean id="jspmPasswordCredentialQueryCache" class="org.apache.jetspeed.security.spi.impl.cache.JSPMQueryEhCacheImpl">
+        <meta key="j2:cat" value="default or cache"/>
+        <constructor-arg><ref bean="ehJSPMPasswordCredentialQueryCache"/></constructor-arg>
+    </bean>
+
+    <bean id="jspmPermissionQueryCache" class="org.apache.jetspeed.security.spi.impl.cache.JSPMQueryEhCacheImpl">
+        <meta key="j2:cat" value="default or cache"/>
+        <constructor-arg><ref bean="ehJSPMPermissionQueryCache"/></constructor-arg>
+    </bean>
+
+    <bean id="jspmDomainQueryCache" class="org.apache.jetspeed.security.spi.impl.cache.JSPMQueryEhCacheImpl">
+        <meta key="j2:cat" value="default or cache"/>
+        <constructor-arg><ref bean="ehJSPMDomainQueryCache"/></constructor-arg>
+    </bean>
+
+    <bean id="org.apache.jetspeed.security.spi.impl.cache.JSPMCache" class="org.apache.jetspeed.security.spi.impl.cache.JSPMCacheImpl"
+          init-method="initialize" destroy-method="terminate">
+        <meta key="j2:cat" value="default or cache"/>
+        <constructor-arg><ref bean="jspmPrincipalCache"/></constructor-arg>
+        <constructor-arg><ref bean="jspmPermissionCache"/></constructor-arg>
+        <constructor-arg><ref bean="jspmDomainCache"/></constructor-arg>
+        <constructor-arg><ref bean="jspmPrincipalQueryCache"/></constructor-arg>
+        <constructor-arg><ref bean="jspmAssociationQueryCache"/></constructor-arg>
+        <constructor-arg><ref bean="jspmPasswordCredentialQueryCache"/></constructor-arg>
+        <constructor-arg><ref bean="jspmPermissionQueryCache"/></constructor-arg>
+        <constructor-arg><ref bean="jspmDomainQueryCache"/></constructor-arg>
+    </bean>
 </beans>

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/PersistentJetspeedPrincipal.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/PersistentJetspeedPrincipal.java?rev=1678139&r1=1678138&r2=1678139&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/PersistentJetspeedPrincipal.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/PersistentJetspeedPrincipal.java Thu May  7 06:48:06 2015
@@ -17,12 +17,7 @@
 
 package org.apache.jetspeed.security.impl;
 
-import java.io.Serializable;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-
+import org.apache.jetspeed.cache.DistributedCacheObject;
 import org.apache.jetspeed.security.SecurityAttributes;
 import org.apache.jetspeed.security.SecurityException;
 import org.apache.jetspeed.security.spi.impl.SynchronizationStateAccess;
@@ -30,11 +25,17 @@ import org.apache.ojb.broker.Persistence
 import org.apache.ojb.broker.PersistenceBrokerAware;
 import org.apache.ojb.broker.PersistenceBrokerException;
 
+import java.io.Serializable;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
 /**
  * @version $Id$
  *
  */
-public abstract class PersistentJetspeedPrincipal extends TransientJetspeedPrincipal implements PersistenceBrokerAware, Serializable
+public abstract class PersistentJetspeedPrincipal extends TransientJetspeedPrincipal implements PersistenceBrokerAware, DistributedCacheObject, Serializable
 {
     private Long id;
     private Timestamp creationDate;
@@ -193,4 +194,8 @@ public abstract class PersistentJetspeed
         return SynchronizationStateAccess.isSynchronizing();
     }
 
+    @Override
+    public void notifyChange(int action)
+    {
+    }
 }

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/SecurityDomainImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/SecurityDomainImpl.java?rev=1678139&r1=1678138&r2=1678139&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/SecurityDomainImpl.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/SecurityDomainImpl.java Thu May  7 06:48:06 2015
@@ -16,6 +16,7 @@
  */
 package org.apache.jetspeed.security.impl;
 
+import org.apache.jetspeed.cache.DistributedCacheObject;
 import org.apache.jetspeed.security.SecurityDomain;
 
 
@@ -23,7 +24,7 @@ import org.apache.jetspeed.security.Secu
  * @author <a href="mailto:ddam@apache.org">Dennis Dam</a>
  * @version $Id$
  */
-public class SecurityDomainImpl implements SecurityDomain
+public class SecurityDomainImpl implements SecurityDomain, DistributedCacheObject
 {
 
     private Long domainId;
@@ -97,5 +98,9 @@ public class SecurityDomainImpl implemen
     {
         this.enabled = enabled;
     }
-    
+
+    @Override
+    public void notifyChange(int action)
+    {
+    }
 }

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedSecurityPersistenceManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedSecurityPersistenceManager.java?rev=1678139&r1=1678138&r2=1678139&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedSecurityPersistenceManager.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedSecurityPersistenceManager.java Thu May  7 06:48:06 2015
@@ -16,15 +16,6 @@
  */
 package org.apache.jetspeed.security.spi.impl;
 
-import java.io.Serializable;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
 import org.apache.jetspeed.components.dao.InitablePersistenceBrokerDaoSupport;
 import org.apache.jetspeed.i18n.KeyedMessage;
 import org.apache.jetspeed.security.JetspeedPermission;
@@ -52,6 +43,7 @@ import org.apache.jetspeed.security.spi.
 import org.apache.jetspeed.security.spi.SecurityDomainStorageManager;
 import org.apache.jetspeed.security.spi.UserPasswordCredentialAccessManager;
 import org.apache.jetspeed.security.spi.UserPasswordCredentialStorageManager;
+import org.apache.jetspeed.security.spi.impl.cache.JSPMCache;
 import org.apache.ojb.broker.PersistenceBroker;
 import org.apache.ojb.broker.PersistenceBrokerException;
 import org.apache.ojb.broker.accesslayer.LookupException;
@@ -67,6 +59,15 @@ import org.springframework.dao.DataInteg
 import org.springframework.orm.ObjectRetrievalFailureException;
 import org.springframework.orm.ojb.PersistenceBrokerCallback;
 
+import java.io.Serializable;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
 /**
  * @version $Id$
  */
@@ -84,6 +85,8 @@ public class JetspeedSecurityPersistence
     private Long defaultSecurityDomainId;
     
     private JetspeedPrincipalLookupManagerFactory jpplf = null;
+
+    private JSPMCache jspmCache = null;
     
     protected static class ManagedListByQueryCallback implements PersistenceBrokerCallback
     {
@@ -100,28 +103,47 @@ public class JetspeedSecurityPersistence
         }
     }
     
-	public JetspeedSecurityPersistenceManager(String repositoryPath, JetspeedPrincipalLookupManagerFactory lookupManagerFactory)
+	public JetspeedSecurityPersistenceManager(String repositoryPath, JetspeedPrincipalLookupManagerFactory lookupManagerFactory, JSPMCache jspmCache)
     {
         super(repositoryPath);
         this.jpplf = lookupManagerFactory;
-        
+        this.jspmCache = jspmCache;
     }
     
     @SuppressWarnings("unchecked")
-    protected Long getPrincipalId(String name, String type, Long domainId) throws SecurityException
+    public Long getPrincipalId(String name, String type, Long domainId) throws SecurityException
     {
         Criteria criteria = new Criteria();
         criteria.addEqualTo("name", name);
         criteria.addEqualTo("type", type);
         criteria.addEqualTo("domainId", domainId);
+        // check cache
+        String cacheKey = "getPrincipalId:"+criteria;
+        Object principalId = jspmCache.getPrincipalQuery(cacheKey);
+        if (principalId != null)
+        {
+            if (principalId != JSPMCache.CACHE_NULL)
+            {
+                return (Long)principalId;
+            }
+            throw new SecurityException(SecurityException.PRINCIPAL_DOES_NOT_EXIST.createScoped(type, name));
+        }
+        // perform query
         ReportQueryByCriteria query = QueryFactory.newReportQuery(PersistentJetspeedPrincipal.class, criteria);
         query.setAttributes(new String[]{"id"});
         // need to force OJB to return a Long, otherwise it'll return a Integer causing a CCE
         query.setJdbcTypes(new int[]{Types.BIGINT});
         for (Iterator<Object[]> iter = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query); iter.hasNext(); )
         {
-            return (Long)iter.next()[0];
-        }
+            principalId = iter.next()[0];
+            // put result in cache
+            jspmCache.putPrincipalQuery(cacheKey, (Long)principalId, null, domainId, principalId);
+            // return result
+            return (Long)principalId;
+        }
+        // put null result in cache
+        jspmCache.putPrincipalQuery(cacheKey, JSPMCache.ANY_ID, null, domainId, JSPMCache.CACHE_NULL);
+        // throw result
         throw new SecurityException(SecurityException.PRINCIPAL_DOES_NOT_EXIST.createScoped(type, name));
     }
     
@@ -129,19 +151,33 @@ public class JetspeedSecurityPersistence
     {
         if (principal.getId() == null)
         {
-            if (principal.getDomainId() != null){
+            if (principal.getDomainId() != null)
+            {
                 return principalExists(principal.getName(), principal.getType(), principal.getDomainId());    
-            } else {
+            }
+            else
+            {
                 return principalExists(principal.getName(), principal.getType());
             }
-            
         }
         Criteria criteria = new Criteria();
         criteria.addEqualTo("id", principal.getId());
         criteria.addEqualTo("type", principal.getType().getName());
         criteria.addEqualTo("domainId", principal.getDomainId());
+        // check cache
+        String cacheKey = "principalExists:"+criteria;
+        Boolean principalExists = (Boolean)jspmCache.getPrincipalQuery(cacheKey);
+        if (principalExists != null)
+        {
+            return principalExists;
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PersistentJetspeedPrincipal.class,criteria);
-        return getPersistenceBrokerTemplate().getCount(query) == 1;
+        principalExists = (getPersistenceBrokerTemplate().getCount(query) == 1);
+        // put result in cache
+        jspmCache.putPrincipalQuery(cacheKey, (principalExists ? principal.getId() : JSPMCache.ANY_ID), null, principal.getDomainId(), principalExists);
+        // return result
+        return principalExists;
     }
 
 	public List<JetspeedPrincipal> getAssociatedFrom(String principalFromName, JetspeedPrincipalType from, JetspeedPrincipalType to, String associationName){
@@ -161,8 +197,27 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("type", to.getName());
         criteria.addEqualTo("associationsTo.from.domainId", fromSecurityDomain);
         criteria.addEqualTo("domainId", toSecurityDomain);
+        // check cache
+        String cacheKey = "getAssociatedFrom:"+criteria;
+        List<JetspeedPrincipal> associatedFrom = (List<JetspeedPrincipal>)jspmCache.getAssociationQuery(cacheKey);
+        if (associatedFrom != null)
+        {
+            return new ArrayList<JetspeedPrincipal>(associatedFrom);
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PersistentJetspeedPrincipal.class, criteria);
-        return (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        associatedFrom = (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        try
+        {
+            Long principalFromId = getPrincipalId(principalFromName, from.getName(), fromSecurityDomain);
+            jspmCache.putAssociationQuery(cacheKey, principalFromId, extractPrincipalIds(associatedFrom), fromSecurityDomain, toSecurityDomain, new ArrayList<JetspeedPrincipal>(associatedFrom));
+        }
+        catch (SecurityException se)
+        {
+        }
+        // return result
+        return associatedFrom;
     }
 
     public List<JetspeedPrincipal> getAssociatedTo(String principalToName, JetspeedPrincipalType from, JetspeedPrincipalType to, String associationName){
@@ -180,8 +235,27 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("associationsFrom.to.type", to.getName());
         criteria.addEqualTo("associationsFrom.to.domainId", toSecurityDomain);
         criteria.addEqualTo("domainId", fromSecurityDomain);
+        // check cache
+        String cacheKey = "getAssociatedTo:"+criteria;
+        List<JetspeedPrincipal> associatedTo = (List<JetspeedPrincipal>)jspmCache.getAssociationQuery(cacheKey);
+        if (associatedTo != null)
+        {
+            return new ArrayList<JetspeedPrincipal>(associatedTo);
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PersistentJetspeedPrincipal.class, criteria);
-        return (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        associatedTo = (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        try
+        {
+            Long principalToId = getPrincipalId(principalToName, to.getName(), toSecurityDomain);
+            jspmCache.putAssociationQuery(cacheKey, principalToId, extractPrincipalIds(associatedTo), fromSecurityDomain, toSecurityDomain, new ArrayList<JetspeedPrincipal>(associatedTo));
+        }
+        catch (SecurityException se)
+        {
+        }
+        // return result
+        return associatedTo;
     }
 
     public List<JetspeedPrincipal> getAssociatedFrom(Long principalFromId, JetspeedPrincipalType from, JetspeedPrincipalType to, String associationName){
@@ -199,8 +273,20 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("type", to.getName());
         criteria.addEqualTo("associationsTo.from.domainId", fromSecurityDomain);
         criteria.addEqualTo("domainId", toSecurityDomain);
+        // check cache
+        String cacheKey = "getAssociatedFrom:"+criteria;
+        List<JetspeedPrincipal> associatedFrom = (List<JetspeedPrincipal>)jspmCache.getAssociationQuery(cacheKey);
+        if (associatedFrom != null)
+        {
+            return new ArrayList<JetspeedPrincipal>(associatedFrom);
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PersistentJetspeedPrincipal.class, criteria);
-        return (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        associatedFrom = (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        jspmCache.putAssociationQuery(cacheKey, principalFromId, extractPrincipalIds(associatedFrom), fromSecurityDomain, toSecurityDomain, new ArrayList<JetspeedPrincipal>(associatedFrom));
+        // return result
+        return associatedFrom;
     }
 
     public List<JetspeedPrincipal> getAssociatedTo(Long principalToId, JetspeedPrincipalType from, JetspeedPrincipalType to, String associationName){
@@ -218,8 +304,40 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("associationsFrom.to.type", to.getName());
         criteria.addEqualTo("associationsFrom.to.domainId", toSecurityDomain);
         criteria.addEqualTo("domainId", fromSecurityDomain);
+        // check cache
+        String cacheKey = "getAssociatedTo:"+criteria;
+        List<JetspeedPrincipal> associatedTo = (List<JetspeedPrincipal>)jspmCache.getAssociationQuery(cacheKey);
+        if (associatedTo != null)
+        {
+            return new ArrayList<JetspeedPrincipal>(associatedTo);
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PersistentJetspeedPrincipal.class, criteria);
-        return (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        associatedTo = (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        jspmCache.putAssociationQuery(cacheKey, principalToId, extractPrincipalIds(associatedTo), fromSecurityDomain, toSecurityDomain, new ArrayList<JetspeedPrincipal>(associatedTo));
+        // return result
+        return associatedTo;
+    }
+
+    /**
+     * Extract principal ids from principals.
+     *
+     * @param principals list of principals
+     * @return array of principal ids
+     */
+    private Long [] extractPrincipalIds(List<JetspeedPrincipal> principals)
+    {
+        if ((principals == null) || principals.isEmpty())
+        {
+            return null;
+        }
+        List<Long> principalIds = new ArrayList<Long>(principals.size());
+        for (JetspeedPrincipal principal : principals)
+        {
+            principalIds.add(principal.getId());
+        }
+        return principalIds.toArray(new Long[principalIds.size()]);
     }
 
     public List<String> getAssociatedNamesFrom(String principalFromName, JetspeedPrincipalType from, JetspeedPrincipalType to, String associationName){
@@ -237,14 +355,35 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("type", to.getName());
         criteria.addEqualTo("associationsTo.from.domainId", fromSecurityDomain);
         criteria.addEqualTo("domainId", toSecurityDomain);
+        // check cache
+        String cacheKey = "getAssociatedNamesFrom:"+criteria;
+        List<String> associatedNamesFrom = (List<String>)jspmCache.getAssociationQuery(cacheKey);
+        if (associatedNamesFrom != null)
+        {
+            return new ArrayList<String>(associatedNamesFrom);
+        }
+        // perform query
         ReportQueryByCriteria query = QueryFactory.newReportQuery(PersistentJetspeedPrincipal.class, criteria);
-        query.setAttributes(new String[]{"name"});
-        ArrayList<String> names = new ArrayList<String>();
+        query.setAttributes(new String[]{"name", "id"});
+        associatedNamesFrom = new ArrayList<String>();
+        List<Long> associatedIdsFrom = new ArrayList<Long>();
         for (Iterator<Object[]> iter = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query); iter.hasNext(); )
         {
-            names.add((String)iter.next()[0]);
+            Object[] associatedFrom = iter.next();
+            associatedNamesFrom.add((String) associatedFrom[0]);
+            associatedIdsFrom.add(((Integer) associatedFrom[1]).longValue());
         }
-        return names;
+        // put result in cache
+        try
+        {
+            Long principalFromId = getPrincipalId(principalFromName, from.getName(), fromSecurityDomain);
+            jspmCache.putAssociationQuery(cacheKey, principalFromId, associatedIdsFrom.toArray(new Long[associatedIdsFrom.size()]), fromSecurityDomain, toSecurityDomain, new ArrayList<String>(associatedNamesFrom));
+        }
+        catch (SecurityException se)
+        {
+        }
+        // return result
+        return associatedNamesFrom;
     }
 
     public List<String> getAssociatedNamesFrom(Long principalFromId, JetspeedPrincipalType from, JetspeedPrincipalType to, String associationName){
@@ -262,14 +401,28 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("type", to.getName());
         criteria.addEqualTo("associationsTo.from.domainId", fromSecurityDomain);
         criteria.addEqualTo("domainId", toSecurityDomain);
+        // check cache
+        String cacheKey = "getAssociatedNamesFrom:"+criteria;
+        List<String> associatedNamesFrom = (List<String>)jspmCache.getAssociationQuery(cacheKey);
+        if (associatedNamesFrom != null)
+        {
+            return new ArrayList<String>(associatedNamesFrom);
+        }
+        // perform query
         ReportQueryByCriteria query = QueryFactory.newReportQuery(PersistentJetspeedPrincipal.class, criteria);
-        query.setAttributes(new String[]{"name"});
-        ArrayList<String> names = new ArrayList<String>();
+        query.setAttributes(new String[]{"name", "id"});
+        associatedNamesFrom = new ArrayList<String>();
+        List<Long> associatedIdsFrom = new ArrayList<Long>();
         for (Iterator<Object[]> iter = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query); iter.hasNext(); )
         {
-            names.add((String)iter.next()[0]);
-        }
-        return names;
+            Object[] associatedFrom = iter.next();
+            associatedNamesFrom.add((String) associatedFrom[0]);
+            associatedIdsFrom.add(((Integer) associatedFrom[1]).longValue());
+        }
+        // put result in cache
+        jspmCache.putAssociationQuery(cacheKey, principalFromId, associatedIdsFrom.toArray(new Long[associatedIdsFrom.size()]), fromSecurityDomain, toSecurityDomain, new ArrayList<String>(associatedNamesFrom));
+        // return result
+        return associatedNamesFrom;
     }
 
     public List<String> getAssociatedNamesTo(String principalToName, JetspeedPrincipalType from, JetspeedPrincipalType to, String associationName){
@@ -287,14 +440,35 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("associationsFrom.to.type", to.getName());
         criteria.addEqualTo("associationsFrom.to.domainId", toSecurityDomain);
         criteria.addEqualTo("domainId", fromSecurityDomain);
+        // check cache
+        String cacheKey = "getAssociatedNamesTo:"+criteria;
+        List<String> associatedNamesTo = (List<String>)jspmCache.getAssociationQuery(cacheKey);
+        if (associatedNamesTo != null)
+        {
+            return new ArrayList<String>(associatedNamesTo);
+        }
+        // perform query
         ReportQueryByCriteria query = QueryFactory.newReportQuery(PersistentJetspeedPrincipal.class, criteria);
-        query.setAttributes(new String[]{"name"});
-        ArrayList<String> names = new ArrayList<String>();
+        query.setAttributes(new String[]{"name", "id"});
+        associatedNamesTo = new ArrayList<String>();
+        List<Long> associatedIdsTo = new ArrayList<Long>();
         for (Iterator<Object[]> iter = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query); iter.hasNext(); )
         {
-            names.add((String)iter.next()[0]);
+            Object[] associatedTo = iter.next();
+            associatedNamesTo.add((String) associatedTo[0]);
+            associatedIdsTo.add(((Integer) associatedTo[1]).longValue());
+        }
+        // put result in cache
+        try
+        {
+            Long principalToId = getPrincipalId(principalToName, from.getName(), fromSecurityDomain);
+            jspmCache.putAssociationQuery(cacheKey, principalToId, associatedIdsTo.toArray(new Long[associatedIdsTo.size()]), fromSecurityDomain, toSecurityDomain, new ArrayList<String>(associatedNamesTo));
+        }
+        catch (SecurityException se)
+        {
         }
-        return names;
+        // return result
+        return associatedNamesTo;
     }
 
     public List<String> getAssociatedNamesTo(Long principalToId, JetspeedPrincipalType from, JetspeedPrincipalType to, String associationName){
@@ -312,19 +486,50 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("associationsFrom.to.type", to.getName());
         criteria.addEqualTo("associationsFrom.to.domainId", toSecurityDomain);
         criteria.addEqualTo("domainId", fromSecurityDomain);
+        // check cache
+        String cacheKey = "getAssociatedNamesTo:"+criteria;
+        List<String> associatedNamesTo = (List<String>)jspmCache.getAssociationQuery(cacheKey);
+        if (associatedNamesTo != null)
+        {
+            return new ArrayList<String>(associatedNamesTo);
+        }
+        // perform query
         ReportQueryByCriteria query = QueryFactory.newReportQuery(PersistentJetspeedPrincipal.class, criteria);
-        query.setAttributes(new String[]{"name"});
-        ArrayList<String> names = new ArrayList<String>();
+        query.setAttributes(new String[]{"name", "id"});
+        associatedNamesTo = new ArrayList<String>();
+        List<Long> associatedIdsTo = new ArrayList<Long>();
         for (Iterator<Object[]> iter = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query); iter.hasNext(); )
         {
-            names.add((String)iter.next()[0]);
-        }
-        return names;
+            Object[] associatedTo = iter.next();
+            associatedNamesTo.add((String) associatedTo[0]);
+            associatedIdsTo.add(((Integer) associatedTo[1]).longValue());
+        }
+        // put result in cache
+        jspmCache.putAssociationQuery(cacheKey, principalToId, associatedIdsTo.toArray(new Long[associatedIdsTo.size()]), fromSecurityDomain, toSecurityDomain, new ArrayList<String>(associatedNamesTo));
+        // return result
+        return associatedNamesTo;
     }
 
     public JetspeedPrincipal getPrincipal(Long id)
-    {        
-        return (JetspeedPrincipal)getPersistenceBrokerTemplate().getObjectById(PersistentJetspeedPrincipal.class, id);
+    {
+        // check cache
+        Object principal = jspmCache.getPrincipal(id);
+        if (principal != null)
+        {
+            return ((principal != JSPMCache.CACHE_NULL) ? (JetspeedPrincipal) principal : null);
+        }
+        // perform query
+        try
+        {
+            principal = getPersistenceBrokerTemplate().getObjectById(PersistentJetspeedPrincipal.class, id);
+        }
+        catch (ObjectRetrievalFailureException orfe)
+        {
+        }
+        // put result in cache
+        jspmCache.putPrincipal(id, ((principal != null) ? principal : JSPMCache.CACHE_NULL));
+        // return result
+        return (JetspeedPrincipal) principal;
     }
 
     public JetspeedPrincipal getPrincipal(String principalName, JetspeedPrincipalType type)
@@ -338,8 +543,27 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("name", principalName);
         criteria.addEqualTo("type", type.getName());
         criteria.addEqualTo("domainId", securityDomain);
+        // check cache
+        String cacheKey = "getPrincipal:"+criteria;
+        Object principal = jspmCache.getPrincipalQuery(cacheKey);
+        if (principal != null)
+        {
+            return ((principal != JSPMCache.CACHE_NULL) ? (JetspeedPrincipal) principal : null);
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PersistentJetspeedPrincipal.class,criteria);
-        return (JetspeedPrincipal)getPersistenceBrokerTemplate().getObjectByQuery(query);
+        principal = getPersistenceBrokerTemplate().getObjectByQuery(query);
+        // put result in cache
+        if (principal != null)
+        {
+            jspmCache.putPrincipalQuery(cacheKey, ((JetspeedPrincipal)principal).getId(), null, securityDomain, principal);
+        }
+        else
+        {
+            jspmCache.putPrincipalQuery(cacheKey, JSPMCache.ANY_ID, null, securityDomain, JSPMCache.CACHE_NULL);
+        }
+        // return result
+        return (JetspeedPrincipal) principal;
     }
 
     public List<String> getPrincipalNames(String nameFilter, JetspeedPrincipalType type)
@@ -357,14 +581,25 @@ public class JetspeedSecurityPersistence
         }
         criteria.addEqualTo("type", type.getName());
         criteria.addEqualTo("domainId", securityDomain);
+        // check cache
+        String cacheKey = "getPrincipalNames:"+criteria;
+        List<String> principalNames = (List<String>)jspmCache.getPrincipalQuery(cacheKey);
+        if (principalNames != null)
+        {
+            return new ArrayList<String>(principalNames);
+        }
+        // perform query
         ReportQueryByCriteria query = QueryFactory.newReportQuery(PersistentJetspeedPrincipal.class,criteria);
         query.setAttributes(new String[]{"name"});
-        ArrayList<String> names = new ArrayList<String>();
+        principalNames = new ArrayList<String>();
         for (Iterator<Object[]> iter = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query); iter.hasNext(); )
         {
-            names.add((String)iter.next()[0]);
+            principalNames.add((String) iter.next()[0]);
         }
-        return names;
+        // put result in cache
+        jspmCache.putPrincipalQuery(cacheKey, JSPMCache.ANY_ID, null, securityDomain, new ArrayList<String>(principalNames));
+        // return result
+        return principalNames;
     }
 
     public List<JetspeedPrincipal> getPrincipals(String nameFilter, JetspeedPrincipalType type)
@@ -382,8 +617,20 @@ public class JetspeedSecurityPersistence
         }
         criteria.addEqualTo("type", type.getName());
         criteria.addEqualTo("domainId", securityDomain);
+        // check cache
+        String cacheKey = "getPrincipals:"+criteria;
+        List<JetspeedPrincipal> principals = (List<JetspeedPrincipal>)jspmCache.getPrincipalQuery(cacheKey);
+        if (principals != null)
+        {
+            return new ArrayList<JetspeedPrincipal>(principals);
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PersistentJetspeedPrincipal.class,criteria);
-        return (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        principals = (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        jspmCache.putPrincipalQuery(cacheKey, JSPMCache.ANY_ID, null, securityDomain, new ArrayList<JetspeedPrincipal>(principals));
+        // return result
+        return principals;
     }
 
     public List<JetspeedPrincipal> getPrincipalsByAttribute(String attributeName, String attributeValue, JetspeedPrincipalType type)
@@ -399,8 +646,20 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("attributes.value", attributeValue);
         criteria.addEqualTo("type", type.getName());
         criteria.addEqualTo("domainId", securityDomain);
+        // check cache
+        String cacheKey = "getPrincipalsByAttribute:"+criteria;
+        List<JetspeedPrincipal> principals = (List<JetspeedPrincipal>)jspmCache.getPrincipalQuery(cacheKey);
+        if (principals != null)
+        {
+            return new ArrayList<JetspeedPrincipal>(principals);
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PersistentJetspeedPrincipal.class,criteria);
-        return (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        principals = (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        jspmCache.putPrincipalQuery(cacheKey, JSPMCache.ANY_ID, null, securityDomain, new ArrayList<JetspeedPrincipal>(principals));
+        // return result
+        return principals;
     }
 
     public boolean principalExists(String principalName, JetspeedPrincipalType type)
@@ -414,8 +673,34 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("name", principalName);
         criteria.addEqualTo("type", type.getName());
         criteria.addEqualTo("domainId", securityDomain);
+        // check cache
+        String cacheKey = "principalExists:"+criteria;
+        Boolean principalExists = (Boolean)jspmCache.getPrincipalQuery(cacheKey);
+        if (principalExists != null)
+        {
+            return principalExists;
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PersistentJetspeedPrincipal.class,criteria);
-        return getPersistenceBrokerTemplate().getCount(query) == 1;
+        principalExists = (getPersistenceBrokerTemplate().getCount(query) == 1);
+        // put result in cache
+        if (principalExists)
+        {
+            try
+            {
+                Long principalId = getPrincipalId(principalName, type.getName(), securityDomain);
+                jspmCache.putPrincipalQuery(cacheKey, principalId, null, securityDomain, principalExists);
+            }
+            catch (SecurityException se)
+            {
+            }
+        }
+        else
+        {
+            jspmCache.putPrincipalQuery(cacheKey, JSPMCache.ANY_ID, null, securityDomain, principalExists);
+        }
+        // return result
+        return principalExists;
     }
 
     //
@@ -424,7 +709,8 @@ public class JetspeedSecurityPersistence
     public void addPrincipal(JetspeedPrincipal principal, Set<JetspeedPrincipalAssociationReference> associations)
         throws SecurityException
     {
-        if (principal.getDomainId() == null && principal instanceof TransientJetspeedPrincipal){
+        if (principal.getDomainId() == null && principal instanceof TransientJetspeedPrincipal)
+        {
             ((TransientJetspeedPrincipal)principal).setDomainId(getDefaultSecurityDomainId());
         }
         if (principalExists(principal))
@@ -434,6 +720,9 @@ public class JetspeedSecurityPersistence
         try
         {
             getPersistenceBrokerTemplate().store(principal);
+            // evict from and put in cache to notify
+            jspmCache.evictPrincipal(principal.getId());
+            jspmCache.putPrincipal(principal.getId(), principal);
         }
         catch (Exception pbe)
         {
@@ -452,7 +741,6 @@ public class JetspeedSecurityPersistence
     }
 
     public void removePrincipal(JetspeedPrincipal principal) throws SecurityException
-    
     {
         if (!principalExists(principal))
         {
@@ -461,6 +749,8 @@ public class JetspeedSecurityPersistence
         try
         {
             getPersistenceBrokerTemplate().delete(principal);
+            // evict from cache to notify
+            jspmCache.evictPrincipal(principal.getId());
         }
         catch (Exception pbe)
         {
@@ -479,7 +769,6 @@ public class JetspeedSecurityPersistence
     }
 
     public void updatePrincipal(JetspeedPrincipal principal) throws SecurityException
-                                                            
     {
         if (!principalExists(principal))
         {
@@ -488,6 +777,9 @@ public class JetspeedSecurityPersistence
         try
         {
             getPersistenceBrokerTemplate().store(principal);
+            // evict from and put in cache to notify
+            jspmCache.evictPrincipal(principal.getId());
+            jspmCache.putPrincipal(principal.getId(), principal);
         }
         catch (Exception pbe)
         {
@@ -513,19 +805,41 @@ public class JetspeedSecurityPersistence
         Criteria criteria = new Criteria();
         criteria.addEqualTo("principalId", user.getId());
         criteria.addEqualTo("type", PasswordCredential.TYPE_CURRENT);
+        // check cache
+        String cacheKey = "getPasswordCredential:"+criteria;
+        PasswordCredential passwordCredential = (PasswordCredential) jspmCache.getPasswordCredentialQuery(cacheKey);
+        if (passwordCredential != null)
+        {
+            return passwordCredential;
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PasswordCredentialImpl.class,criteria);
-        PasswordCredentialImpl pwc = (PasswordCredentialImpl)getPersistenceBrokerTemplate().getObjectByQuery(query);
-        if (pwc == null)
+        passwordCredential = (PasswordCredential) getPersistenceBrokerTemplate().getObjectByQuery(query);
+        if (passwordCredential != null)
         {
-            pwc = new PasswordCredentialImpl();
+            // store the user by hand as its configured as auto-retrieve="false"
+            ((PasswordCredentialImpl)passwordCredential).setUser(user);
+        }
+        // put result in cache
+        if (passwordCredential != null)
+        {
+            jspmCache.putPasswordCredentialQuery(cacheKey, user.getId(), user.getDomainId(), passwordCredential);
+        }
+        // return result
+        if (passwordCredential == null)
+        {
+            passwordCredential = new PasswordCredentialImpl();
+            // store the user by hand as its configured as auto-retrieve="false"
+            ((PasswordCredentialImpl)passwordCredential).setUser(user);
         }
-        // store the user by hand as its configured as auto-retrieve="false"
-        pwc.setUser(user);
-        return pwc;
+        return passwordCredential;
     }
 
     public void storePasswordCredential(PasswordCredential credential) throws SecurityException
     {
+        if (credential.getUser() == null) {
+            loadPasswordCredentialUser(credential);
+        }
         if (credential.isNewPasswordSet())
         {
             if (credential.getNewPassword() != null)
@@ -534,11 +848,14 @@ public class JetspeedSecurityPersistence
             }
         }
         getPersistenceBrokerTemplate().store(credential);
+        // evict user principal from cache to notify
+        jspmCache.evictPrincipal(credential.getUser().getId());
     }
 
     public PasswordCredential getPasswordCredential(String userName){
         return getPasswordCredential(userName,getDefaultSecurityDomainId());
     }
+
     //
     // UserPasswordCredentialAccessManager interface implementation
     //
@@ -560,14 +877,39 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("user.enabled",true);
         criteria.addEqualTo("type", PasswordCredential.TYPE_CURRENT);
         criteria.addEqualTo("domainId", securityDomain);
+        // check cache
+        String cacheKey = "getPasswordCredential:"+criteria;
+        Object passwordCredential = jspmCache.getPasswordCredentialQuery(cacheKey);
+        if (passwordCredential != null)
+        {
+            return ((passwordCredential != JSPMCache.CACHE_NULL) ? (PasswordCredential) passwordCredential : null);
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PasswordCredentialImpl.class,criteria);
-        PasswordCredentialImpl pwc = (PasswordCredentialImpl)getPersistenceBrokerTemplate().getObjectByQuery(query);
-        if (pwc != null)
+        passwordCredential = (PasswordCredential) getPersistenceBrokerTemplate().getObjectByQuery(query);
+        if (passwordCredential != null)
         {
             // store the userName by hand as the user is configured as auto-retrieve="false"
-            pwc.setUserName(userName);
+            ((PasswordCredentialImpl)passwordCredential).setUserName(userName);
         }
-        return pwc;
+        // put result in cache
+        if (passwordCredential != null)
+        {
+            try
+            {
+                Long principalId = getPrincipalId(userName, JetspeedPrincipalType.USER ,securityDomain);
+                jspmCache.putPasswordCredentialQuery(cacheKey, principalId, securityDomain, passwordCredential);
+            }
+            catch (SecurityException se)
+            {
+            }
+        }
+        else
+        {
+            jspmCache.putPasswordCredentialQuery(cacheKey, JSPMCache.ANY_ID, securityDomain, JSPMCache.CACHE_NULL);
+        }
+        // return result
+        return (PasswordCredential) passwordCredential;
     }
     
     public void loadPasswordCredentialUser(final PasswordCredential credential)
@@ -597,14 +939,25 @@ public class JetspeedSecurityPersistence
         Criteria criteria = new Criteria();
         criteria.addEqualTo("principalId", user.getId());
         criteria.addEqualTo("type", PasswordCredential.TYPE_HISTORICAL);
+        // check cache
+        String cacheKey = "getHistoricPasswordCredentials:"+criteria;
+        List<PasswordCredential> passwordCredentials = (List<PasswordCredential>) jspmCache.getPasswordCredentialQuery(cacheKey);
+        if (passwordCredentials != null)
+        {
+            return new ArrayList<PasswordCredential>(passwordCredentials);
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PasswordCredentialImpl.class,criteria);
-        List<PasswordCredential> list = (List<PasswordCredential>)getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
-        for (PasswordCredential pwc : list)
+        passwordCredentials = (List<PasswordCredential>)getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        for (PasswordCredential passwordCredential : passwordCredentials)
         {
             // store the user by hand as its configured as auto-retrieve="false"
-            ((PasswordCredentialImpl)pwc).setUser(user);
+            ((PasswordCredentialImpl)passwordCredential).setUser(user);
         }
-        return list;
+        // put result in cache
+        jspmCache.putPasswordCredentialQuery(cacheKey, user.getId(), user.getDomainId(), new ArrayList<PasswordCredential>(passwordCredentials));
+        // return result
+        return passwordCredentials;
     }
 
     //
@@ -623,6 +976,9 @@ public class JetspeedSecurityPersistence
             try
             {
                 getPersistenceBrokerTemplate().store(new JetspeedPrincipalAssociation(from, to, associationName));
+                // evict principals from cache to notify
+                jspmCache.evictPrincipal(from.getId());
+                jspmCache.evictPrincipal(to.getId());
             }
             catch (Exception pbe)
             {
@@ -653,6 +1009,9 @@ public class JetspeedSecurityPersistence
             try
             {
                 getPersistenceBrokerTemplate().delete(new JetspeedPrincipalAssociation(from, to, associationName));
+                // evict principals from cache to notify
+                jspmCache.evictPrincipal(from.getId());
+                jspmCache.evictPrincipal(to.getId());
             }
             catch (Exception pbe)
             {
@@ -671,10 +1030,22 @@ public class JetspeedSecurityPersistence
     @SuppressWarnings("unchecked") 
     public List<PersistentJetspeedPermission> getPermissions()
     {
+        // check cache
+        String cacheKey = "getPermissions:[]";
+        List<PersistentJetspeedPermission> permissions = (List<PersistentJetspeedPermission>) jspmCache.getPermissionQuery(cacheKey);
+        if (permissions != null)
+        {
+            return new ArrayList<PersistentJetspeedPermission>(permissions);
+        }
+        // perform query
         QueryByCriteria query = QueryFactory.newQuery(PersistentJetspeedPermissionImpl.class, new Criteria());
         query.addOrderByAscending("type");
         query.addOrderByAscending("name");
-        return (List<PersistentJetspeedPermission>)getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        permissions = (List<PersistentJetspeedPermission>)getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        jspmCache.putPermissionQuery(cacheKey, null, null, JSPMCache.ANY_ID, null, new ArrayList<PersistentJetspeedPermission>(permissions));
+        // return result
+        return permissions;
     }
 
     public List<PersistentJetspeedPermission> getPermissions(String type)
@@ -691,9 +1062,21 @@ public class JetspeedSecurityPersistence
         {
             criteria.addLike("name", nameFilter+"%");
         }
+        // check cache
+        String cacheKey = "getPermissions:"+criteria;
+        List<PersistentJetspeedPermission> permissions = (List<PersistentJetspeedPermission>) jspmCache.getPermissionQuery(cacheKey);
+        if (permissions != null)
+        {
+            return new ArrayList<PersistentJetspeedPermission>(permissions);
+        }
+        // perform query
         QueryByCriteria query = QueryFactory.newQuery(PersistentJetspeedPermissionImpl.class, criteria);
         query.addOrderByAscending("name");
-        return (List<PersistentJetspeedPermission>)getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        permissions = (List<PersistentJetspeedPermission>)getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        jspmCache.putPermissionQuery(cacheKey, null, null, JSPMCache.ANY_ID, null, new ArrayList<PersistentJetspeedPermission>(permissions));
+        // return result
+        return permissions;
     }
 
     public boolean permissionExists(JetspeedPermission permission)
@@ -702,8 +1085,20 @@ public class JetspeedSecurityPersistence
         criteria.addEqualTo("type", permission.getType());
         criteria.addEqualTo("name", permission.getName());
         criteria.addEqualTo("actions", permission.getActions());
+        // check cache
+        String cacheKey = "permissionExists:"+criteria;
+        Boolean permissionExists = (Boolean)jspmCache.getPermissionQuery(cacheKey);
+        if (permissionExists != null)
+        {
+            return permissionExists;
+        }
+        // perform query
         Query query = QueryFactory.newQuery(PersistentJetspeedPermissionImpl.class, criteria);
-        return getPersistenceBrokerTemplate().getCount(query) == 1;
+        permissionExists = (getPersistenceBrokerTemplate().getCount(query) == 1);
+        // put result in cache
+        jspmCache.putPermissionQuery(cacheKey, null, null, JSPMCache.ANY_ID, null, permissionExists);
+        // return result
+        return permissionExists;
     }
     
     @SuppressWarnings("unchecked") 
@@ -711,15 +1106,32 @@ public class JetspeedSecurityPersistence
     {
         Criteria criteria = new Criteria();
         criteria.addEqualTo("principals.principalId", principal.getId());
+        // check cache
+        String cacheKey = "getPermissions:"+criteria;
+        List<PersistentJetspeedPermission> permissions = (List<PersistentJetspeedPermission>) jspmCache.getPermissionQuery(cacheKey);
+        if (permissions != null)
+        {
+            return new ArrayList<PersistentJetspeedPermission>(permissions);
+        }
+        // perform query
         QueryByCriteria query = QueryFactory.newQuery(PersistentJetspeedPermissionImpl.class, criteria);
         query.addOrderByAscending("type");
         query.addOrderByAscending("name");
-        return (List<PersistentJetspeedPermission>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        permissions = (List<PersistentJetspeedPermission>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        jspmCache.putPermissionQuery(cacheKey, principal.getId(), null, JSPMCache.ANY_ID, null, new ArrayList<PersistentJetspeedPermission>(permissions));
+        // return result
+        return permissions;
     }
 
-    @SuppressWarnings("unchecked") 
     public List<JetspeedPrincipal> getPrincipals(PersistentJetspeedPermission permission, String principalType)
     {
+        return getPrincipals(permission, principalType, getDefaultSecurityDomainId());
+    }
+
+    @SuppressWarnings("unchecked") 
+    public List<JetspeedPrincipal> getPrincipals(PersistentJetspeedPermission permission, String principalType, Long securityDomain)
+    {
         Criteria criteria = new Criteria();
         if (permission.getId() != null)
         {
@@ -734,11 +1146,23 @@ public class JetspeedSecurityPersistence
         {
             criteria.addEqualTo("type", principalType);
         }
-        criteria.addEqualTo("domainId", getDefaultSecurityDomainId());
+        criteria.addEqualTo("domainId", securityDomain);
+        // check cache
+        String cacheKey = "getPrincipals:"+criteria;
+        List<JetspeedPrincipal> principals = (List<JetspeedPrincipal>) jspmCache.getPermissionQuery(cacheKey);
+        if (principals != null)
+        {
+            return new ArrayList<JetspeedPrincipal>(principals);
+        }
+        // perform query
         QueryByCriteria query = QueryFactory.newQuery(PersistentJetspeedPrincipal.class, criteria);
         query.addOrderByAscending("type");
         query.addOrderByAscending("name");
-        return (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        principals = (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        jspmCache.putPermissionQuery(cacheKey, null, extractPrincipalIds(principals), ((permission.getId() != null) ? permission.getId(): JSPMCache.ANY_ID), securityDomain, new ArrayList<JetspeedPrincipal>(principals));
+        // return result
+        return principals;
     }
 
     //
@@ -753,6 +1177,9 @@ public class JetspeedSecurityPersistence
         try
         {
             getPersistenceBrokerTemplate().store(permission);
+            // evict from and put in cache to notify
+            jspmCache.evictPermission(permission.getId());
+            jspmCache.putPermission(permission.getId(), permission);
         }
         catch (Exception pbe)
         {
@@ -788,6 +1215,9 @@ public class JetspeedSecurityPersistence
             try
             {
                 getPersistenceBrokerTemplate().store(current);
+                // evict from and put in cache to notify
+                jspmCache.evictPermission(current.getId());
+                jspmCache.putPermission(current.getId(), current);
             }
             catch (Exception pbe)
             {
@@ -821,6 +1251,8 @@ public class JetspeedSecurityPersistence
         try
         {
             getPersistenceBrokerTemplate().delete(current);
+            // evict from cache to notify
+            jspmCache.evictPermission(current.getId());
         }
         catch (Exception pbe)
         {
@@ -870,6 +1302,9 @@ public class JetspeedSecurityPersistence
             try
             {
                 getPersistenceBrokerTemplate().store(new JetspeedPrincipalPermission(principal, permission));
+                // evict from principal and permission caches to notify
+                jspmCache.evictPrincipal(permission.getId());
+                jspmCache.evictPermission(permission.getId());
             }
             catch (Exception pbe)
             {
@@ -882,9 +1317,14 @@ public class JetspeedSecurityPersistence
         }
     }
 
-    @SuppressWarnings("unchecked") 
     public void grantPermissionOnlyTo(PersistentJetspeedPermission permission, String principalType, List<JetspeedPrincipal> principals) throws SecurityException
     {
+        grantPermissionOnlyTo(permission, principalType, principals, getDefaultSecurityDomainId());
+    }
+
+    @SuppressWarnings("unchecked")
+    public void grantPermissionOnlyTo(PersistentJetspeedPermission permission, String principalType, List<JetspeedPrincipal> principals, Long securityDomain) throws SecurityException
+    {
         if (permission.getId() == null)
         {
             Criteria criteria = new Criteria();
@@ -904,7 +1344,7 @@ public class JetspeedSecurityPersistence
         {
             criteria.addEqualTo("type", principalType);
         }
-        criteria.addEqualTo("domainId", getDefaultSecurityDomainId());
+        criteria.addEqualTo("domainId", securityDomain);
         QueryByCriteria query = QueryFactory.newQuery(PersistentJetspeedPrincipal.class, criteria);
         List<JetspeedPrincipal> currentList = (List<JetspeedPrincipal>) getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
         List<JetspeedPrincipal> targetList = new ArrayList<JetspeedPrincipal>(principals);
@@ -946,29 +1386,38 @@ public class JetspeedSecurityPersistence
     public void revokePermission(PersistentJetspeedPermission permission, JetspeedPrincipal principal) throws SecurityException
     {
         Long principalId = null;
-        Criteria criteria = new Criteria();
         if (principal.isTransient() || principal.getId() == null)
         {
-            principalId = getPrincipalId(principal.getName(), principal.getType().getName(), getDefaultSecurityDomainId());
+            Long securityDomain = ((principal.getDomainId() != null) ? principal.getDomainId() : getDefaultSecurityDomainId());
+            principalId = getPrincipalId(principal.getName(), principal.getType().getName(), securityDomain);
         }
         else
         {
             principalId = principal.getId();
         }
-        criteria.addEqualTo("principalId", principalId);
         if (permission.getId() == null)
         {
-            criteria.addEqualTo("permission.type", permission.getType());
-            criteria.addEqualTo("permission.name", permission.getName());
-        }
-        else
-        {
-            criteria.addEqualTo("permissionId", permission.getId());
+            Criteria criteria = new Criteria();
+            criteria.addEqualTo("type", permission.getType());
+            criteria.addEqualTo("name", permission.getName());
+            Query query = QueryFactory.newQuery(PersistentJetspeedPermissionImpl.class, criteria);
+            PersistentJetspeedPermission p = (PersistentJetspeedPermission)getPersistenceBrokerTemplate().getObjectByQuery(query);
+            if (p == null)
+            {
+                throw new SecurityException(SecurityException.PERMISSION_DOES_NOT_EXIST.create(permission.getName()));
+            }
+            permission = p;
         }
+        Criteria criteria = new Criteria();
+        criteria.addEqualTo("principalId", principalId);
+        criteria.addEqualTo("permissionId", permission.getId());
         Query query = QueryFactory.newQuery(JetspeedPrincipalPermission.class,criteria);
         try
         {
             getPersistenceBrokerTemplate().deleteByQuery(query);
+            // evict from principal cache to notify
+            jspmCache.evictPrincipal(principalId);
+            jspmCache.evictPermission(permission.getId());
         }
         catch (Exception pbe)
         {
@@ -986,7 +1435,8 @@ public class JetspeedSecurityPersistence
         Criteria criteria = new Criteria();
         if (principal.isTransient() || principal.getId() == null)
         {
-            principalId = getPrincipalId(principal.getName(), principal.getType().getName(), getDefaultSecurityDomainId());
+            Long securityDomain = ((principal.getDomainId() != null) ? principal.getDomainId() : getDefaultSecurityDomainId());
+            principalId = getPrincipalId(principal.getName(), principal.getType().getName(), securityDomain);
         }
         else
         {
@@ -997,6 +1447,8 @@ public class JetspeedSecurityPersistence
         try
         {
             getPersistenceBrokerTemplate().deleteByQuery(query);
+            // evict from principal cache to notify
+            jspmCache.evictPrincipal(principalId);
         }
         catch (Exception pbe)
         {
@@ -1025,6 +1477,9 @@ public class JetspeedSecurityPersistence
         try
         {
             getPersistenceBrokerTemplate().store(domain);
+            // evict from and put in cache to notify
+            jspmCache.evictDomain(domain.getDomainId());
+            jspmCache.putDomain(domain.getDomainId(), domain);
         }
         catch (Exception pbe)
         {
@@ -1038,12 +1493,24 @@ public class JetspeedSecurityPersistence
 
     public SecurityDomain getDomain(Long domainId)
     {
-        try{
-            return (SecurityDomain) getPersistenceBrokerTemplate().getObjectById(SecurityDomainImpl.class, domainId);    
-        } catch (ObjectRetrievalFailureException ore){
-            return null;
+        // check cache
+        Object domain = jspmCache.getDomain(domainId);
+        if (domain != null)
+        {
+            return ((domain != JSPMCache.CACHE_NULL) ? (SecurityDomain) domain : null);
         }
-        
+        // perform query
+        try
+        {
+            domain = getPersistenceBrokerTemplate().getObjectById(SecurityDomainImpl.class, domainId);
+        }
+        catch (ObjectRetrievalFailureException orfe)
+        {
+        }
+        // put result in cache
+        jspmCache.putDomain(domainId, ((domain != null) ? domain : JSPMCache.CACHE_NULL));
+        // return result
+        return (SecurityDomain) domain;
     }
 
     protected Long getDefaultSecurityDomainId()
@@ -1068,16 +1535,47 @@ public class JetspeedSecurityPersistence
     {
     	Criteria criteria = new Criteria();
         criteria.addEqualTo("name", domainName);
+        // check cache
+        String cacheKey = "getDomainByName:"+criteria;
+        Object domain = jspmCache.getDomainQuery(cacheKey);
+        if (domain != null)
+        {
+            return ((domain != JSPMCache.CACHE_NULL) ? (SecurityDomain) domain : null);
+        }
+        // perform query
         Query query = QueryFactory.newQuery(SecurityDomainImpl.class,criteria);
-        return (SecurityDomain) getPersistenceBrokerTemplate().getObjectByQuery(query);    
+        domain = getPersistenceBrokerTemplate().getObjectByQuery(query);
+        // put result in cache
+        if (domain != null)
+        {
+            jspmCache.putDomainQuery(cacheKey, ((SecurityDomain)domain).getDomainId(), domain);
+        }
+        else
+        {
+            jspmCache.putDomainQuery(cacheKey, JSPMCache.ANY_ID, JSPMCache.CACHE_NULL);
+        }
+        // return result
+        return (SecurityDomain) domain;
     }
 
     @SuppressWarnings("unchecked") 
     public Collection<SecurityDomain> getAllDomains()
     {
+        // check cache
+        String cacheKey = "getDomains:[]";
+        List<SecurityDomain> domains = (List<SecurityDomain>) jspmCache.getDomainQuery(cacheKey);
+        if (domains != null)
+        {
+            return new ArrayList<SecurityDomain>(domains);
+        }
+        // perform query
         QueryByCriteria query = QueryFactory.newQuery(SecurityDomainImpl.class, new Criteria());
         query.addOrderByAscending("name");
-        return (List<SecurityDomain>)getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        domains = (List<SecurityDomain>)getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        jspmCache.putDomainQuery(cacheKey, JSPMCache.ANY_ID, new ArrayList<SecurityDomain>(domains));
+        // return result
+        return domains;
     }
     
     public void removeDomain(SecurityDomain domain) throws SecurityException
@@ -1089,6 +1587,8 @@ public class JetspeedSecurityPersistence
         try
         {
             getPersistenceBrokerTemplate().delete(domain);
+            // evict from cache to notify
+            jspmCache.evictDomain(domain.getDomainId());
         }
         catch (Exception pbe)
         {
@@ -1115,6 +1615,9 @@ public class JetspeedSecurityPersistence
          try
          {
              getPersistenceBrokerTemplate().store(domain);
+             // evict from and put in cache to notify
+             jspmCache.evictDomain(domain.getDomainId());
+             jspmCache.putDomain(domain.getDomainId(), domain);
          }
          catch (Exception pbe)
          {
@@ -1137,9 +1640,21 @@ public class JetspeedSecurityPersistence
     {
         Criteria criteria = new Criteria();
         criteria.addEqualTo("ownerDomainId", ownerDomainId);
+        // check cache
+        String cacheKey = "getDomainsOwnedBy:"+criteria;
+        List<SecurityDomain> domains = (List<SecurityDomain>) jspmCache.getDomainQuery(cacheKey);
+        if (domains != null)
+        {
+            return new ArrayList<SecurityDomain>(domains);
+        }
+        // perform query
         QueryByCriteria query = QueryFactory.newQuery(SecurityDomainImpl.class, criteria);
         query.addOrderByAscending("name");
-        return (List<SecurityDomain>)getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        domains = (List<SecurityDomain>)getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
+        // put result in cache
+        jspmCache.putDomainQuery(cacheKey, JSPMCache.ANY_ID, new ArrayList<SecurityDomain>(domains));
+        // return result
+        return domains;
     }
     
 	public JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext, JetspeedPrincipalType type) {
@@ -1150,6 +1665,8 @@ public class JetspeedSecurityPersistence
 	 * @see org.apache.jetspeed.security.spi.JetspeedPrincipalAccessManager#getPrincipals(org.apache.jetspeed.security.JetspeedPrincipalQueryContext, org.apache.jetspeed.security.JetspeedPrincipalType, java.lang.Long)
 	 */
 	public JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext, JetspeedPrincipalType type, Long securityDomain) {
+        // paged principal queries not cached: used only for UI purposes where
+        // results should reflect exact set of principals in database
 		JetspeedPrincipalLookupManager jppm = jpplf.getJetspeedPrincipalLookupManager();
 		queryContext.put(JetspeedPrincipalQueryContext.JETSPEED_PRINCIPAL_TYPE, type.getName());
 		queryContext.put(JetspeedPrincipalQueryContext.SECURITY_DOMAIN, securityDomain);

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/PersistentJetspeedPermissionImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/PersistentJetspeedPermissionImpl.java?rev=1678139&r1=1678138&r2=1678139&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/PersistentJetspeedPermissionImpl.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/PersistentJetspeedPermissionImpl.java Thu May  7 06:48:06 2015
@@ -17,13 +17,14 @@
 
 package org.apache.jetspeed.security.spi.impl;
 
+import org.apache.jetspeed.cache.DistributedCacheObject;
 import org.apache.jetspeed.security.spi.PersistentJetspeedPermission;
 
 /**
  * @version $Id$
  *
  */
-public class PersistentJetspeedPermissionImpl implements PersistentJetspeedPermission
+public class PersistentJetspeedPermissionImpl implements PersistentJetspeedPermission, DistributedCacheObject
 {
     private static final long serialVersionUID = 9200223005769593282L;
     private Long id;
@@ -65,4 +66,9 @@ public class PersistentJetspeedPermissio
     {
         this.actions = actions;
     }
+
+    @Override
+    public void notifyChange(int action)
+    {
+    }
 }

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/cache/JSPMCache.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/cache/JSPMCache.java?rev=1678139&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/cache/JSPMCache.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/cache/JSPMCache.java Thu May  7 06:48:06 2015
@@ -0,0 +1,245 @@
+/*
+ * 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.security.spi.impl.cache;
+
+import org.apache.jetspeed.cache.DistributedCacheObject;
+
+/**
+ * JSPMCache - JetspeedSecurityPersistenceManager cache
+ *
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id: $
+ */
+public interface JSPMCache {
+
+    /**
+     * Negative caching null sentinel cache element value.
+     */
+    public static final Object CACHE_NULL = new DistributedCacheObject()
+    {
+        @Override
+        public void notifyChange(int action)
+        {
+        }
+
+        @Override
+        public String toString()
+        {
+            return "JSPMCache.CACHE_NULL";
+        }
+    };
+
+    /**
+     * Cache element wildcard dependent id.
+     */
+    public static final Long ANY_ID = JSPMQueryCacheElement.ANY_ID;
+
+    /**
+     * Get principal from instance cache.
+     *
+     * @param id principal id
+     * @return principal instance or CACHE_NULL
+     */
+    Object getPrincipal(Long id);
+
+    /**
+     * Put principal in instance cache.
+     *
+     * @param id principal id
+     * @param principal principal instance or CACHE_NULL
+     */
+    void putPrincipal(Long id, Object principal);
+
+    /**
+     * Evict principal from instance cache and notify local
+     * and distributed listeners. Also evicts related queries
+     * from query caches.
+     *
+     * @param id principal id
+     */
+    void evictPrincipal(Long id);
+
+    /**
+     * Get permission from instance cache.
+     *
+     * @param id permission id
+     * @return permission instance or CACHE_NULL
+     */
+    Object getPermission(Long id);
+
+    /**
+     * Put permission in instance cache.
+     *
+     * @param id permission id
+     * @param permission permission instance or CACHE_NULL
+     */
+    void putPermission(Long id, Object permission);
+
+    /**
+     * Evict permission from instance cache and notify local
+     * and distributed listeners. Also evicts related queries
+     * from query caches.
+     *
+     * @param id permission id
+     */
+    void evictPermission(Long id);
+
+    /**
+     * Get domain from instance cache.
+     *
+     * @param id domain id
+     * @return domain instance or CACHE_NULL
+     */
+    Object getDomain(Long id);
+
+    /**
+     * Put domain in instance cache.
+     *
+     * @param id domain id
+     * @param domain domain instance or CACHE_NULL
+     */
+    void putDomain(Long id, Object domain);
+
+    /**
+     * Evict domain from instance cache and notify local
+     * and distributed listeners. Also evicts related queries
+     * from query caches.
+     *
+     * @param id domain id
+     */
+    void evictDomain(Long id);
+
+    /**
+     * Get principal query result from query cache.
+     *
+     * @param key principal query key
+     * @return principle query result or CACHE_NULL
+     */
+    Object getPrincipalQuery(String key);
+
+    /**
+     * Put principal query result and dependent instance ids
+     * in query cache. Dependent instance ids are used to
+     * evict based on instance cache notifications.
+     *
+     * @param key principal query key
+     * @param principalId dependent principal id, ANY_ID, or null
+     * @param permissionId dependent permission id, ANY_ID, or null
+     * @param domainId dependent domain id, ANY_ID, or null
+     * @param query query result
+     */
+    void putPrincipalQuery(String key, Long principalId, Long permissionId, Long domainId, Object query);
+
+    /**
+     * Get principal association query result from query cache.
+     *
+     * @param key principal association query key
+     * @return principle association query result or CACHE_NULL
+     */
+    Object getAssociationQuery(String key);
+
+    /**
+     * Put principal association query result and dependent
+     * instance ids in query cache. Dependent instance ids are
+     * used to evict based on instance cache notifications.
+     *
+     * @param key principal association query key
+     * @param principalId dependent principal id, ANY_ID, or null
+     * @param otherPrincipalIds dependent principal ids or null
+     * @param domainId dependent domain id, ANY_ID, or null
+     * @param otherDomainId dependent domain id, ANY_ID, or null
+     * @param query query result
+     */
+    void putAssociationQuery(String key, Long principalId, Long [] otherPrincipalIds, Long domainId, Long otherDomainId,
+                             Object query);
+
+    /**
+     * Get principal password credential query result from query cache.
+     *
+     * @param key principal password credential query key
+     * @return principle password credential query result or CACHE_NULL
+     */
+    Object getPasswordCredentialQuery(String key);
+
+    /**
+     * Put principal password credential query result and
+     * dependent instance ids in query cache. Dependent
+     * instance ids are used to evict based on instance cache
+     * notifications.
+     *
+     * @param key principal password credential query key
+     * @param principalId dependent principal id, ANY_ID, or null
+     * @param domainId dependent domain id, ANY_ID, or null
+     * @param query query result
+     */
+    void putPasswordCredentialQuery(String key, Long principalId, Long domainId, Object query);
+
+    /**
+     * Get permission query result from query cache.
+     *
+     * @param key permission query key
+     * @return permission query result or CACHE_NULL
+     */
+    Object getPermissionQuery(String key);
+
+    /**
+     * Put permission query result and dependent instance ids
+     * in query cache. Dependent instance ids are used to
+     * evict based on instance cache notifications.
+     *
+     * @param key permission query key
+     * @param principalId dependent principal id, ANY_ID, or null
+     * @param otherPrincipalIds dependent principal ids or null
+     * @param permissionId dependent permission id, ANY_ID, or null
+     * @param domainId dependent domain id, ANY_ID, or null
+     * @param query query result
+     */
+    void putPermissionQuery(String key, Long principalId, Long [] otherPrincipalIds, Long permissionId, Long domainId,
+                            Object query);
+
+    /**
+     * Get domain query result from query cache.
+     *
+     * @param key domain query key
+     * @return domain query result or CACHE_NULL
+     */
+    Object getDomainQuery(String key);
+
+    /**
+     * Put domain query result and dependent instance ids in
+     * query cache. Dependent instance ids are used to evict
+     * based on instance cache notifications.
+     *
+     * @param key domain query key
+     * @param domainId dependent domain id, ANY_ID, or null
+     * @param query query result
+     */
+    void putDomainQuery(String key, Long domainId, Object query);
+
+    /**
+     * Return sum of the number of elements in all instance
+     * and query caches.
+     *
+     * @return cache size
+     */
+    int size();
+
+    /**
+     * Clear all instance and query caches.
+     */
+    void clear();
+}



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