1 19 20 package com.sslexplorer.activedirectory; 21 22 import java.io.File ; 23 import java.io.Serializable ; 24 import java.util.ArrayList ; 25 import java.util.Collection ; 26 import java.util.HashSet ; 27 import java.util.regex.Pattern ; 28 29 import org.apache.commons.cache.BaseStorageListener; 30 import org.apache.commons.cache.Cache; 31 import org.apache.commons.cache.FileStash; 32 import org.apache.commons.cache.GroupMapImpl; 33 import org.apache.commons.cache.LRUEvictionPolicy; 34 import org.apache.commons.cache.MemoryStash; 35 import org.apache.commons.cache.SimpleCache; 36 import org.apache.commons.cache.Stash; 37 import org.apache.commons.cache.StorageListener; 38 import org.apache.commons.logging.Log; 39 import org.apache.commons.logging.LogFactory; 40 41 import com.sslexplorer.boot.ContextHolder; 42 import com.sslexplorer.boot.Util; 43 import com.sslexplorer.core.BundleActionMessage; 44 import com.sslexplorer.core.CoreUtil; 45 import com.sslexplorer.core.GlobalWarning; 46 import com.sslexplorer.policyframework.Principal; 47 48 public class PrincipalContainer<T extends Principal> { 49 private static final Log logger = LogFactory.getLog(PrincipalContainer.class); 50 private final int cacheSize; 51 private final boolean inMemoryCache; 52 private final String cacheType; 53 private final Cache principalCache; 54 55 PrincipalContainer(int cacheSize, boolean inMemoryCache, String cacheType, String cacheFullMessageText) { 56 this.cacheSize = cacheSize; 57 this.inMemoryCache = inMemoryCache; 58 this.cacheType = cacheType; 59 principalCache = createCache(cacheFullMessageText); 60 } 61 62 synchronized boolean containsPrincipal(String principalName) { 63 return retrievePrincipal(principalName) != null; 64 } 65 66 @SuppressWarnings ("unchecked") 67 synchronized T retrievePrincipal(String principalName) { 68 return (T) principalCache.retrieve(principalName); 69 } 70 71 synchronized Collection <String > retrievePrincipalNames() { 72 Serializable [] keysForGroup = principalCache.getKeysForGroup(cacheType); 73 Collection <String > principalNames = new ArrayList <String >(keysForGroup.length); 74 for (Serializable principalName : keysForGroup) { 75 principalNames.add((String ) principalName); 76 } 77 return principalNames; 78 } 79 80 @SuppressWarnings ("unchecked") 81 synchronized Collection <T> retrievePrincipals(String filter) { 82 String regex = Util.parseSimplePatternToRegExp(filter); 83 Pattern pattern = Pattern.compile(regex); 84 85 Serializable [] keysForGroup = principalCache.getKeysForGroup(cacheType); 86 Collection <T> principals = new HashSet <T>(keysForGroup.length); 87 for (Serializable principalName : keysForGroup) { 88 boolean matches = pattern.matcher((String ) principalName).matches(); 89 if (matches) { 90 T retrieve = (T) principalCache.retrieve(principalName); 91 if (retrieve != null) { 92 principals.add(retrieve); 93 } 94 } 95 } 96 97 if (logger.isDebugEnabled()) { 98 if (principals.isEmpty()) { 99 logger.debug("No principals in cache"); 100 } else { 101 logger.debug("Got " + principals.size() + " principals from the cache"); 102 } 103 } 104 return principals; 105 } 106 107 synchronized String storePrincipal(T principal) { 108 String principalName = principal.getPrincipalName(); 109 storePrinciple(principalName, principal); 110 return principalName; 111 } 112 113 synchronized String storePrinciple(String key, T principal) { 114 if (logger.isDebugEnabled()) { 115 logger.debug("Caching " + principal); 116 } 117 principalCache.store(key, (Serializable ) principal, Long.MAX_VALUE, null, cacheType); 118 return key; 119 } 120 121 synchronized void updateRemovedPrincipals(Collection <String > missingPrincipals) { 122 for (String principalName : missingPrincipals) { 123 removePrincipal(principalName); 124 } 125 } 126 127 public synchronized void removePrincipal(T principal) { 128 removePrincipal(principal.getPrincipalName()); 129 } 130 131 void removePrincipal(String principleName) { 132 principalCache.store(principleName, null, 0L, null, cacheType); 133 } 134 135 synchronized void close() { 136 closeCache(principalCache); 137 } 138 139 Cache createCache(String cacheFullMessageText) { 140 File cacheDirectory = new File (ContextHolder.getContext().getTempDirectory(), "cache"); 141 File cacheTypeDirectory = new File (cacheDirectory, cacheType); 142 Stash stash = inMemoryCache ? new MemoryStash(cacheSize) : new FileStash(Long.MAX_VALUE, cacheSize, new File []{cacheTypeDirectory}, true); 143 SimpleCache cache = new SimpleCache(stash, new LRUEvictionPolicy(), null, new GroupMapImpl()); 144 cache.registerStorageListener(getStorageListener(cacheFullMessageText)); 145 return cache; 146 } 147 148 private StorageListener getStorageListener(final String messageKey) { 149 return new BaseStorageListener() { 150 private static final long serialVersionUID = 4283488241230531541L; 151 private int storageCounter = 0; 152 private boolean addedWarning; 153 154 public synchronized void stored(Serializable arg0, Serializable arg1, Long arg2, Long arg3, Serializable arg4) { 155 storageCounter++; 156 } 157 158 public synchronized void cleared(Serializable arg0) { 159 if (storageCounter == cacheSize && !addedWarning) { 160 BundleActionMessage message = new BundleActionMessage("activeDirectory", messageKey, String.valueOf(cacheSize)); 161 CoreUtil.addMultipleGlobalWarning(GlobalWarning.MANAGEMENT_USERS, message); 162 addedWarning = true; 163 } 164 storageCounter--; 165 } 166 167 public synchronized void cleared() { 168 storageCounter = 0; 169 addedWarning = false; 170 CoreUtil.removeGlobalWarningFromAllSessions(messageKey); 171 } 172 }; 173 } 174 175 static void closeCache(Cache cache) { 176 try { 177 cache.clear(); 178 cache.unregisterStorageListeners(); 179 } catch (Exception e) { 180 logger.error("Failed to close cache", e); 181 } 182 } 183 }
| Popular Tags
|