Transactional safe cache added to PersonServiceImpl to cache person NodeRefs against usernames.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6036 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2007-06-20 16:30:49 +00:00
parent 1073576c12
commit aa41ae3768
3 changed files with 220 additions and 114 deletions

View File

@@ -173,11 +173,9 @@
--> -->
<!-- The person service. --> <!-- The person service. -->
<bean id="personService" class="org.alfresco.repo.security.person.PersonServiceImpl"> <bean id="personService" class="org.alfresco.repo.security.person.PersonServiceImpl" init-method="init">
<property name="nodeService"> <property name="nodeService">
<ref bean="nodeService" /> <ref bean="nodeService" />
</property> </property>
@@ -193,6 +191,12 @@
<property name="namespacePrefixResolver"> <property name="namespacePrefixResolver">
<ref bean="namespaceService" /> <ref bean="namespaceService" />
</property> </property>
<property name="policyComponent">
<ref bean="policyComponent"/>
</property>
<property name="personCache">
<ref bean="personCache" />
</property>
<!-- Configurable properties. --> <!-- Configurable properties. -->
<!-- --> <!-- -->
<!-- TODO: --> <!-- TODO: -->

View File

@@ -208,4 +208,41 @@
</property> </property>
</bean> </bean>
<!-- ===================================== -->
<!-- Person username to NodeRef cache -->
<!-- ===================================== -->
<!-- The cross-transaction shared cache for Person -->
<bean name="personSharedCache" class="org.alfresco.repo.cache.EhCacheAdapter">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean" >
<property name="cacheManager">
<ref bean="internalEHCacheManager" />
</property>
<property name="cacheName">
<value>org.alfresco.cache.personCache</value>
</property>
</bean>
</property>
</bean>
<!-- The transactional cache for Person -->
<bean name="personCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="personSharedCache" />
</property>
<property name="cacheManager" >
<ref bean="transactionalEHCacheManager" />
</property>
<!-- Eh cache area -->
<property name="name">
<value>org.alfresco.personTransactionalCache</value>
</property>
<property name="maxCacheSize">
<value>1000</value>
</property>
</bean>
</beans> </beans>

View File

