1 17 package org.alfresco.repo.policy; 18 19 import java.util.ArrayList ; 20 import java.util.Collection ; 21 import java.util.HashMap ; 22 import java.util.Map ; 23 import java.util.concurrent.locks.ReentrantReadWriteLock ; 24 25 import org.apache.commons.logging.Log; 26 import org.apache.commons.logging.LogFactory; 27 28 29 37 class CachedPolicyFactory<B extends BehaviourBinding, P extends Policy> extends PolicyFactory<B, P> 38 { 39 private static final Log logger = LogFactory.getLog(PolicyComponentImpl.class); 41 42 private BehaviourFilter behaviourFilter = null; 44 45 private ReentrantReadWriteLock lock = new ReentrantReadWriteLock (); 47 48 51 private Map <B, P> singleCache = new HashMap <B, P>(); 52 53 56 private Map <B, Collection <P>> listCache = new HashMap <B, Collection <P>>(); 57 58 59 65 CachedPolicyFactory(Class <P> policyClass, BehaviourIndex<B> index) 66 { 67 super(policyClass, index); 68 behaviourFilter = index.getFilter(); 69 70 index.addChangeObserver(new BehaviourChangeObserver<B>() 73 { 74 public void addition(B binding, Behaviour behaviour) 75 { 76 clearCache("aggregate delegate", singleCache, binding); 77 clearCache("delegate collection", listCache, binding); 78 } 79 }); 80 } 81 82 83 @Override 84 public P create(B binding) 85 { 86 if (behaviourFilter != null && behaviourFilter.isActivated()) 88 { 89 return super.create(binding); 90 } 91 92 lock.readLock().lock(); 93 94 try 95 { 96 P policyInterface = singleCache.get(binding); 97 if (policyInterface == null) 98 { 99 lock.readLock().unlock(); 101 lock.writeLock().lock(); 102 103 try 104 { 105 policyInterface = singleCache.get(binding); 107 if (policyInterface == null) 108 { 109 policyInterface = super.create(binding); 110 singleCache.put(binding, policyInterface); 111 112 if (logger.isDebugEnabled()) 113 logger.debug("Cached delegate interface " + policyInterface + " for " + binding + " and policy " + getPolicyClass()); 114 } 115 } 116 finally 117 { 118 lock.readLock().lock(); 120 lock.writeLock().unlock(); 121 } 122 } 123 return policyInterface; 124 } 125 finally 126 { 127 lock.readLock().unlock(); 128 } 129 } 130 131 132 @Override 133 public Collection <P> createList(B binding) 134 { 135 if (behaviourFilter != null && behaviourFilter.isActivated()) 137 { 138 return super.createList(binding); 139 } 140 141 lock.readLock().lock(); 142 143 try 144 { 145 Collection <P> policyInterfaces = listCache.get(binding); 146 if (policyInterfaces == null) 147 { 148 lock.readLock().unlock(); 150 lock.writeLock().lock(); 151 152 try 153 { 154 policyInterfaces = listCache.get(binding); 156 if (policyInterfaces == null) 157 { 158 policyInterfaces = super.createList(binding); 159 listCache.put(binding, policyInterfaces); 160 161 if (logger.isDebugEnabled()) 162 logger.debug("Cached delegate interface collection " + policyInterfaces + " for " + binding + " and policy " + getPolicyClass()); 163 } 164 } 165 finally 166 { 167 lock.readLock().lock(); 169 lock.writeLock().unlock(); 170 } 171 } 172 return policyInterfaces; 173 } 174 finally 175 { 176 lock.readLock().unlock(); 177 } 178 } 179 180 181 188 private void clearCache(String cacheDescription, Map <B, ?> cache, B binding) 189 { 190 if (binding == null) 191 { 192 lock.writeLock().lock(); 193 194 try 195 { 196 cache.clear(); 198 199 if (logger.isDebugEnabled() && cache.isEmpty() == false) 200 logger.debug("Cleared " + cacheDescription + " cache (all class bindings) for policy " + getPolicyClass()); 201 } 202 finally 203 { 204 lock.writeLock().unlock(); 205 } 206 } 207 else 208 { 209 Collection <B> invalidBindings = new ArrayList <B>(); 213 for (B cachedBinding : cache.keySet()) 214 { 215 BehaviourBinding generalisedBinding = cachedBinding; 217 while(generalisedBinding != null) 218 { 219 if (generalisedBinding.equals(binding)) 220 { 221 invalidBindings.add(cachedBinding); 222 break; 223 } 224 generalisedBinding = generalisedBinding.generaliseBinding(); 225 } 226 } 227 228 if (invalidBindings.size() > 0) 230 { 231 lock.writeLock().lock(); 232 233 try 234 { 235 for (B invalidBinding : invalidBindings) 236 { 237 cache.remove(invalidBinding); 238 239 if (logger.isDebugEnabled()) 240 logger.debug("Cleared " + cacheDescription + " cache for " + invalidBinding + " and policy " + getPolicyClass()); 241 } 242 } 243 finally 244 { 245 lock.writeLock().unlock(); 246 } 247 } 248 } 249 } 250 251 } 252 | Popular Tags |