001/* 002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Anahide Tchertchian 018 */ 019package org.nuxeo.ecm.web.resources.wro.factory; 020 021import static org.apache.commons.lang3.Validate.notNull; 022 023import java.util.Map; 024 025import javax.servlet.http.HttpServletRequest; 026 027import org.apache.commons.io.FilenameUtils; 028import org.apache.commons.lang3.StringUtils; 029import org.apache.commons.lang3.Validate; 030import org.apache.commons.logging.Log; 031import org.apache.commons.logging.LogFactory; 032import org.nuxeo.common.utils.URIUtils; 033 034import ro.isdc.wro.cache.CacheKey; 035import ro.isdc.wro.cache.factory.DefaultCacheKeyFactory; 036import ro.isdc.wro.config.ReadOnlyContext; 037import ro.isdc.wro.model.group.DefaultGroupExtractor; 038import ro.isdc.wro.model.group.GroupExtractor; 039import ro.isdc.wro.model.group.Inject; 040import ro.isdc.wro.model.resource.ResourceType; 041 042/** 043 * Cache key extractor generating a key depending on all request parameters, and accepting slash character for page 044 * names. 045 * 046 * @since 7.10 047 */ 048public class NuxeoWroPageCacheKeyFactory extends DefaultCacheKeyFactory { 049 050 private static final Log log = LogFactory.getLog(NuxeoWroPageCacheKeyFactory.class); 051 052 protected static final String URI_MARKER = "/resource/page/"; 053 054 @Inject 055 private GroupExtractor groupExtractor; 056 057 @Inject 058 private ReadOnlyContext context; 059 060 @Override 061 public CacheKey create(HttpServletRequest request) { 062 notNull(request); 063 CacheKey key = null; 064 065 GroupExtractor ext = new DefaultGroupExtractor() { 066 067 @Override 068 public String getGroupName(HttpServletRequest request) { 069 Validate.notNull(request); 070 String uri = request.getRequestURI(); 071 // check if include or uri path are present and use one of these as request uri. 072 final String includeUriPath = (String) request.getAttribute(ATTR_INCLUDE_PATH); 073 uri = includeUriPath != null ? includeUriPath : uri; 074 final String groupName = FilenameUtils.removeExtension(getPageName(stripSessionID(uri))); 075 return StringUtils.isEmpty(groupName) ? null : groupName; 076 } 077 078 private String stripSessionID(final String uri) { // NOSONAR 079 if (uri == null) { 080 return null; 081 } 082 return uri.replaceFirst("(?i)(;jsessionid.*)", ""); 083 } 084 085 protected String getPageName(String filename) { 086 if (filename == null) { 087 return null; 088 } 089 int index = filename.indexOf(URI_MARKER); 090 if (index != -1) { 091 return filename.substring(index + URI_MARKER.length()); 092 } 093 return null; 094 } 095 096 }; 097 098 final String groupName = ext.getGroupName(request); 099 final ResourceType resourceType = groupExtractor.getResourceType(request); 100 final boolean minimize = isMinimized(request); 101 if (groupName != null && resourceType != null) { 102 key = new CacheKey(groupName, resourceType, minimize); 103 } 104 105 if (key != null) { 106 // add additional attributes for request-related info 107 Map<String, String> params = URIUtils.getRequestParameters(request.getQueryString()); 108 if (params != null) { 109 for (Map.Entry<String, String> entry : params.entrySet()) { 110 key.addAttribute(entry.getKey(), entry.getValue()); 111 } 112 } 113 } 114 if (log.isDebugEnabled()) { 115 log.debug(String.format("Cache key for request '%s' '%s': %s", request.getRequestURL(), 116 request.getQueryString(), key)); 117 } 118 return key; 119 } 120 121 /** 122 * Uses isMinimizeEnabled configuration to compute minimize value. 123 */ 124 private boolean isMinimized(final HttpServletRequest request) { // NOSONAR 125 return context.getConfig().isMinimizeEnabled() ? groupExtractor.isMinimized(request) : false; 126 } 127 128}