diff --git a/kernel-impl/src/main/java/org/sakaiproject/alias/impl/BaseAliasService.java b/kernel-impl/src/main/java/org/sakaiproject/alias/impl/BaseAliasService.java index a33d227..5ca3a25 100644 --- a/kernel-impl/src/main/java/org/sakaiproject/alias/impl/BaseAliasService.java +++ b/kernel-impl/src/main/java/org/sakaiproject/alias/impl/BaseAliasService.java @@ -21,10 +21,13 @@ package org.sakaiproject.alias.impl; +import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Observable; +import java.util.Observer; import java.util.Set; import java.util.Stack; import java.util.Arrays; @@ -44,6 +47,7 @@ import org.sakaiproject.entity.api.HttpAccess; import org.sakaiproject.entity.api.Reference; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.entity.api.ResourcePropertiesEdit; +import org.sakaiproject.event.api.Event; import org.sakaiproject.event.api.EventTrackingService; import org.sakaiproject.exception.IdInvalidException; import org.sakaiproject.exception.IdUnusedException; @@ -52,6 +56,7 @@ import org.sakaiproject.exception.InUseException; import org.sakaiproject.exception.PermissionException; import org.sakaiproject.memory.api.Cache; import org.sakaiproject.memory.api.MemoryService; +import org.sakaiproject.memory.api.MultiRefCache; import org.sakaiproject.site.api.SiteService; import org.sakaiproject.time.api.Time; import org.sakaiproject.time.api.TimeService; @@ -75,7 +80,7 @@ import org.w3c.dom.NodeList; * BaseAliasService is ... *

*/ -public abstract class BaseAliasService implements AliasService, StorageUser +public abstract class BaseAliasService implements AliasService, StorageUser, Observer { /** Our logger. */ private static Log M_log = LogFactory.getLog(BaseAliasService.class); @@ -88,6 +93,9 @@ public abstract class BaseAliasService implements AliasService, StorageUser /** A cache of calls to the service and the results. */ protected Cache m_callCache = null; + + /** A cache of calls to the getAliases calls */ + protected MultiRefCache m_targetCache = null; private List prohibited_aliases = null; @@ -374,6 +382,11 @@ public abstract class BaseAliasService implements AliasService, StorageUser m_callCache = memoryService().newCache( "org.sakaiproject.alias.api.AliasService.callCache", aliasReference("")); + m_targetCache = memoryService().newMultiRefCache( + "org.sakaiproject.alias.api.AliasService.targetCache"); + + // Need to catch new aliases being added so we don't still serve up the old data. + eventTrackingService().addObserver(this); } // register as an entity producer @@ -601,8 +614,32 @@ public abstract class BaseAliasService implements AliasService, StorageUser */ public List getAliases(String target) { - List allForTarget = m_storage.getAll(target); + List allForTarget = null; + boolean found = false; + if (m_targetCache != null) + { + allForTarget = (List)m_targetCache.get(target); + } + if (allForTarget == null) + { + allForTarget = m_storage.getAll(target); + if (m_targetCache != null) + { + Collection dependRefs = null; + if (allForTarget != null) + { + dependRefs = new ArrayList(allForTarget.size()); + // Need to cache against a set of references. + for(Alias alias: (List)allForTarget) + { + dependRefs.add(alias.getReference()); + } + } + m_targetCache.put(target, allForTarget, target, dependRefs); + } + } + return allForTarget; } // getAliases @@ -1894,6 +1931,36 @@ public abstract class BaseAliasService implements AliasService, StorageUser { return null; } + + /** + * Registered with the event service, to invalidate cache entries. + * @param The observable object. + * @param Hopefully an Event which we can check against. + */ + public void update(Observable o, Object arg) + { + if (arg instanceof Event) + { + Event event = (Event) arg; + if (SECURE_ADD_ALIAS.equals(event.getEvent()) + && event.getResource().startsWith( + REFERENCE_ROOT + Entity.SEPARATOR)) + { + String id = event.getResource().substring( + (REFERENCE_ROOT + Entity.SEPARATOR).length()); + String target; + try + { + target = getTarget(id); + m_targetCache.remove(target); + } + catch (IdUnusedException e) + { + M_log.warn("Failed to find new Alias: " + id); + } + } + } + } } // BaseAliasService