001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.request.resource.caching; 018 019import org.apache.wicket.request.cycle.RequestCycle; 020import org.apache.wicket.request.http.WebResponse; 021import org.apache.wicket.request.mapper.parameter.INamedParameters; 022import org.apache.wicket.request.resource.AbstractResource; 023import org.apache.wicket.request.resource.caching.version.CachingResourceVersion; 024import org.apache.wicket.request.resource.caching.version.IResourceVersion; 025import org.apache.wicket.util.lang.Args; 026import org.apache.wicket.util.string.StringValue; 027 028/** 029 * resource caching strategy that adds a version string to the query parameters of the resource 030 * (this is similar to how wicket 1.4 does it when enabling timestamps on resources). You should 031 * preferably use {@link FilenameWithVersionResourceCachingStrategy} since it is more reliable. 032 * 033 * @author Peter Ertl 034 * 035 * @see FilenameWithVersionResourceCachingStrategy 036 * 037 * @since 1.5 038 */ 039public class QueryStringWithVersionResourceCachingStrategy implements IResourceCachingStrategy 040{ 041 /** 042 * default query parameter for version information 043 */ 044 private static final String DEFAULT_VERSION_PARAMETER = "ver"; 045 046 /** 047 * query string parameter name that contains the version string for the resource 048 */ 049 private final String versionParameter; 050 051 /** 052 * resource version provider 053 */ 054 private final IResourceVersion resourceVersion; 055 056 /** 057 * create query string resource caching strategy 058 * <p/> 059 * it will use a query parameter named <code>{@value #DEFAULT_VERSION_PARAMETER}</code> 060 * for storing the version information. 061 * 062 * @param resourceVersion 063 * resource version provider 064 */ 065 public QueryStringWithVersionResourceCachingStrategy(IResourceVersion resourceVersion) 066 { 067 this(DEFAULT_VERSION_PARAMETER, resourceVersion); 068 } 069 070 /** 071 * create query string resource caching strategy 072 * <p/> 073 * it will use a query parameter with name specified by 074 * parameter <code>resourceVersion</code> for storing the version information. 075 * 076 * @param versionParameter 077 * name of version parameter which will be added to query string 078 * containing the resource version 079 * @param resourceVersion 080 * resource version provider 081 */ 082 public QueryStringWithVersionResourceCachingStrategy(String versionParameter, 083 IResourceVersion resourceVersion) 084 { 085 this.versionParameter = Args.notEmpty(versionParameter, "versionParameter"); 086 this.resourceVersion = Args.notNull(resourceVersion, "resourceVersion"); 087 } 088 089 /** 090 * @return name of version parameter which will be added to query string 091 */ 092 public final String getVersionParameter() 093 { 094 return versionParameter; 095 } 096 097 @Override 098 public void decorateUrl(ResourceUrl url, final IStaticCacheableResource resource) 099 { 100 String version = resourceVersion.getVersion(resource); 101 102 if (version != null) 103 { 104 url.getParameters().set(versionParameter, version, INamedParameters.Type.MANUAL); 105 } 106 } 107 108 @Override 109 public void undecorateUrl(ResourceUrl url) 110 { 111 final INamedParameters parameters = url.getParameters(); 112 113 if (parameters != null) 114 { 115 // store the version in the request cycle 116 StringValue versionValue = parameters.get(versionParameter); 117 RequestCycle requestCycle = RequestCycle.get(); 118 if (versionValue.isEmpty() == false && requestCycle != null) 119 { 120 requestCycle.setMetaData(URL_VERSION, versionValue.toString()); 121 } 122 123 // undecorate 124 parameters.remove(versionParameter); 125 } 126 } 127 128 @Override 129 public void decorateResponse(AbstractResource.ResourceResponse response, IStaticCacheableResource resource) 130 { 131 String requestedVersion = RequestCycle.get().getMetaData(URL_VERSION); 132 String calculatedVersion = this.resourceVersion.getVersion(resource); 133 if (calculatedVersion != null && calculatedVersion.equals(requestedVersion)) 134 { 135 response.setCacheDurationToMaximum(); 136 response.setCacheScope(WebResponse.CacheScope.PUBLIC); 137 } 138 } 139 140 @Override 141 public void clearCache() 142 { 143 if (resourceVersion instanceof CachingResourceVersion) 144 { 145 ((CachingResourceVersion) resourceVersion).invalidateAll(); 146 } 147 } 148}