001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Anahide Tchertchian
016 */
017package org.nuxeo.ecm.web.resources.wro.factory;
018
019import static org.apache.commons.lang3.Validate.notNull;
020
021import java.util.Map;
022
023import javax.servlet.http.HttpServletRequest;
024
025import org.apache.commons.io.FilenameUtils;
026import org.apache.commons.lang3.StringUtils;
027import org.apache.commons.lang3.Validate;
028import org.apache.commons.logging.Log;
029import org.apache.commons.logging.LogFactory;
030import org.nuxeo.common.utils.URIUtils;
031
032import ro.isdc.wro.cache.CacheKey;
033import ro.isdc.wro.cache.factory.DefaultCacheKeyFactory;
034import ro.isdc.wro.config.ReadOnlyContext;
035import ro.isdc.wro.model.group.DefaultGroupExtractor;
036import ro.isdc.wro.model.group.GroupExtractor;
037import ro.isdc.wro.model.group.Inject;
038import ro.isdc.wro.model.resource.ResourceType;
039
040/**
041 * Cache key extractor generating a key depending on all request parameters, and accepting slash character for page
042 * names.
043 *
044 * @since 7.10
045 */
046public class NuxeoWroPageCacheKeyFactory extends DefaultCacheKeyFactory {
047
048    private static final Log log = LogFactory.getLog(NuxeoWroPageCacheKeyFactory.class);
049
050    protected static final String URI_MARKER = "/resource/page/";
051
052    @Inject
053    private GroupExtractor groupExtractor;
054
055    @Inject
056    private ReadOnlyContext context;
057
058    @Override
059    public CacheKey create(HttpServletRequest request) {
060        notNull(request);
061        CacheKey key = null;
062
063        GroupExtractor ext = new DefaultGroupExtractor() {
064
065            @Override
066            public String getGroupName(HttpServletRequest request) {
067                Validate.notNull(request);
068                String uri = request.getRequestURI();
069                // check if include or uri path are present and use one of these as request uri.
070                final String includeUriPath = (String) request.getAttribute(ATTR_INCLUDE_PATH);
071                uri = includeUriPath != null ? includeUriPath : uri;
072                final String groupName = FilenameUtils.removeExtension(getPageName(stripSessionID(uri)));
073                return StringUtils.isEmpty(groupName) ? null : groupName;
074            }
075
076            private String stripSessionID(final String uri) {
077                if (uri == null) {
078                    return null;
079                }
080                return uri.replaceFirst("(?i)(;jsessionid.*)", "");
081            }
082
083            protected String getPageName(String filename) {
084                if (filename == null) {
085                    return null;
086                }
087                int index = filename.indexOf(URI_MARKER);
088                if (index != -1) {
089                    return filename.substring(index + URI_MARKER.length());
090                }
091                return null;
092            }
093
094        };
095
096        final String groupName = ext.getGroupName(request);
097        final ResourceType resourceType = groupExtractor.getResourceType(request);
098        final boolean minimize = isMinimized(request);
099        if (groupName != null && resourceType != null) {
100            key = new CacheKey(groupName, resourceType, minimize);
101        }
102
103        if (key != null) {
104            // add additional attributes for request-related info
105            Map<String, String> params = URIUtils.getRequestParameters(request.getQueryString());
106            if (params != null) {
107                for (Map.Entry<String, String> entry : params.entrySet()) {
108                    key.addAttribute(entry.getKey(), entry.getValue());
109                }
110            }
111        }
112        if (log.isDebugEnabled()) {
113            log.debug(String.format("Cache key for request '%s' '%s': %s", request.getRequestURL(),
114                    request.getQueryString(), key));
115        }
116        return key;
117    }
118
119    /**
120     * Uses isMinimizeEnabled configuration to compute minimize value.
121     */
122    private boolean isMinimized(final HttpServletRequest request) {
123        return context.getConfig().isMinimizeEnabled() ? groupExtractor.isMinimized(request) : false;
124    }
125
126}