1 13 package info.magnolia.cms.beans.config; 14 15 import info.magnolia.cms.core.CacheHandler; 16 import info.magnolia.cms.core.Content; 17 import info.magnolia.cms.core.NodeData; 18 import info.magnolia.cms.core.Path; 19 import info.magnolia.cms.util.SimpleUrlPattern; 20 import info.magnolia.cms.util.UrlPattern; 21 22 import java.util.HashMap ; 23 import java.util.Hashtable ; 24 import java.util.Iterator ; 25 import java.util.Map ; 26 27 import javax.jcr.RepositoryException; 28 import javax.jcr.observation.Event; 29 import javax.jcr.observation.EventIterator; 30 import javax.jcr.observation.EventListener; 31 import javax.jcr.observation.ObservationManager; 32 import javax.servlet.http.HttpServletRequest ; 33 34 import org.apache.commons.lang.BooleanUtils; 35 import org.apache.commons.lang.StringUtils; 36 import org.apache.log4j.Logger; 37 38 39 43 public final class Cache { 44 45 private static final String CONFIG_PATH = "server/cache/level1"; 47 private static final String CACHE_MAPPING_NODE = "URI"; 49 private static final String COMPRESSION_LIST_NODE = "compression"; 51 private static final String ALLOW_LIST = "allow"; 53 private static final String DENY_LIST = "deny"; 55 private static final String ACTIVE = "active"; 57 private static final String DOMAIN = "domain"; 59 62 private static Logger log = Logger.getLogger(Cache.class); 63 64 private static Map cachedCacheableURIMapping = new HashMap (); 65 66 69 private static final Map COMPRESSION_LIST = new Hashtable (); 70 71 private static boolean active; 72 73 private static String domain; 74 75 78 private Cache() { 79 } 81 82 protected static void init() { 83 load(); 84 registerEventListener(); 85 } 86 87 public static void load() { 88 cachedCacheableURIMapping.clear(); 89 COMPRESSION_LIST.clear(); 90 91 log.info("Config : loading cache mapping"); try { 93 Content startPage = ContentRepository.getHierarchyManager(ContentRepository.CONFIG).getContent(CONFIG_PATH); 94 active = startPage.getNodeData(ACTIVE).getBoolean(); 95 if (active) { 96 domain = startPage.getNodeData(DOMAIN).getString(); 97 Content contentNode = startPage.getContent(CACHE_MAPPING_NODE + "/" + ALLOW_LIST); cacheCacheableURIMappings(contentNode, true); 99 contentNode = startPage.getContent(CACHE_MAPPING_NODE + "/" + DENY_LIST); cacheCacheableURIMappings(contentNode, false); 101 Content compressionListNode = startPage.getContent(COMPRESSION_LIST_NODE); 102 updateCompressionList(compressionListNode); 103 } 105 log.info("Config: cache mapping loaded"); } 107 catch (RepositoryException re) { 108 log.error("Config: Failed to load cache mapping or no mapping defined - " + re.getMessage(), re); } 110 } 111 112 public static void reload() { 113 log.info("Config : reloading cache mapping"); 115 info.magnolia.cms.beans.runtime.Cache.clearCachedURIList(); 118 CacheHandler.flushCache(); 119 120 load(); 121 } 122 123 126 private static void registerEventListener() { 127 128 log.info("Registering event listener for cache"); 130 try { 131 ObservationManager observationManager = ContentRepository 132 .getHierarchyManager(ContentRepository.CONFIG) 133 .getWorkspace() 134 .getObservationManager(); 135 136 observationManager.addEventListener(new EventListener() { 137 138 public void onEvent(EventIterator iterator) { 139 reload(); 141 } 142 }, Event.NODE_ADDED 143 | Event.NODE_REMOVED 144 | Event.PROPERTY_ADDED 145 | Event.PROPERTY_CHANGED 146 | Event.PROPERTY_REMOVED, "/" + CONFIG_PATH, true, null, null, false); } 148 catch (RepositoryException e) { 149 log.error("Unable to add event listeners for cache", e); } 151 } 152 153 156 private static void cacheCacheableURIMappings(Content nodeList, boolean allow) { 157 if (nodeList == null) { 158 return; 159 } 160 Iterator it = nodeList.getChildren().iterator(); 161 while (it.hasNext()) { 162 Content container = (Content) it.next(); 163 NodeData uri = container.getNodeData(CACHE_MAPPING_NODE); 164 UrlPattern p = new SimpleUrlPattern(uri.getString()); 165 cachedCacheableURIMapping.put(p, BooleanUtils.toBooleanObject(allow)); 166 } 167 try { 168 CacheHandler.validatePath(CacheHandler.CACHE_DIRECTORY); 169 } 170 catch (Exception e) { 171 log.error("Failed to validate cache directory location: " + e.getMessage(), e); } 173 } 174 175 private static void updateCompressionList(Content list) { 176 if (list == null) { 177 return; 178 } 179 Iterator it = list.getChildren().iterator(); 180 while (it.hasNext()) { 181 Content node = (Content) it.next(); 182 COMPRESSION_LIST.put(node.getNodeData("extension").getString(), node.getNodeData("type").getString()); } 184 } 185 186 public static boolean applyCompression(String key) { 187 return COMPRESSION_LIST.containsKey(key.trim().toLowerCase()); 188 } 189 190 196 public static boolean isCacheable() { 197 return active; 198 } 199 200 204 public static boolean isActive() { 205 return active; 206 } 207 208 public static String getDomain() { 209 return domain; 210 } 211 212 215 public static boolean isCacheable(HttpServletRequest request) { 216 217 if (!isActive()) { 219 return false; 220 } 221 222 224 if ("POST".equals(request.getMethod()) || request.getParameterMap().size() > 0) { return false; 227 } 228 229 if (StringUtils.isEmpty(MIMEMapping.getMIMEType(Path.getExtension(request)))) { 231 return false; 232 } 233 234 Iterator listEnum = cachedCacheableURIMapping.keySet().iterator(); 235 236 String uri = Path.getURI(request); 237 boolean isAllowed = false; 238 int lastMatchedPatternlength = 0; 239 240 while (listEnum.hasNext()) { 241 UrlPattern p = (UrlPattern) listEnum.next(); 242 if (p.match(uri)) { 243 int patternLength = p.getLength(); 244 if (lastMatchedPatternlength < patternLength) { 245 lastMatchedPatternlength = patternLength; 246 isAllowed = ((Boolean ) cachedCacheableURIMapping.get(p)).booleanValue(); 247 } 248 } 249 } 250 return isAllowed; 251 } 252 253 } 254 | Popular Tags |