@@ -35,8 +35,12 @@ import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.ldap.LDAPPersonExportSource; import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.security.permissions.PermissionServiceSPI; import org.alfresco.repo.security.permissions.PermissionServiceSPI;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
@@ -49,12 +53,14 @@ import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.NoSuchPersonException; import org.alfresco.service.cmr.security.NoSuchPersonException;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.NamespacePrefixResolver; import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
public class PersonServiceImpl implements PersonService public class PersonServiceImpl implements PersonService,
NodeServicePolicies.OnCreateNodePolicy, NodeServicePolicies.BeforeDeleteNodePolicy
{ {
private static Log s_logger = LogFactory.getLog(PersonServiceImpl.class); private static Log s_logger = LogFactory.getLog(PersonServiceImpl.class);
@@ -82,6 +88,8 @@ public class PersonServiceImpl implements PersonService
private NamespacePrefixResolver namespacePrefixResolver; private NamespacePrefixResolver namespacePrefixResolver;
private PolicyComponent policyComponent;
private boolean createMissingPeople; private boolean createMissingPeople;
private static Set<QName> mutableProperties; private static Set<QName> mutableProperties;
@@ -98,6 +106,9 @@ public class PersonServiceImpl implements PersonService
private boolean includeAutoCreated = false; private boolean includeAutoCreated = false;
/** a transactionally-safe cache to be injected */
private SimpleCache<String, NodeRef> personCache;
static static
{ {
Set<QName> props = new HashSet<QName>(); Set<QName> props = new HashSet<QName>();
@@ -110,9 +121,19 @@ public class PersonServiceImpl implements PersonService
mutableProperties = Collections.unmodifiableSet(props); mutableProperties = Collections.unmodifiableSet(props);
} }
public PersonServiceImpl() /**
* Spring bean init method
*/
public void init()
{ {
super(); this.policyComponent.bindClassBehaviour(
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
ContentModel.TYPE_PERSON,
new JavaBehaviour(this, "onCreateNode"));
this.policyComponent.bindClassBehaviour(
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
ContentModel.TYPE_PERSON,
new JavaBehaviour(this, "beforeDeleteNode"));
} }
public boolean getUserNamesAreCaseSensitive() public boolean getUserNamesAreCaseSensitive()
@@ -150,6 +171,26 @@ public class PersonServiceImpl implements PersonService
this.processDuplicates = processDuplicates; this.processDuplicates = processDuplicates;
} }
/**
* Set the username to person cache.
*
* @param personCache a transactionally safe cache
*/
public void setPersonCache(SimpleCache<String, NodeRef> personCache)
{
this.personCache = personCache;
}
/**
* Retrieve the person NodeRef for a username key. Depending on configuration missing people
* will be created if not found, else a NoSuchPersonException exception will be thrown.
*
* @param userName of the person NodeRef to retrieve
*
* @return NodeRef of the person as specified by the username
*
* @throws NoSuchPersonException
*/
public NodeRef getPerson(String userName) public NodeRef getPerson(String userName)
{ {
NodeRef personNode = getPersonOrNull(userName); NodeRef personNode = getPersonOrNull(userName);
@@ -163,7 +204,6 @@ public class PersonServiceImpl implements PersonService
{ {
throw new NoSuchPersonException(userName); throw new NoSuchPersonException(userName);
} }
} }
else else
{ {
@@ -176,14 +216,14 @@ public class PersonServiceImpl implements PersonService
return getPersonOrNull(caseSensitiveUserName) != null; return getPersonOrNull(caseSensitiveUserName) != null;
} }
public NodeRef getPersonOrNull(String searchUserName) private NodeRef getPersonOrNull(String searchUserName)
{
NodeRef returnRef = this.personCache.get(searchUserName);
if (returnRef == null)
{ {
NodeRef returnRef = null;
SearchParameters sp = new SearchParameters(); SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_LUCENE); sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery("TYPE:\\{http\\://www.alfresco.org/model/content/1.0\\}person +@cm\\:userName:\"" sp.setQuery("@cm\\:userName:\"" + searchUserName + "\"");
+ searchUserName + "\"");
sp.addStore(storeRef); sp.addStore(storeRef);
sp.excludeDataInTheCurrentTransaction(false); sp.excludeDataInTheCurrentTransaction(false);
@@ -197,7 +237,6 @@ public class PersonServiceImpl implements PersonService
for (ResultSetRow row : rs) for (ResultSetRow row : rs)
{ {
NodeRef nodeRef = row.getNodeRef(); NodeRef nodeRef = row.getNodeRef();
if (nodeService.exists(nodeRef)) if (nodeService.exists(nodeRef))
{ {
@@ -244,15 +283,19 @@ public class PersonServiceImpl implements PersonService
rs.close(); rs.close();
} }
} }
if (singleton) if (singleton)
{ {
return returnRef; returnRef = returnRef;
} }
else else
{ {
return handleDuplicates(searchUserName); returnRef = handleDuplicates(searchUserName);
} }
// add to cache
this.personCache.put(searchUserName, returnRef);
}
return returnRef;
} }
private NodeRef handleDuplicates(String searchUserName) private NodeRef handleDuplicates(String searchUserName)
@@ -298,8 +341,7 @@ public class PersonServiceImpl implements PersonService
{ {
SearchParameters sp = new SearchParameters(); SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_LUCENE); sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery("TYPE:\\{http\\://www.alfresco.org/model/content/1.0\\}person +@cm\\:userName:\"" sp.setQuery("@cm\\:userName:\"" + searchUserName + "\"");
+ searchUserName + "\"");
sp.addStore(storeRef); sp.addStore(storeRef);
sp.excludeDataInTheCurrentTransaction(false); sp.excludeDataInTheCurrentTransaction(false);
@@ -349,8 +391,7 @@ public class PersonServiceImpl implements PersonService
{ {
SearchParameters sp = new SearchParameters(); SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_LUCENE); sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery("TYPE:\\{http\\://www.alfresco.org/model/content/1.0\\}person +@cm\\:userName:\"" sp.setQuery("@cm\\:userName:\"" + searchUserName + "\"");
+ searchUserName + "\"");
sp.addStore(storeRef); sp.addStore(storeRef);
sp.excludeDataInTheCurrentTransaction(false); sp.excludeDataInTheCurrentTransaction(false);
@@ -402,8 +443,7 @@ public class PersonServiceImpl implements PersonService
{ {
SearchParameters sp = new SearchParameters(); SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_LUCENE); sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery("TYPE:\\{http\\://www.alfresco.org/model/content/1.0\\}person +@cm\\:userName:\"" sp.setQuery("@cm\\:userName:\"" + searchUserName + "\"");
+ searchUserName + "\"");
sp.addStore(storeRef); sp.addStore(storeRef);
sp.excludeDataInTheCurrentTransaction(false); sp.excludeDataInTheCurrentTransaction(false);
if (lastIsBest) if (lastIsBest)
@@ -647,6 +687,29 @@ public class PersonServiceImpl implements PersonService
return nodes; return nodes;
} }
// Policies
/* (non-Javadoc)
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy#onCreateNode(org.alfresco.service.cmr.repository.ChildAssociationRef)
*/
public void onCreateNode(ChildAssociationRef childAssocRef)
{
NodeRef personRef = childAssocRef.getChildRef();
String username = (String)this.nodeService.getProperty(personRef, ContentModel.PROP_USERNAME);
this.personCache.put(username, personRef);
}
/* (non-Javadoc)
* @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef)
*/
public void beforeDeleteNode(NodeRef nodeRef)
{
String username = (String)this.nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME);
this.personCache.remove(username);
}
// IOC Setters
public void setCreateMissingPeople(boolean createMissingPeople) public void setCreateMissingPeople(boolean createMissingPeople)
{ {
this.createMissingPeople = createMissingPeople; this.createMissingPeople = createMissingPeople;
@@ -677,6 +740,11 @@ public class PersonServiceImpl implements PersonService
this.searchService = searchService; this.searchService = searchService;
} }
public void setPolicyComponent(PolicyComponent policyComponent)
{
this.policyComponent = policyComponent;
}
public void setStoreUrl(String storeUrl) public void setStoreUrl(String storeUrl)
{ {
this.storeRef = new StoreRef(storeUrl); this.storeRef = new StoreRef(storeUrl);
@@ -693,7 +761,4 @@ public class PersonServiceImpl implements PersonService
} }
return null; return null;
} }
// IOC Setters
} }